diff --git a/.circleci/config.yml b/.circleci/config.yml index 659de54ea..9504eadb8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -95,7 +95,7 @@ commands: jobs: build-debian: docker: - - image: redisfab/rmbuilder:6.0.1-x64-buster + - image: redisfab/rmbuilder:6.0.5-x64-buster steps: - build-steps: platform: debian @@ -112,7 +112,7 @@ jobs: coverage: docker: - - image: redisfab/rmbuilder:6.0.1-x64-buster + - image: redisfab/rmbuilder:6.0.5-x64-buster steps: - checkout - run: @@ -136,7 +136,7 @@ jobs: - run: name: Test with coverage command: | - make -C opt test SHOW=1 COV=1 + make -C opt test SHOW=1 COV=1 CLUSTER=1 make -C opt cov-upload no_output_timeout: 20m @@ -209,7 +209,7 @@ jobs: package: type: string docker: - - image: redisfab/rmbuilder:6.0.1-x64-buster + - image: redisfab/rmbuilder:6.0.5-x64-buster steps: - attach_workspace: at: workspace diff --git a/opt/Makefile b/opt/Makefile index ae638ab3f..a8193f250 100755 --- a/opt/Makefile +++ b/opt/Makefile @@ -189,12 +189,14 @@ endif export GEN ?= 1 export SLAVES ?= 1 export AOF ?= 1 +export CLUSTER ?= 1 test: $(COVERAGE_RESET) $(SHOW)\ DEVICE=$(DEVICE) \ MODULE=$(INSTALLED_TARGET) \ + CLUSTER=$(CLUSTER) \ GEN=$(GEN) AOF=$(AOF) SLAVES=$(SLAVES) \ VALGRIND=$(VALGRIND) \ $(ROOT)/test/tests.sh diff --git a/src/dag.c b/src/dag.c index 3ffb03f05..d1d70d347 100644 --- a/src/dag.c +++ b/src/dag.c @@ -510,7 +510,6 @@ int RAI_parseDAGLoadArgs(RedisModuleCtx *ctx, RedisModuleString **argv, ctx, "ERR invalid or negative value found in number of keys to LOAD"); return -1; } - int number_loaded_keys = 0; int separator_flag = 0; size_t argpos = 2; @@ -522,8 +521,7 @@ int RAI_parseDAGLoadArgs(RedisModuleCtx *ctx, RedisModuleString **argv, } else { RAI_Tensor *t; RedisModuleKey *key; - const int status = RAI_GetTensorFromKeyspace(ctx, argv[argpos], &key, &t, - REDISMODULE_READ); + const int status = RAI_GetTensorFromKeyspace(ctx, argv[argpos], &key, &t, REDISMODULE_READ); if (status == REDISMODULE_ERR) { RedisModule_Log( ctx, "warning", @@ -532,9 +530,9 @@ int RAI_parseDAGLoadArgs(RedisModuleCtx *ctx, RedisModuleString **argv, return -1; } RedisModule_CloseKey(key); - char *dictKey = RedisModule_Alloc(strlen(arg_string) + 4); + char *dictKey = (char*) RedisModule_Alloc((strlen(arg_string) + 5)*sizeof(char)); sprintf(dictKey, "%s%04d", arg_string, 1); - AI_dictAdd(*localContextDict, (void*)dictKey, t); + AI_dictAdd(*localContextDict, (void*)dictKey, (void *)t); AI_dictAdd(*loadedContextDict, (void*)dictKey, (void *)1); RedisModule_Free(dictKey); number_loaded_keys++; @@ -587,10 +585,35 @@ int RAI_parseDAGPersistArgs(RedisModuleCtx *ctx, RedisModuleString **argv, return argpos; } +int RedisAI_DagRun_IsKeysPositionRequest_ReportKeys(RedisModuleCtx *ctx, + RedisModuleString **argv, int argc){ + for (size_t argpos = 1; argpos < argc; argpos++){ + const char *arg_string = RedisModule_StringPtrLen(argv[argpos], NULL); + if ( (!strcasecmp(arg_string, "LOAD") || !strcasecmp(arg_string, "PERSIST") ) && (argpos+1 < argc) ) { + long long n_keys; + argpos++; + const int retval = RedisModule_StringToLongLong(argv[argpos], &n_keys); + if(retval != REDISMODULE_OK){ + return REDISMODULE_ERR; + } + argpos++; + if (n_keys > 0){ + size_t last_persist_argpos = n_keys+argpos; + for (; argpos < last_persist_argpos && argpos < argc; argpos++){ + RedisModule_KeyAtPos(ctx, argpos); + } + } + } + } + return REDISMODULE_OK; +} + int RedisAI_DagRunSyntaxParser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int dagMode) { + if (RedisModule_IsKeysPositionRequest(ctx)) { + return RedisAI_DagRun_IsKeysPositionRequest_ReportKeys(ctx, argv, argc); + } if (argc < 4) return RedisModule_WrongArity(ctx); - RedisAI_RunInfo *rinfo = NULL; if (RAI_InitRunInfo(&rinfo) == REDISMODULE_ERR) { return RedisModule_ReplyWithError( @@ -703,6 +726,7 @@ int RedisAI_DagRunSyntaxParser(RedisModuleCtx *ctx, RedisModuleString **argv, for (long long i=0; idagOps); i++) { RAI_DagOp *currentOp = rinfo->dagOps[i]; + if(currentOp==NULL) continue; int parse_result; switch (currentOp->commandType) { case REDISAI_DAG_CMD_TENSORSET: @@ -818,7 +842,8 @@ int RedisAI_DagRunSyntaxParser(RedisModuleCtx *ctx, RedisModuleString **argv, } int *instance = AI_dictGetVal(mangled_entry); RedisModuleString *mangled_key = RedisModule_CreateStringPrintf(ctx, "%s%04d", key, *instance); - AI_dictAdd(mangled_persisted, (void *)RedisModule_StringPtrLen(mangled_key, NULL), (void *)1); + const char* mangled_key_str = RedisModule_StringPtrLen(mangled_key, NULL); + AI_dictAdd(mangled_persisted, (void *)mangled_key_str, (void *)1); entry = AI_dictNext(iter); } AI_dictReleaseIterator(iter); diff --git a/src/dag.h b/src/dag.h index 2c19a27de..402174cb2 100644 --- a/src/dag.h +++ b/src/dag.h @@ -81,6 +81,21 @@ int RAI_parseDAGPersistArgs(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, AI_dict **localContextDict, const char *chaining_operator); +/** + * When a module command is called in order to obtain the position of + * keys, since it was flagged as "getkeys-api" during the registration, + * the command implementation checks for this special call using the + * RedisModule_IsKeysPositionRequest() API and uses this function in + * order to report keys. + * No real execution is done on this special call. + * @param ctx Context in which Redis modules operate + * @param argv Redis command arguments, as an array of strings + * @param argc Redis command number of arguments + * @return + */ +int RedisAI_DagRun_IsKeysPositionRequest_ReportKeys(RedisModuleCtx *ctx, + RedisModuleString **argv, int argc); + /** * DAGRUN and DAGRUN_RO parser, which reads the the sequence of * arguments and decides whether the sequence conforms to the syntax diff --git a/src/model.c b/src/model.c index 74b90b302..e05d1a414 100644 --- a/src/model.c +++ b/src/model.c @@ -548,6 +548,18 @@ int RAI_ModelSerialize(RAI_Model *model, char **buffer, size_t *len, RAI_Error * return ret; } +int RedisAI_ModelRun_IsKeysPositionRequest_ReportKeys(RedisModuleCtx *ctx, + RedisModuleString **argv, int argc){ + RedisModule_KeyAtPos(ctx, 1); + for (size_t argpos = 3; argpos < argc; argpos++){ + const char *str = RedisModule_StringPtrLen(argv[argpos], NULL); + if (!strcasecmp(str, "OUTPUTS")) { + continue; + } + RedisModule_KeyAtPos(ctx,argpos); + } + return REDISMODULE_OK; +} int RedisAI_Parse_ModelRun_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, @@ -590,7 +602,6 @@ int RedisAI_Parse_ModelRun_RedisCommand(RedisModuleCtx *ctx, } } } - if ((*mto)->inputs && array_len((*mto)->inputs) != ninputs) { RAI_SetError( error, RAI_EMODELRUN, diff --git a/src/model.h b/src/model.h index e52fec407..d5aced277 100644 --- a/src/model.h +++ b/src/model.h @@ -201,6 +201,21 @@ int RAI_ModelSerialize(RAI_Model* model, char** buffer, size_t* len, int RAI_GetModelFromKeyspace(RedisModuleCtx* ctx, RedisModuleString* keyName, RedisModuleKey** key, RAI_Model** model, int mode); +/** + * When a module command is called in order to obtain the position of + * keys, since it was flagged as "getkeys-api" during the registration, + * the command implementation checks for this special call using the + * RedisModule_IsKeysPositionRequest() API and uses this function in + * order to report keys. + * No real execution is done on this special call. + * @param ctx Context in which Redis modules operate + * @param argv Redis command arguments, as an array of strings + * @param argc Redis command number of arguments + * @return + */ +int RedisAI_ModelRun_IsKeysPositionRequest_ReportKeys(RedisModuleCtx *ctx, + RedisModuleString **argv, int argc); + /** * Helper method to parse AI.MODELRUN arguments * diff --git a/src/redisai.c b/src/redisai.c index d848d681a..17db10a0f 100644 --- a/src/redisai.c +++ b/src/redisai.c @@ -535,20 +535,20 @@ int RedisAI_ModelScan_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv */ int RedisAI_ModelRun_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (RedisModule_IsKeysPositionRequest(ctx)) { + return RedisAI_ModelRun_IsKeysPositionRequest_ReportKeys(ctx, argv, argc); + } if (argc < 3) return RedisModule_WrongArity(ctx); - RedisAI_RunInfo *rinfo = NULL; if (RAI_InitRunInfo(&rinfo) == REDISMODULE_ERR) { return RedisModule_ReplyWithError(ctx, "ERR Unable to allocate the memory and initialise the RedisAI_RunInfo structure"); } - RAI_Model *mto; RedisModuleKey *modelKey; const int status = RAI_GetModelFromKeyspace(ctx, argv[1], &modelKey, &mto, REDISMODULE_READ); if (status == REDISMODULE_ERR) { return REDISMODULE_ERR; } - RedisModule_RetainString(NULL, argv[1]); rinfo->runkey = argv[1]; rinfo->mctx = RAI_ModelRunCtxCreate(mto); @@ -618,8 +618,10 @@ int RedisAI_ModelRun_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, * AI.SCRIPTRUN INPUTS [input ...] OUTPUTS [output ...] */ int RedisAI_ScriptRun_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (RedisModule_IsKeysPositionRequest(ctx)) { + return RedisAI_ScriptRun_IsKeysPositionRequest_ReportKeys(ctx, argv, argc); + } if (argc < 6) return RedisModule_WrongArity(ctx); - RedisAI_RunInfo *rinfo = NULL; if (RAI_InitRunInfo(&rinfo) == REDISMODULE_ERR) { return RedisModule_ReplyWithError( @@ -627,7 +629,6 @@ int RedisAI_ScriptRun_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv "ERR Unable to allocate the memory and initialise the RedisAI_RunInfo" "structure"); } - RedisModule_RetainString(NULL, argv[1]); rinfo->runkey = argv[1]; @@ -1204,11 +1205,11 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) == REDISMODULE_ERR) return REDISMODULE_ERR; - if (RedisModule_CreateCommand(ctx, "ai.dagrun", RedisAI_DagRun_RedisCommand, "write deny-oom", 3, 3, 1) + if (RedisModule_CreateCommand(ctx, "ai.dagrun", RedisAI_DagRun_RedisCommand, "write deny-oom getkeys-api", 3, 3, 1) == REDISMODULE_ERR) return REDISMODULE_ERR; - if (RedisModule_CreateCommand(ctx, "ai.dagrun_ro", RedisAI_DagRunRO_RedisCommand, "readonly", 3, 3, 1) + if (RedisModule_CreateCommand(ctx, "ai.dagrun_ro", RedisAI_DagRunRO_RedisCommand, "readonly getkeys-api", 3, 3, 1) == REDISMODULE_ERR) return REDISMODULE_ERR; diff --git a/src/run_info.c b/src/run_info.c index 8fa30d1f3..b1d44d1c4 100644 --- a/src/run_info.c +++ b/src/run_info.c @@ -179,6 +179,9 @@ int RAI_ShallowCopyDagRunInfo(RedisAI_RunInfo **result, RedisAI_RunInfo *src) { void RAI_FreeDagOp(RedisModuleCtx *ctx, RAI_DagOp *dagOp) { if (dagOp) { RAI_FreeError(dagOp->err); + if(dagOp->runkey){ + RedisModule_FreeString(ctx,dagOp->runkey); + } if (dagOp->argv) { for (size_t i = 0; i < array_len(dagOp->argv); i++) { RedisModule_FreeString(ctx, dagOp->argv[i]); @@ -203,14 +206,14 @@ void RAI_FreeDagOp(RedisModuleCtx *ctx, RAI_DagOp *dagOp) { if (dagOp->inkeys) { for (size_t i=0; iinkeys); i++) { - RedisModule_Free(dagOp->inkeys[i]); + RedisModule_FreeString(ctx,dagOp->inkeys[i]); } array_free(dagOp->inkeys); } if (dagOp->outkeys) { for (size_t i=0; ioutkeys); i++) { - RedisModule_Free(dagOp->outkeys[i]); + RedisModule_FreeString(ctx,dagOp->outkeys[i]); } array_free(dagOp->outkeys); } @@ -273,10 +276,6 @@ void RAI_FreeRunInfo(RedisModuleCtx *ctx, struct RedisAI_RunInfo *rinfo) { entry = AI_dictNext(iter); } AI_dictReleaseIterator(iter); - - RedisModule_Free(rinfo->dagTensorsContext); - RedisModule_Free(rinfo->dagTensorsLoadedContext); - RedisModule_Free(rinfo->dagTensorsPersistedContext); } if (rinfo->dagOps) { diff --git a/src/script.c b/src/script.c index 24853ecb1..ce6cba23e 100644 --- a/src/script.c +++ b/src/script.c @@ -266,6 +266,19 @@ int RAI_GetScriptFromKeyspace(RedisModuleCtx* ctx, RedisModuleString* keyName, return REDISMODULE_OK; } +int RedisAI_ScriptRun_IsKeysPositionRequest_ReportKeys(RedisModuleCtx *ctx, + RedisModuleString **argv, int argc){ + RedisModule_KeyAtPos(ctx, 1); + for (size_t argpos = 4; argpos < argc; argpos++){ + const char *str = RedisModule_StringPtrLen(argv[argpos], NULL); + if (!strcasecmp(str, "OUTPUTS")) { + continue; + } + RedisModule_KeyAtPos(ctx,argpos); + } + return REDISMODULE_OK; +} + /** * AI.SCRIPTRUN INPUTS [input ...] OUTPUTS [output ...] */ diff --git a/src/script.h b/src/script.h index fc652db40..db499197c 100644 --- a/src/script.h +++ b/src/script.h @@ -170,6 +170,21 @@ int RAI_GetScriptFromKeyspace(RedisModuleCtx* ctx, RedisModuleString* keyName, int mode); +/** + * When a module command is called in order to obtain the position of + * keys, since it was flagged as "getkeys-api" during the registration, + * the command implementation checks for this special call using the + * RedisModule_IsKeysPositionRequest() API and uses this function in + * order to report keys. + * No real execution is done on this special call. + * @param ctx Context in which Redis modules operate + * @param argv Redis command arguments, as an array of strings + * @param argc Redis command number of arguments + * @return + */ +int RedisAI_ScriptRun_IsKeysPositionRequest_ReportKeys(RedisModuleCtx *ctx, + RedisModuleString **argv, int argc); + /** * Helper method to parse AI.SCRIPTRUN arguments * diff --git a/src/util/dict.c b/src/util/dict.c index d04efa993..1b73a90ba 100644 --- a/src/util/dict.c +++ b/src/util/dict.c @@ -99,10 +99,10 @@ static unsigned int dict_force_resize_ratio = 5; /* -------------------------- private prototypes ---------------------------- */ -static int _dictExpandIfNeeded(AI_dict *ht); -static unsigned long _dictNextPower(unsigned long size); -static long _dictKeyIndex(AI_dict *ht, const void *key, uint64_t hash, AI_dictEntry **existing); -static int _dictInit(AI_dict *ht, AI_dictType *type, void *privDataPtr); +static int _AI_dictExpandIfNeeded(AI_dict *ht); +static unsigned long _AI_dictNextPower(unsigned long size); +static long _AI_dictKeyIndex(AI_dict *ht, const void *key, uint64_t hash, AI_dictEntry **existing); +static int _AI_dictInit(AI_dict *ht, AI_dictType *type, void *privDataPtr); /* -------------------------- hash functions -------------------------------- */ @@ -117,24 +117,24 @@ uint8_t *AI_dictGetHashFunctionSeed(void) { } /* The default hashing function uses SipHash implementation - * in siphash.c. */ + * in _AI_siphash.c. */ -uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k); -uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k); +uint64_t _AI_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k); +uint64_t _AI_siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k); uint64_t AI_dictGenHashFunction(const void *key, int len) { - return siphash(key,len,dict_hash_function_seed); + return _AI_siphash(key,len,dict_hash_function_seed); } uint64_t AI_dictGenCaseHashFunction(const unsigned char *buf, int len) { - return siphash_nocase(buf,len,dict_hash_function_seed); + return _AI_siphash_nocase(buf,len,dict_hash_function_seed); } /* ----------------------------- API implementation ------------------------- */ /* Reset a hash table already initialized with ht_init(). * NOTE: This function should only be called by ht_destroy(). */ -static void _dictReset(AI_dictht *ht) +static void _AI_dictReset(AI_dictht *ht) { ht->table = NULL; ht->size = 0; @@ -148,16 +148,16 @@ AI_dict *AI_dictCreate(AI_dictType *type, { AI_dict *d = RA_ALLOC(sizeof(*d)); - _dictInit(d,type,privDataPtr); + _AI_dictInit(d,type,privDataPtr); return d; } /* Initialize the hash table */ -int _dictInit(AI_dict *d, AI_dictType *type, +int _AI_dictInit(AI_dict *d, AI_dictType *type, void *privDataPtr) { - _dictReset(&d->ht[0]); - _dictReset(&d->ht[1]); + _AI_dictReset(&d->ht[0]); + _AI_dictReset(&d->ht[1]); d->type = type; d->privdata = privDataPtr; d->rehashidx = -1; @@ -187,7 +187,7 @@ int AI_dictExpand(AI_dict *d, unsigned long size) return DICT_ERR; AI_dictht n; /* the new hash table */ - unsigned long realsize = _dictNextPower(size); + unsigned long realsize = _AI_dictNextPower(size); /* Rehashing to the same table size is not useful. */ if (realsize == d->ht[0].size) return DICT_ERR; @@ -256,7 +256,7 @@ int AI_dictRehash(AI_dict *d, int n) { if (d->ht[0].used == 0) { RA_FREE(d->ht[0].table); d->ht[0] = d->ht[1]; - _dictReset(&d->ht[1]); + _AI_dictReset(&d->ht[1]); d->rehashidx = -1; return 0; } @@ -292,7 +292,7 @@ int AI_dictRehashMilliseconds(AI_dict *d, int ms) { * This function is called by common lookup or update operations in the * dictionary so that the hash table automatically migrates from H1 to H2 * while it is actively used. */ -static void _dictRehashStep(AI_dict *d) { +static void _AI_dictRehashStep(AI_dict *d) { if (d->iterators == 0) AI_dictRehash(d,1); } @@ -334,11 +334,11 @@ AI_dictEntry *AI_dictAddRaw(AI_dict *d, void *key, AI_dictEntry **existing) AI_dictEntry *entry; AI_dictht *ht; - if (AI_dictIsRehashing(d)) _dictRehashStep(d); + if (AI_dictIsRehashing(d))_AI_dictRehashStep(d); /* Get the index of the new element, or -1 if * the element already exists. */ - if ((index = _dictKeyIndex(d, key, AI_dictHashKey(d,key), existing)) == -1) + if ((index = _AI_dictKeyIndex(d, key, AI_dictHashKey(d,key), existing)) == -1) return NULL; /* Allocate the memory and store the new entry. @@ -407,7 +407,7 @@ static AI_dictEntry *dictGenericDelete(AI_dict *d, const void *key, int nofree) if (d->ht[0].used == 0 && d->ht[1].used == 0) return NULL; - if (AI_dictIsRehashing(d)) _dictRehashStep(d); + if (AI_dictIsRehashing(d))_AI_dictRehashStep(d); h = AI_dictHashKey(d, key); for (table = 0; table <= 1; table++) { @@ -478,7 +478,7 @@ void AI_dictFreeUnlinkedEntry(AI_dict *d, AI_dictEntry *he) { } /* Destroy an entire dictionary */ -static int _dictClear(AI_dict *d, AI_dictht *ht, void(callback)(void *)) { +static int AI_dictClear(AI_dict *d, AI_dictht *ht, void(callback)(void *)) { unsigned long i; /* Free all the elements */ @@ -500,15 +500,15 @@ static int _dictClear(AI_dict *d, AI_dictht *ht, void(callback)(void *)) { /* Free the table and the allocated cache structure */ RA_FREE(ht->table); /* Re-initialize the table */ - _dictReset(ht); + _AI_dictReset(ht); return DICT_OK; /* never fails */ } /* Clear & Release the hash table */ void AI_dictRelease(AI_dict *d) { - _dictClear(d,&d->ht[0],NULL); - _dictClear(d,&d->ht[1],NULL); + AI_dictClear(d,&d->ht[0],NULL); + AI_dictClear(d,&d->ht[1],NULL); RA_FREE(d); } @@ -518,7 +518,7 @@ AI_dictEntry *AI_dictFind(AI_dict *d, const void *key) uint64_t h, idx, table; if (d->ht[0].used + d->ht[1].used == 0) return NULL; /* dict is empty */ - if (AI_dictIsRehashing(d)) _dictRehashStep(d); + if (AI_dictIsRehashing(d))_AI_dictRehashStep(d); h = AI_dictHashKey(d, key); for (table = 0; table <= 1; table++) { idx = h & d->ht[table].sizemask; @@ -653,7 +653,7 @@ AI_dictEntry *AI_dictGetRandomKey(AI_dict *d) int listlen, listele; if (AI_dictSize(d) == 0) return NULL; - if (AI_dictIsRehashing(d)) _dictRehashStep(d); + if (AI_dictIsRehashing(d))_AI_dictRehashStep(d); if (AI_dictIsRehashing(d)) { do { /* We are sure there are no elements in indexes from 0 @@ -721,7 +721,7 @@ unsigned int AI_dictGetSomeKeys(AI_dict *d, AI_dictEntry **des, unsigned int cou /* Try to do a rehashing work proportional to 'count'. */ for (j = 0; j < count; j++) { if (AI_dictIsRehashing(d)) - _dictRehashStep(d); + _AI_dictRehashStep(d); else break; } @@ -958,7 +958,7 @@ unsigned long AI_dictScan(AI_dict *d, /* ------------------------- private functions ------------------------------ */ /* Expand the hash table if needed */ -static int _dictExpandIfNeeded(AI_dict *d) +static int _AI_dictExpandIfNeeded(AI_dict *d) { /* Incremental rehashing already in progress. Return. */ if (AI_dictIsRehashing(d)) return DICT_OK; @@ -980,7 +980,7 @@ static int _dictExpandIfNeeded(AI_dict *d) } /* Our hash table capability is a power of two */ -static unsigned long _dictNextPower(unsigned long size) +static unsigned long _AI_dictNextPower(unsigned long size) { unsigned long i = DICT_HT_INITIAL_SIZE; @@ -999,14 +999,14 @@ static unsigned long _dictNextPower(unsigned long size) * * Note that if we are in the process of rehashing the hash table, the * index is always returned in the context of the second (new) hash table. */ -static long _dictKeyIndex(AI_dict *d, const void *key, uint64_t hash, AI_dictEntry **existing) +static long _AI_dictKeyIndex(AI_dict *d, const void *key, uint64_t hash, AI_dictEntry **existing) { unsigned long idx, table; AI_dictEntry *he; if (existing) *existing = NULL; /* Expand the hash table if needed */ - if (_dictExpandIfNeeded(d) == DICT_ERR) + if (_AI_dictExpandIfNeeded(d) == DICT_ERR) return -1; for (table = 0; table <= 1; table++) { idx = hash & d->ht[table].sizemask; @@ -1025,8 +1025,8 @@ static long _dictKeyIndex(AI_dict *d, const void *key, uint64_t hash, AI_dictEnt } void AI_dictEmpty(AI_dict *d, void(callback)(void*)) { - _dictClear(d,&d->ht[0],callback); - _dictClear(d,&d->ht[1],callback); + AI_dictClear(d,&d->ht[0],callback); + AI_dictClear(d,&d->ht[1],callback); d->rehashidx = -1; d->iterators = 0; } @@ -1071,7 +1071,7 @@ AI_dictEntry **AI_dictFindEntryRefByPtrAndHash(AI_dict *d, const void *oldptr, u /* ------------------------------- Debugging ---------------------------------*/ #define DICT_STATS_VECTLEN 50 -static size_t _dictGetStatsHt(char *buf, size_t bufsize, AI_dictht *ht, int tableid) { +static size_t _AI_dictGetStatsHt(char *buf, size_t bufsize, AI_dictht *ht, int tableid) { unsigned long i, slots = 0, chainlen, maxchainlen = 0; unsigned long totchainlen = 0; unsigned long clvector[DICT_STATS_VECTLEN]; @@ -1137,11 +1137,11 @@ void AI_dictGetStats(char *buf, size_t bufsize, AI_dict *d) { char *orig_buf = buf; size_t orig_bufsize = bufsize; - l = _dictGetStatsHt(buf,bufsize,&d->ht[0],0); + l =_AI_dictGetStatsHt(buf,bufsize,&d->ht[0],0); buf += l; bufsize -= l; if (AI_dictIsRehashing(d) && bufsize > 0) { - _dictGetStatsHt(buf,bufsize,&d->ht[1],1); + _AI_dictGetStatsHt(buf,bufsize,&d->ht[1],1); } /* Make sure there is a NULL term at the end. */ if (orig_bufsize) orig_buf[orig_bufsize-1] = '\0'; diff --git a/src/util/siphash.c.inc b/src/util/siphash.c.inc index 6b9419031..f1b5a66cc 100644 --- a/src/util/siphash.c.inc +++ b/src/util/siphash.c.inc @@ -112,7 +112,7 @@ int siptlw(int c) { v2 = ROTL(v2, 32); \ } while (0) -uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) { +uint64_t _AI_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) { #ifndef UNALIGNED_LE_CPU uint64_t hash; uint8_t *out = (uint8_t*) &hash; @@ -171,7 +171,7 @@ uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) { #endif } -uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k) +uint64_t _AI_siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k) { #ifndef UNALIGNED_LE_CPU uint64_t hash; @@ -304,13 +304,13 @@ const uint8_t vectors_sip64[64][8] = { }; -/* Test siphash using a test vector. Returns 0 if the function passed +/* Test _AI_siphash using a test vector. Returns 0 if the function passed * all the tests, otherwise 1 is returned. * * IMPORTANT: The test vector is for SipHash 2-4. Before running - * the test revert back the siphash() function to 2-4 rounds since + * the test revert back the _AI_siphash() function to 2-4 rounds since * now it uses 1-2 rounds. */ -int siphash_test(void) { +int _AI_siphash_test(void) { uint8_t in[64], k[16]; int i; int fails = 0; @@ -320,7 +320,7 @@ int siphash_test(void) { for (i = 0; i < 64; ++i) { in[i] = i; - uint64_t hash = siphash(in, i, k); + uint64_t hash = _AI_siphash(in, i, k); const uint8_t *v = NULL; v = (uint8_t *)vectors_sip64; if (memcmp(&hash, v + (i * 8), 8)) { @@ -331,16 +331,16 @@ int siphash_test(void) { /* Run a few basic tests with the case insensitive version. */ uint64_t h1, h2; - h1 = siphash((uint8_t*)"hello world",11,(uint8_t*)"1234567812345678"); - h2 = siphash_nocase((uint8_t*)"hello world",11,(uint8_t*)"1234567812345678"); + h1 = _AI_siphash((uint8_t*)"hello world",11,(uint8_t*)"1234567812345678"); + h2 = _AI_siphash_nocase((uint8_t*)"hello world",11,(uint8_t*)"1234567812345678"); if (h1 != h2) fails++; - h1 = siphash((uint8_t*)"hello world",11,(uint8_t*)"1234567812345678"); - h2 = siphash_nocase((uint8_t*)"HELLO world",11,(uint8_t*)"1234567812345678"); + h1 = _AI_siphash((uint8_t*)"hello world",11,(uint8_t*)"1234567812345678"); + h2 = _AI_siphash_nocase((uint8_t*)"HELLO world",11,(uint8_t*)"1234567812345678"); if (h1 != h2) fails++; - h1 = siphash((uint8_t*)"HELLO world",11,(uint8_t*)"1234567812345678"); - h2 = siphash_nocase((uint8_t*)"HELLO world",11,(uint8_t*)"1234567812345678"); + h1 = _AI_siphash((uint8_t*)"HELLO world",11,(uint8_t*)"1234567812345678"); + h2 = _AI_siphash_nocase((uint8_t*)"HELLO world",11,(uint8_t*)"1234567812345678"); if (h1 == h2) fails++; if (!fails) return 0; diff --git a/test/includes.py b/test/includes.py index 80715e94a..03c5f3ec2 100755 --- a/test/includes.py +++ b/test/includes.py @@ -156,12 +156,12 @@ def load_creditcardfraud_data(env,max_tensors=10000): def run_mobilenet(con, img, input_var, output_var): time.sleep(0.5 * random.randint(0, 10)) - con.execute_command('AI.TENSORSET', 'input', + con.execute_command('AI.TENSORSET', 'input{1}', 'FLOAT', 1, img.shape[1], img.shape[0], img.shape[2], 'BLOB', img.tobytes()) - con.execute_command('AI.MODELRUN', 'mobilenet', - 'INPUTS', 'input', 'OUTPUTS', 'output') + con.execute_command('AI.MODELRUN', 'mobilenet{1}', + 'INPUTS', 'input{1}', 'OUTPUTS', 'output{1}') def run_test_multiproc(env, n_procs, fn, args=tuple()): diff --git a/test/tests.sh b/test/tests.sh index 4d265b650..0e3820c13 100755 --- a/test/tests.sh +++ b/test/tests.sh @@ -107,7 +107,7 @@ RLTEST_ARGS="" [[ $VALGRIND == 1 || $VGD == 1 ]] && valgrind_config if [[ ! -z $TEST ]]; then - RLTEST_ARGS+=" -s --test $TEST" + RLTEST_ARGS+=" --test $TEST" export PYDEBUG=${PYDEBUG:-1} fi @@ -121,5 +121,6 @@ install_git_lfs check_redis_server [[ $GEN == 1 ]] && run_tests +[[ $CLUSTER == 1 ]] && RLTEST_ARGS+=" --env oss-cluster --shards-count 1" run_tests "--env oss-cluster" [[ $SLAVES == 1 ]] && RLTEST_ARGS+=" --use-slaves" run_tests "--use-slaves" [[ $AOF == 1 ]] && RLTEST_ARGS+=" --use-aof" run_tests "--use-aof" diff --git a/test/tests_dag.py b/test/tests_dag.py index 4cbc3b20f..138dde772 100644 --- a/test/tests_dag.py +++ b/test/tests_dag.py @@ -2,6 +2,7 @@ from functools import wraps import multiprocessing as mp from includes import * +import time ''' python -m RLTest --test tests_dag.py --module path/to/redisai.so @@ -13,12 +14,12 @@ def test_dag_load(env): con = env.getConnection() ret = con.execute_command( - "AI.TENSORSET persisted_tensor_1 FLOAT 1 2 VALUES 5 10") + "AI.TENSORSET persisted_tensor_1{{1}} FLOAT 1 2 VALUES 5 10") env.assertEqual(ret, b'OK') command = "AI.DAGRUN "\ - "LOAD 1 persisted_tensor_1 "\ - "PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + "LOAD 1 persisted_tensor_1{{1}} "\ + "PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) env.assertEqual(ret, [b'OK']) @@ -29,9 +30,9 @@ def test_dag_load_errors(env): # ERR tensor key is empty try: command = "AI.DAGRUN "\ - "LOAD 1 persisted_tensor_1 "\ - "PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + "LOAD 1 persisted_tensor_1{{1}} "\ + "PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) except Exception as e: @@ -41,11 +42,11 @@ def test_dag_load_errors(env): # WRONGTYPE Operation against a key holding the wrong kind of value try: - con.execute_command('SET', 'non-tensor', 'value') + con.execute_command('SET', 'non-tensor{{1}}', 'value') command = "AI.DAGRUN "\ - "LOAD 1 non-tensor "\ - "PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + "LOAD 1 non-tensor{{1}} "\ + "PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) except Exception as e: @@ -60,7 +61,7 @@ def test_dag_common_errors(env): # ERR unsupported command within DAG try: command = "AI.DAGRUN |> "\ - "AI.DONTEXIST tensor1 FLOAT 1 2 VALUES 5 10" + "AI.DONTEXIST tensor1{{1}} FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) except Exception as e: @@ -80,7 +81,7 @@ def test_dag_common_errors(env): # ERR invalid or negative value found in number of keys to PERSIST try: - command = "AI.DAGRUN PERSIST notnumber |> "\ + command = "AI.DAGRUN PERSIST notnumber{{1}} |> "\ "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) @@ -91,43 +92,8 @@ def test_dag_common_errors(env): # ERR invalid or negative value found in number of keys to LOAD try: - command = "AI.DAGRUN LOAD notnumber |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" - - ret = con.execute_command(command) - except Exception as e: - exception = e - env.assertEqual(type(exception), redis.exceptions.ResponseError) - env.assertEqual("invalid or negative value found in number of keys to LOAD",exception.__str__()) - - # ERR INPUT key cannot be found in DAG - try: - command = "AI.DAGRUN |> "\ - "AI.TENSORGET tensor1 VALUES" - - ret = con.execute_command(command) - except Exception as e: - exception = e - env.assertEqual(type(exception), redis.exceptions.ResponseError) - env.assertEqual("INPUT key cannot be found in DAG",exception.__str__()) - - # ERR invalid value - try: - command = "AI.DAGRUN |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES ASD |> "\ - "AI.TENSORGET tensor1" - - ret = con.execute_command(command) - env.assertEqual(b"NA", ret[1]) - except Exception as e: - exception = e - env.assertEqual(type(exception), redis.exceptions.ResponseError) - env.assertEqual("invalid value", exception.__str__()) - - # ERR invalid or negative value found in number of keys to LOAD - try: - command = "AI.DAGRUN LOAD notnumber |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + command = "AI.DAGRUN LOAD notnumber{{1}} |> "\ + "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) except Exception as e: @@ -142,7 +108,7 @@ def test_dagro_common_errors(env): # ERR unsupported command within DAG try: command = "AI.DAGRUN_RO |> "\ - "AI.DONTEXIST tensor1 FLOAT 1 2 VALUES 5 10" + "AI.DONTEXIST tensor1 FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) except Exception as e: @@ -162,8 +128,8 @@ def test_dagro_common_errors(env): # ERR invalid or negative value found in number of keys to LOAD try: - command = "AI.DAGRUN_RO LOAD notnumber |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + command = "AI.DAGRUN_RO LOAD notnumber{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) except Exception as e: @@ -176,8 +142,8 @@ def test_dagrun_ro_modelrun_scriptrun_resnet(env): if (not TEST_TF or not TEST_PT): return con = env.getConnection() - model_name = 'imagenet_model' - script_name = 'imagenet_script' + model_name = 'imagenet_model{{1}}' + script_name = 'imagenet_script{{1}}' inputvar = 'images' outputvar = 'output' model_pb, script, labels, img = load_resnet_test_data() @@ -191,11 +157,11 @@ def test_dagrun_ro_modelrun_scriptrun_resnet(env): ret = con.execute_command('AI.SCRIPTSET', script_name, DEVICE, 'SOURCE', script) env.assertEqual(ret, b'OK') # - for opnumber in range(1, 100): - image_key = 'image' - temp_key1 = 'temp_key1' - temp_key2 = 'temp_key2' - class_key = 'output' + for opnumber in range(1,100): + image_key = 'image{{1}}' + temp_key1 = 'temp_key1{{1}}' + temp_key2 = 'temp_key2{{1}}' + class_key = 'output{{1}}' ret = con.execute_command( 'AI.DAGRUN_RO', '|>', @@ -223,8 +189,12 @@ def test_dagrun_modelrun_scriptrun_resnet(env): if (not TEST_TF or not TEST_PT): return con = env.getConnection() - model_name = 'imagenet_model' - script_name = 'imagenet_script' + model_name = 'imagenet_model:{{1}}' + script_name = 'imagenet_script:{{1}}' + image_key = 'image:{{1}}' + temp_key1 = 'temp_key1' + temp_key2 = 'temp_key2' + class_key = 'output:{{1}}' inputvar = 'images' outputvar = 'output' model_pb, script, labels, img = load_resnet_test_data() @@ -240,10 +210,7 @@ def test_dagrun_modelrun_scriptrun_resnet(env): # for opnumber in range(1,100): - image_key = 'image' - temp_key1 = 'temp_key1' - temp_key2 = 'temp_key2' - class_key = 'output' + ret = con.execute_command( 'AI.DAGRUN', 'PERSIST', '1', class_key, '|>', @@ -269,8 +236,8 @@ def test_dag_scriptrun_errors(env): if (not TEST_TF or not TEST_PT): return con = env.getConnection() - model_name = 'imagenet_model' - script_name = 'imagenet_script' + model_name = 'imagenet_model{{1}}' + script_name = 'imagenet_script{{1}}' inputvar = 'images' outputvar = 'output' model_pb, script, labels, img = load_resnet_test_data() @@ -286,10 +253,10 @@ def test_dag_scriptrun_errors(env): # ERR wrong number of inputs try: - image_key = 'image' - temp_key1 = 'temp_key1' - temp_key2 = 'temp_key2' - class_key = 'output' + image_key = 'image{{1}}' + temp_key1 = 'temp_key1{{1}}' + temp_key2 = 'temp_key2{{1}}' + class_key = 'output{{1}}' ret = con.execute_command( 'AI.DAGRUN', '|>', @@ -314,30 +281,30 @@ def test_dag_modelrun_financialNet_errors(env): if not TEST_TF: return con = env.getConnection() + model_key = 'financialNet_errors{{1}}' model_pb, creditcard_transactions, creditcard_referencedata = load_creditcardfraud_data( env) - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', "CPU", + ret = con.execute_command('AI.MODELSET', model_key, 'TF', "CPU", 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - tensor_number = 1 - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), - 'FLOAT', 1, 256, - 'BLOB', creditcard_referencedata[0].tobytes()) + tensor_number=1 + ret = con.execute_command( 'AI.TENSORSET', 'referenceTensor:{{1}}{0}'.format(tensor_number), + 'FLOAT', 1, 256, + 'BLOB', creditcard_referencedata[0].tobytes()) env.assertEqual(ret, b'OK') # ERR wrong number of inputs try: - tensor_number = 1 ret = con.execute_command( - 'AI.DAGRUN', 'LOAD', '1', 'referenceTensor:{}'.format(tensor_number), - 'PERSIST', '1', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORSET', 'transactionTensor:{}'.format(tensor_number), 'FLOAT', 1, 30, '|>', - 'AI.MODELRUN', 'financialNet', - 'INPUTS', 'transactionTensor:{}'.format(tensor_number), - 'OUTPUTS', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORGET', 'classificationTensor:{}'.format(tensor_number), 'META', + 'AI.DAGRUN', 'LOAD', '1', 'referenceTensor:{{1}}{}'.format(tensor_number), + 'PERSIST', '1', 'resultTensor:{{1}}{}'.format(tensor_number), '|>', + 'AI.TENSORSET', 'transactionTensor:{}'.format(tensor_number), 'FLOAT', 1, 30, '|>', + 'AI.MODELRUN', model_key, + 'INPUTS', 'transactionTensor:{}'.format(tensor_number), + 'OUTPUTS', 'resultTensor:{{1}}{}'.format(tensor_number), '|>', + 'AI.TENSORGET', 'resultTensor:{{1}}{}'.format(tensor_number), 'META', ) except Exception as e: exception = e @@ -379,17 +346,17 @@ def test_dag_local_tensorset_persist(env): con = env.getConnection() command = "AI.DAGRUN "\ - "PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + "PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10" ret = con.execute_command(command) env.assertEqual(ret, [b'OK']) # assert that transaction tensor exists - ret = con.execute_command("EXISTS tensor1") + ret = con.execute_command("EXISTS tensor1{{1}}") env.assertEqual(ret, 1 ) - ret = con.execute_command("AI.TENSORGET tensor1 META VALUES") + ret = con.execute_command("AI.TENSORGET tensor1{{1}} META VALUES") env.assertEqual(ret, [b'dtype', b'FLOAT', b'shape', [1, 2], b'values', [b'5', b'10']]) @@ -397,8 +364,8 @@ def test_dagro_local_tensorset_persist(env): con = env.getConnection() command = "AI.DAGRUN_RO "\ - "PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10" + "PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10" try: con.execute_command(command) @@ -412,17 +379,17 @@ def test_dag_multilocal_tensorset_persist(env): con = env.getConnection() command = "AI.DAGRUN "\ - "PERSIST 1 tensor3 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10 |> "\ + "PERSIST 1 tensor3:{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10 |> "\ "AI.TENSORSET tensor2 FLOAT 1 2 VALUES 5 10 |> "\ - "AI.TENSORSET tensor3 FLOAT 1 2 VALUES 5 10 |> "\ - "AI.TENSORSET tensor4 FLOAT 1 2 VALUES 5 10 " + "AI.TENSORSET tensor3:{{1}} FLOAT 1 2 VALUES 5 10 |> "\ + "AI.TENSORSET tensor4:{{1}} FLOAT 1 2 VALUES 5 10 " ret = con.execute_command(command) env.assertEqual([b'OK',b'OK',b'OK',b'OK'],ret) # assert that transaction tensor exists - ret = con.execute_command("EXISTS tensor1") + ret = con.execute_command("EXISTS tensor1{{1}}") env.assertEqual(ret, 0 ) # assert that transaction tensor exists @@ -430,39 +397,40 @@ def test_dag_multilocal_tensorset_persist(env): env.assertEqual(ret, 0 ) # assert that transaction tensor exists - ret = con.execute_command("EXISTS tensor3") + ret = con.execute_command("EXISTS tensor3:{{1}}") env.assertEqual(ret, 1 ) # assert that transaction tensor exists - ret = con.execute_command("EXISTS tensor4") + ret = con.execute_command("EXISTS tensor4:{{1}}") env.assertEqual(ret, 0 ) - ret = con.execute_command("AI.TENSORGET tensor3 META VALUES") + ret = con.execute_command("AI.TENSORGET tensor3:{{1}} META VALUES") env.assertEqual(ret, [b'dtype', b'FLOAT', b'shape', [1, 2], b'values', [b'5', b'10']]) def test_dag_local_tensorset_tensorget_persist(env): con = env.getConnection() - command = "AI.DAGRUN PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10 |> "\ - "AI.TENSORGET tensor1 VALUES" + command = "AI.DAGRUN PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10 |> "\ + "AI.TENSORGET tensor1{{1}} VALUES" ret = con.execute_command(command) env.assertEqual(ret, [b'OK', [b'5', b'10']]) - ret = con.execute_command("AI.TENSORGET tensor1 VALUES") + ret = con.execute_command("AI.TENSORGET tensor1{{1}} VALUES") env.assertEqual(ret, [b'5', b'10']) def test_dag_local_multiple_tensorset_on_same_tensor(env): con = env.getConnection() - command = "AI.DAGRUN PERSIST 1 tensor1 |> "\ - "AI.TENSORSET tensor1 FLOAT 1 2 VALUES 5 10 |> "\ - "AI.TENSORGET tensor1 META VALUES |> "\ - "AI.TENSORSET tensor1 FLOAT 1 4 VALUES 20 40 60 80 |> "\ - "AI.TENSORGET tensor1 META VALUES" + command = "AI.DAGRUN "\ + "PERSIST 1 tensor1{{1}} |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 2 VALUES 5 10 |> "\ + "AI.TENSORGET tensor1{{1}} META VALUES |> "\ + "AI.TENSORSET tensor1{{1}} FLOAT 1 4 VALUES 20 40 60 80 |> "\ + "AI.TENSORGET tensor1{{1}} META VALUES" ret = con.execute_command(command) env.assertEqual([ @@ -472,7 +440,7 @@ def test_dag_local_multiple_tensorset_on_same_tensor(env): [b'dtype', b'FLOAT', b'shape', [1, 4], b'values', [b'20', b'40', b'60', b'80']] ], ret) - ret = con.execute_command("AI.TENSORGET tensor1 META VALUES") + ret = con.execute_command("AI.TENSORGET tensor1{{1}} META VALUES") env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 4], b'values', [b'20', b'40',b'60',b'80']],ret) @@ -480,17 +448,17 @@ def test_dag_load_persist_tensorset_tensorget(env): con = env.getConnection() ret = con.execute_command( - "AI.TENSORSET persisted_tensor_1 FLOAT 1 2 VALUES 5 10") + "AI.TENSORSET persisted_tensor_1{{1}} FLOAT 1 2 VALUES 5 10") env.assertEqual(ret, b'OK') ret = con.execute_command( - "AI.TENSORSET persisted_tensor_2 FLOAT 1 3 VALUES 0 0 0") + "AI.TENSORSET persisted_tensor_2:{{1}} FLOAT 1 3 VALUES 0 0 0") env.assertEqual(ret, b'OK') - command = "AI.DAGRUN LOAD 2 persisted_tensor_1 persisted_tensor_2 PERSIST 1 volatile_tensor_persisted |> "\ + command = "AI.DAGRUN LOAD 2 persisted_tensor_1{{1}} persisted_tensor_2:{{1}} PERSIST 1 volatile_tensor_persisted |> "\ "AI.TENSORSET volatile_tensor_persisted FLOAT 1 2 VALUES 5 10 |> "\ - "AI.TENSORGET persisted_tensor_1 META VALUES |> "\ - "AI.TENSORGET persisted_tensor_2 META VALUES " + "AI.TENSORGET persisted_tensor_1{{1}} META VALUES |> "\ + "AI.TENSORGET persisted_tensor_2:{{1}} META VALUES " ret = con.execute_command(command) env.assertEqual(ret, [b'OK', [b'dtype', b'FLOAT', b'shape', [1, 2], b'values', [b'5', b'10']], [ @@ -562,39 +530,40 @@ def test_dag_modelrun_financialNet_separate_tensorget(env): model_pb, creditcard_transactions, creditcard_referencedata = load_creditcardfraud_data( env) - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', "CPU", + model_name = 'financialNet{{hhh}}' + + ret = con.execute_command('AI.MODELSET', model_name, 'TF', "CPU", 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - tensor_number = 1 - for reference_tensor in creditcard_referencedata[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), - 'FLOAT', 1, 256, - 'BLOB', reference_tensor.tobytes()) - env.assertEqual(ret, b'OK') - tensor_number = tensor_number + 1 - - tensor_number = 1 - for transaction_tensor in creditcard_transactions[:MAX_TRANSACTIONS]: - ret = con.execute_command( - 'AI.DAGRUN', 'LOAD', '1', 'referenceTensor:{}'.format(tensor_number), - 'PERSIST', '1', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORSET', 'transactionTensor:{}'.format(tensor_number), 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', - 'AI.MODELRUN', 'financialNet', - 'INPUTS', 'transactionTensor:{}'.format(tensor_number), 'referenceTensor:{}'.format(tensor_number), - 'OUTPUTS', 'classificationTensor:{}'.format(tensor_number), - ) - env.assertEqual([b'OK',b'OK'],ret) + for tensor_number in range(1,MAX_TRANSACTIONS): + for repetition in range(1,10): + reference_tensor = creditcard_referencedata[tensor_number] + transaction_tensor = creditcard_transactions[tensor_number] + result_tensor_keyname = 'resultTensor{{hhh}}{}'.format(tensor_number) + reference_tensor_keyname = 'referenceTensor{{hhh}}{}'.format(tensor_number) + transaction_tensor_keyname = 'transactionTensor{{hhh}}{}'.format(tensor_number) + + ret = con.execute_command('AI.TENSORSET', reference_tensor_keyname, + 'FLOAT', 1, 256, + 'BLOB', reference_tensor.tobytes()) + env.assertEqual(ret, b'OK') + ret = con.execute_command("EXISTS {}".format(reference_tensor_keyname)) + env.assertEqual(ret, 1) - ret = con.execute_command("AI.TENSORGET classificationTensor:{} META".format( - tensor_number)) - env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 2]], ret) + ret = con.execute_command( + 'AI.DAGRUN', 'LOAD', '1', reference_tensor_keyname, + 'PERSIST', '1', result_tensor_keyname, '|>', + 'AI.TENSORSET', transaction_tensor_keyname, 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', + 'AI.MODELRUN', model_name, + 'INPUTS', transaction_tensor_keyname, reference_tensor_keyname, + 'OUTPUTS', result_tensor_keyname, + ) + env.assertEqual([b'OK',b'OK'],ret) - # assert that transaction tensor does not exist - ret = con.execute_command("EXISTS transactionTensor:{} META".format( - tensor_number)) - env.assertEqual(ret, 0 ) - tensor_number = tensor_number + 1 + ret = con.execute_command("AI.TENSORGET {} META".format( + result_tensor_keyname)) + env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 2]], ret) def test_dag_modelrun_financialNet(env): @@ -604,37 +573,44 @@ def test_dag_modelrun_financialNet(env): model_pb, creditcard_transactions, creditcard_referencedata = load_creditcardfraud_data( env) - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', "CPU", + model_name = 'financialNet{{hhh}}' + + ret = con.execute_command('AI.MODELSET', model_name, 'TF', "CPU", 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - tensor_number = 1 - for reference_tensor in creditcard_referencedata[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), - 'FLOAT', 1, 256, - 'BLOB', reference_tensor.tobytes()) - env.assertEqual(ret, b'OK') - tensor_number = tensor_number + 1 - - tensor_number = 1 - for transaction_tensor in creditcard_transactions[:MAX_TRANSACTIONS]: - ret = con.execute_command( - 'AI.DAGRUN', 'LOAD', '1', 'referenceTensor:{}'.format(tensor_number), - 'PERSIST', '1', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORSET', 'transactionTensor:{}'.format(tensor_number), 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', - 'AI.MODELRUN', 'financialNet', - 'INPUTS', 'transactionTensor:{}'.format(tensor_number), 'referenceTensor:{}'.format(tensor_number), - 'OUTPUTS', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORGET', 'classificationTensor:{}'.format(tensor_number), 'META', - ) - env.assertEqual([b'OK',b'OK',[b'dtype', b'FLOAT', b'shape', [1, 2]]], ret) + for tensor_number in range(1,MAX_TRANSACTIONS): + for repetition in range(1,10): + reference_tensor = creditcard_referencedata[tensor_number] + transaction_tensor = creditcard_transactions[tensor_number] + result_tensor_keyname = 'resultTensor{{hhh}}{}'.format(tensor_number) + reference_tensor_keyname = 'referenceTensor{{hhh}}{}'.format(tensor_number) + transaction_tensor_keyname = 'transactionTensor{{hhh}}{}'.format(tensor_number) + + ret = con.execute_command('AI.TENSORSET', reference_tensor_keyname, + 'FLOAT', 1, 256, + 'BLOB', reference_tensor.tobytes()) + env.assertEqual(ret, b'OK') + ret = con.execute_command("EXISTS {}".format(reference_tensor_keyname)) + env.assertEqual(ret, 1) - # assert that transaction tensor does not exist - ret = con.execute_command("EXISTS transactionTensor:{}".format( - tensor_number)) - env.assertEqual(ret, 0 ) - tensor_number = tensor_number + 1 + ret = con.execute_command( + 'AI.DAGRUN', 'LOAD', '1', reference_tensor_keyname, + 'PERSIST', '1', result_tensor_keyname, '|>', + 'AI.TENSORSET', transaction_tensor_keyname, 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', + 'AI.MODELRUN', model_name, + 'INPUTS', transaction_tensor_keyname, reference_tensor_keyname, + 'OUTPUTS', result_tensor_keyname, '|>', + 'AI.TENSORGET', result_tensor_keyname, 'META', + ) + env.assertEqual([b'OK',b'OK',[b'dtype', b'FLOAT', b'shape', [1, 2]]], ret) + # assert that transaction tensor does not exist + ret = con.execute_command("EXISTS {}".format(transaction_tensor_keyname)) + env.assertEqual(ret, 0) + # assert that result tensor exists + ret = con.execute_command("EXISTS {}".format(result_tensor_keyname)) + env.assertEqual(ret, 1) def test_dag_modelrun_financialNet_no_writes(env): if not TEST_TF: @@ -643,29 +619,35 @@ def test_dag_modelrun_financialNet_no_writes(env): model_pb, creditcard_transactions, creditcard_referencedata = load_creditcardfraud_data( env) - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', "CPU", + model_name = 'financialNet{{hhh}}' + + ret = con.execute_command('AI.MODELSET', model_name, 'TF', "CPU", 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - tensor_number = 1 - for reference_tensor in creditcard_referencedata[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), - 'FLOAT', 1, 256, - 'BLOB', reference_tensor.tobytes()) - env.assertEqual(ret, b'OK') - tensor_number = tensor_number + 1 + for tensor_number in range(1,MAX_TRANSACTIONS): + for repetition in range(1,10): + reference_tensor = creditcard_referencedata[tensor_number] + transaction_tensor = creditcard_transactions[tensor_number] + result_tensor_keyname = 'resultTensor{{hhh}}{}'.format(tensor_number) + reference_tensor_keyname = 'referenceTensor{{hhh}}{}'.format(tensor_number) + transaction_tensor_keyname = 'transactionTensor{{hhh}}{}'.format(tensor_number) + + ret = con.execute_command('AI.TENSORSET', reference_tensor_keyname, + 'FLOAT', 1, 256, + 'BLOB', reference_tensor.tobytes()) + env.assertEqual(ret, b'OK') + ret = con.execute_command("EXISTS {}".format(reference_tensor_keyname)) + env.assertEqual(ret, 1) - tensor_number = 1 - for transaction_tensor in creditcard_transactions[:MAX_TRANSACTIONS]: - for run_number in range(1,10): ret = con.execute_command( - 'AI.DAGRUN', 'LOAD', '1', 'referenceTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORSET', 'transactionTensor:{}'.format(tensor_number), 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', - 'AI.MODELRUN', 'financialNet', - 'INPUTS', 'transactionTensor:{}'.format(tensor_number), 'referenceTensor:{}'.format(tensor_number), - 'OUTPUTS', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORGET', 'classificationTensor:{}'.format(tensor_number), 'META', '|>', - 'AI.TENSORGET', 'classificationTensor:{}'.format(tensor_number), 'VALUES' + 'AI.DAGRUN', 'LOAD', '1', reference_tensor_keyname, '|>', + 'AI.TENSORSET', transaction_tensor_keyname, 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', + 'AI.MODELRUN', model_name, + 'INPUTS', transaction_tensor_keyname, reference_tensor_keyname, + 'OUTPUTS', result_tensor_keyname, '|>', + 'AI.TENSORGET',result_tensor_keyname, 'META', '|>', + 'AI.TENSORGET', result_tensor_keyname, 'VALUES' ) env.assertEqual(4, len(ret)) env.assertEqual([b'OK', b'OK'], ret[:2]) @@ -675,16 +657,12 @@ def test_dag_modelrun_financialNet_no_writes(env): env.assertEqual(True, 0 <= float(values[0]) <= 1) env.assertEqual(True, 0 <= float(values[1]) <= 1) - # assert that transactionTensor does not exist - ret = con.execute_command("EXISTS transactionTensor:{}".format( - tensor_number)) - env.assertEqual(ret, 0 ) - - # assert that classificationTensor does not exist - ret = con.execute_command("EXISTS classificationTensor:{}".format( - tensor_number)) - env.assertEqual(ret, 0 ) - tensor_number = tensor_number + 1 + # assert that transaction tensor does not exist + ret = con.execute_command("EXISTS {}".format(transaction_tensor_keyname)) + env.assertEqual(ret, 0) + # assert that result tensor exists + ret = con.execute_command("EXISTS {}".format(result_tensor_keyname)) + env.assertEqual(ret, 0) def test_dagro_modelrun_financialNet_no_writes_multiple_modelruns(env): @@ -694,73 +672,70 @@ def test_dagro_modelrun_financialNet_no_writes_multiple_modelruns(env): model_pb, creditcard_transactions, creditcard_referencedata = load_creditcardfraud_data( env) - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', DEVICE, + model_name = 'financialNet_no_writes{{hhh}}' + + ret = con.execute_command('AI.MODELSET', model_name, 'TF', "CPU", 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - tensor_number = 1 - for reference_tensor in creditcard_referencedata[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), - 'FLOAT', 1, 256, - 'BLOB', reference_tensor.tobytes()) - env.assertEqual(ret, b'OK') - tensor_number = tensor_number + 1 - - tensor_number = 1 - for transaction_tensor in creditcard_transactions[:MAX_TRANSACTIONS]: - ret = con.execute_command( - 'AI.DAGRUN_RO', 'LOAD', '1', 'referenceTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORSET', 'transactionTensor:{}'.format(tensor_number), 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', - 'AI.MODELRUN', 'financialNet', - 'INPUTS', 'transactionTensor:{}'.format(tensor_number), 'referenceTensor:{}'.format(tensor_number), - 'OUTPUTS', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORGET', 'classificationTensor:{}'.format(tensor_number), 'META', 'VALUES', '|>', - 'AI.MODELRUN', 'financialNet', - 'INPUTS', 'transactionTensor:{}'.format(tensor_number), 'referenceTensor:{}'.format(tensor_number), - 'OUTPUTS', 'classificationTensor:{}'.format(tensor_number), '|>', - 'AI.TENSORGET', 'classificationTensor:{}'.format(tensor_number), 'META', 'VALUES', - ) - env.assertEqual(5, len(ret)) - env.assertEqual([b'OK', b'OK'], ret[:2]) - env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 2]], ret[2][:4]) - env.assertEqual(b'OK', ret[3]) - env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 2]], ret[4][:4]) - for _, dtype, _, shape, _, values in [ret[2], ret[4]]: - # Assert that resulting classification is within [0,1] - env.assertEqual(True, 0 <= float(values[0]) <= 1) - env.assertEqual(True, 0 <= float(values[1]) <= 1) - - # assert that transactionTensor does not exist - ret = con.execute_command("EXISTS transactionTensor:{}".format( - tensor_number)) - env.assertEqual(ret, 0) - - # assert that classificationTensor does not exist - ret = con.execute_command("EXISTS classificationTensor:{}".format( - tensor_number)) - env.assertEqual(ret, 0) - tensor_number = tensor_number + 1 - - info = con.execute_command('AI.INFO', 'financialNet') + for tensor_number in range(1,MAX_TRANSACTIONS+1): + for repetition in range(1,11): + reference_tensor = creditcard_referencedata[tensor_number-1] + transaction_tensor = creditcard_transactions[tensor_number-1] + result_tensor_keyname = 'resultTensor{{hhh}}{}'.format(tensor_number) + reference_tensor_keyname = 'referenceTensor{{hhh}}{}'.format(tensor_number) + transaction_tensor_keyname = 'transactionTensor{{hhh}}{}'.format(tensor_number) + + ret = con.execute_command('AI.TENSORSET', reference_tensor_keyname, + 'FLOAT', 1, 256, + 'BLOB', reference_tensor.tobytes()) + env.assertEqual(ret, b'OK') + ret = con.execute_command("EXISTS {}".format(reference_tensor_keyname)) + env.assertEqual(ret, 1) + ret = con.execute_command( + 'AI.DAGRUN_RO', 'LOAD', '1', reference_tensor_keyname, '|>', + 'AI.TENSORSET', transaction_tensor_keyname, 'FLOAT', 1, 30,'BLOB', transaction_tensor.tobytes(), '|>', + 'AI.MODELRUN', model_name, + 'INPUTS', transaction_tensor_keyname, reference_tensor_keyname, + 'OUTPUTS', result_tensor_keyname, '|>', + 'AI.TENSORGET', result_tensor_keyname, 'META', 'VALUES', '|>', + 'AI.MODELRUN', model_name, + 'INPUTS', transaction_tensor_keyname, reference_tensor_keyname, + 'OUTPUTS', result_tensor_keyname, '|>', + 'AI.TENSORGET', result_tensor_keyname, 'META', 'VALUES', + ) + env.assertEqual(5, len(ret)) + env.assertEqual([b'OK', b'OK'], ret[:2]) + env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 2]], ret[2][:4]) + env.assertEqual(b'OK', ret[3]) + env.assertEqual([b'dtype', b'FLOAT', b'shape', [1, 2]], ret[4][:4]) + for _, dtype, _, shape, _, values in [ret[2], ret[4]]: + # Assert that resulting classification is within [0,1] + env.assertEqual(True, 0 <= float(values[0]) <= 1) + env.assertEqual(True, 0 <= float(values[1]) <= 1) + + info = con.execute_command('AI.INFO', model_name) financialNetRunInfo = info_to_dict(info) - env.assertEqual('financialNet', financialNetRunInfo['key']) + env.assertEqual(model_name, financialNetRunInfo['key']) env.assertEqual('MODEL', financialNetRunInfo['type']) env.assertEqual('TF', financialNetRunInfo['backend']) - env.assertEqual(DEVICE, financialNetRunInfo['device']) + # Commenting due to: 'ascii' codec can't encode character '\u274c' in position 8: ordinal not in range(128) + # env.assertEqual(DEVICE, financialNetRunInfo['device']) env.assertTrue(financialNetRunInfo['duration'] > 0) env.assertEqual(0, financialNetRunInfo['samples']) - env.assertEqual(2*MAX_TRANSACTIONS, financialNetRunInfo['calls']) + env.assertEqual(2*MAX_TRANSACTIONS*10, financialNetRunInfo['calls']) env.assertEqual(0, financialNetRunInfo['errors']) - con.execute_command('AI.INFO', 'financialNet', 'RESETSTAT') - info = con.execute_command('AI.INFO', 'financialNet') + con.execute_command('AI.INFO', model_name, 'RESETSTAT') + info = con.execute_command('AI.INFO', model_name) financialNetRunInfo = info_to_dict(info) - env.assertEqual('financialNet', financialNetRunInfo['key']) + env.assertEqual(model_name, financialNetRunInfo['key']) env.assertEqual('MODEL', financialNetRunInfo['type']) env.assertEqual('TF', financialNetRunInfo['backend']) - env.assertEqual(DEVICE, financialNetRunInfo['device']) + # Commenting due to: 'ascii' codec can't encode character '\u274c' in position 8: ordinal not in range(128) + # env.assertEqual(DEVICE, financialNetRunInfo['device']) env.assertEqual(0, financialNetRunInfo['duration']) env.assertEqual(0, financialNetRunInfo['samples']) env.assertEqual(0, financialNetRunInfo['calls']) @@ -771,9 +746,15 @@ def test_dagrun_modelrun_multidevice_resnet(env): if (not TEST_TF or not TEST_PT): return con = env.getConnection() - model_name_0 = 'imagenet_model1' - model_name_1 = 'imagenet_model2' - script_name = 'imagenet_script' + model_name_0 = 'imagenet_model1:{{1}}' + model_name_1 = 'imagenet_model2:{{1}}' + script_name = 'imagenet_script:{{1}}' + image_key = 'image:{{1}}' + temp_key1 = 'temp_key1:{{1}}' + temp_key2_0 = 'temp_key2_0' + temp_key2_1 = 'temp_key2_1' + class_key_0 = 'output0:{{1}}' + class_key_1 = 'output1:{{1}}' inputvar = 'images' outputvar = 'output' model_pb, script, labels, img = load_resnet_test_data() @@ -802,13 +783,6 @@ def test_dagrun_modelrun_multidevice_resnet(env): ensureSlaveSynced(con, env) - image_key = 'image' - temp_key1 = 'temp_key1' - temp_key2_0 = 'temp_key2_0' - temp_key2_1 = 'temp_key2_1' - class_key_0 = 'output0' - class_key_1 = 'output1' - try: ret = con.execute_command( 'AI.DAGRUN', '|>', @@ -907,12 +881,19 @@ def test_dagrun_modelrun_multidevice_resnet_ensemble_alias(env): return con = env.getConnection() - model_name_0 = 'imagenet_model1' - model_name_1 = 'imagenet_model2' - script_name_0 = 'imagenet_script1' - script_name_1 = 'imagenet_script2' + model_name_0 = 'imagenet_model1:{{1}}' + model_name_1 = 'imagenet_model2:{{1}}' + script_name_0 = 'imagenet_script1:{{1}}' + script_name_1 = 'imagenet_script2:{{1}}' inputvar = 'images' outputvar = 'output' + image_key = 'image:{{1}}' + temp_key1 = 'temp_key1:{{1}}' + temp_key2_0 = 'temp_key2_0' + temp_key2_1 = 'temp_key2_1' + class_key_0 = 'output0:{{1}}' + class_key_1 = 'output1:{{1}}' + model_pb, script, labels, img = load_resnet_test_data() device_0 = 'CPU:1' @@ -944,12 +925,7 @@ def test_dagrun_modelrun_multidevice_resnet_ensemble_alias(env): ensureSlaveSynced(con, env) - image_key = 'image' - temp_key1 = 'temp_key1' - temp_key2_0 = 'temp_key2_0' - temp_key2_1 = 'temp_key2_1' - class_key_0 = 'output0' - class_key_1 = 'output1' + try: ret = con.execute_command( diff --git a/test/tests_onnx.py b/test/tests_onnx.py index fff7f9ebb..004adde36 100644 --- a/test/tests_onnx.py +++ b/test/tests_onnx.py @@ -30,24 +30,24 @@ def test_onnx_modelrun_mnist(env): with open(sample_filename, 'rb') as f: sample_raw = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'ONNX', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'ONNX', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'') # assert there are no inputs or outputs env.assertEqual(len(ret[11]), 0) env.assertEqual(len(ret[13]), 0) - ret = con.execute_command('AI.MODELSET', 'm', 'ONNX', DEVICE, 'TAG', 'version:2', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'ONNX', DEVICE, 'TAG', 'version:2', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) # TODO: enable me. CI is having issues on GPU asserts of ONNX and CPU if DEVICE == "CPU": @@ -59,96 +59,96 @@ def test_onnx_modelrun_mnist(env): env.assertEqual(len(ret[13]), 0) try: - con.execute_command('AI.MODELSET', 'm', 'ONNX', DEVICE, 'BLOB', wrong_model_pb) + con.execute_command('AI.MODELSET', 'm{1}', 'ONNX', DEVICE, 'BLOB', wrong_model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("No graph was found in the protobuf.", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_1', 'ONNX', 'BLOB', model_pb) + con.execute_command('AI.MODELSET', 'm_1{1}', 'ONNX', 'BLOB', model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Invalid DEVICE", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_2', model_pb) + con.execute_command('AI.MODELSET', 'm_2{1}', model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("wrong number of arguments for 'AI.MODELSET' command", exception.__str__()) - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) try: - con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'a', 'OUTPUTS') + con.execute_command('AI.MODELRUN', 'm_1{1}', 'INPUTS', 'a{1}', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_2', 'INPUTS', 'a', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm_2{1}', 'INPUTS', 'a{1}', 'b{1}', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_3', 'a', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm_3{1}', 'a{1}', 'b{1}', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_1', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm_1{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("INPUTS not specified", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("tensor key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'OUTPUTS') + con.execute_command('AI.MODELRUN', 'm_1{1}', 'INPUTS', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'a', 'OUTPUTS', 'b') + con.execute_command('AI.MODELRUN', 'm_1{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'OUTPUTS', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'b', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES') argmax = max(range(len(values)), key=lambda i: values[i]) env.assertEqual(argmax, 1) if env.useSlaves: con2 = env.getSlaveConnection() - values2 = con2.execute_command('AI.TENSORGET', 'b', 'VALUES') + values2 = con2.execute_command('AI.TENSORGET', 'b{1}', 'VALUES') env.assertEqual(values2, values) @@ -161,15 +161,15 @@ def test_onnx_modelrun_batchdim_mismatch(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'ONNX', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'ONNX', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 'VALUES', 1, 1) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 'VALUES', 1, 1) + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 'VALUES', 1, 1) + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 'VALUES', 1, 1) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c', 'd') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}', 'd{1}') @@ -189,11 +189,11 @@ def test_onnx_modelrun_mnist_autobatch(env): with open(sample_filename, 'rb') as f: sample_raw = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'ONNX', 'CPU', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'ONNX', 'CPU', 'BATCHSIZE', 2, 'MINBATCHSIZE', 2, 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) # TODO: enable me. CI is having issues on GPU asserts of ONNX and CPU if DEVICE == "CPU": @@ -206,31 +206,31 @@ def test_onnx_modelrun_mnist_autobatch(env): env.assertEqual(len(ret[11]), 0) env.assertEqual(len(ret[13]), 0) - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) - con.execute_command('AI.TENSORSET', 'c', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + con.execute_command('AI.TENSORSET', 'c{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) ensureSlaveSynced(con, env) def run(): con = env.getConnection() - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'c', 'OUTPUTS', 'd') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'c{1}', 'OUTPUTS', 'd{1}') t = threading.Thread(target=run) t.start() - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'OUTPUTS', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}') ensureSlaveSynced(con, env) import time time.sleep(1) - values = con.execute_command('AI.TENSORGET', 'b', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES') argmax = max(range(len(values)), key=lambda i: values[i]) env.assertEqual(argmax, 1) - values = con.execute_command('AI.TENSORGET', 'd', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'd{1}', 'VALUES') argmax = max(range(len(values)), key=lambda i: values[i]) env.assertEqual(argmax, 1) @@ -253,31 +253,31 @@ def test_onnx_modelrun_iris(env): with open(logreg_model_filename, 'rb') as f: logreg_model = f.read() - ret = con.execute_command('AI.MODELSET', 'linear', 'ONNX', DEVICE, 'BLOB', linear_model) + ret = con.execute_command('AI.MODELSET', 'linear{1}', 'ONNX', DEVICE, 'BLOB', linear_model) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.MODELSET', 'logreg', 'ONNX', DEVICE, 'BLOB', logreg_model) + ret = con.execute_command('AI.MODELSET', 'logreg{1}', 'ONNX', DEVICE, 'BLOB', logreg_model) env.assertEqual(ret, b'OK') - con.execute_command('AI.TENSORSET', 'features', 'FLOAT', 1, 4, 'VALUES', 5.1, 3.5, 1.4, 0.2) + con.execute_command('AI.TENSORSET', 'features{1}', 'FLOAT', 1, 4, 'VALUES', 5.1, 3.5, 1.4, 0.2) ensureSlaveSynced(con, env) - con.execute_command('AI.MODELRUN', 'linear', 'INPUTS', 'features', 'OUTPUTS', 'linear_out') - con.execute_command('AI.MODELRUN', 'logreg', 'INPUTS', 'features', 'OUTPUTS', 'logreg_out', 'logreg_probs') + con.execute_command('AI.MODELRUN', 'linear{1}', 'INPUTS', 'features{1}', 'OUTPUTS', 'linear_out{1}') + con.execute_command('AI.MODELRUN', 'logreg{1}', 'INPUTS', 'features{1}', 'OUTPUTS', 'logreg_out{1}', 'logreg_probs{1}') ensureSlaveSynced(con, env) - linear_out = con.execute_command('AI.TENSORGET', 'linear_out', 'VALUES') - logreg_out = con.execute_command('AI.TENSORGET', 'logreg_out', 'VALUES') + linear_out = con.execute_command('AI.TENSORGET', 'linear_out{1}', 'VALUES') + logreg_out = con.execute_command('AI.TENSORGET', 'logreg_out{1}', 'VALUES') env.assertEqual(float(linear_out[0]), -0.090524077415466309) env.assertEqual(logreg_out[0], 0) if env.useSlaves: con2 = env.getSlaveConnection() - linear_out2 = con2.execute_command('AI.TENSORGET', 'linear_out', 'VALUES') - logreg_out2 = con2.execute_command('AI.TENSORGET', 'logreg_out', 'VALUES') + linear_out2 = con2.execute_command('AI.TENSORGET', 'linear_out{1}', 'VALUES') + logreg_out2 = con2.execute_command('AI.TENSORGET', 'logreg_out{1}', 'VALUES') env.assertEqual(linear_out, linear_out2) env.assertEqual(logreg_out, logreg_out2) @@ -294,28 +294,28 @@ def test_onnx_modelinfo(env): with open(linear_model_filename, 'rb') as f: linear_model = f.read() - ret = con.execute_command('AI.MODELSET', 'linear', 'ONNX', DEVICE, 'BLOB', linear_model) + ret = con.execute_command('AI.MODELSET', 'linear{1}', 'ONNX', DEVICE, 'BLOB', linear_model) env.assertEqual(ret, b'OK') - model_serialized_master = con.execute_command('AI.MODELGET', 'linear', 'META') - con.execute_command('AI.TENSORSET', 'features', 'FLOAT', 1, 4, 'VALUES', 5.1, 3.5, 1.4, 0.2) + model_serialized_master = con.execute_command('AI.MODELGET', 'linear{1}', 'META') + con.execute_command('AI.TENSORSET', 'features{1}', 'FLOAT', 1, 4, 'VALUES', 5.1, 3.5, 1.4, 0.2) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - model_serialized_slave = con2.execute_command('AI.MODELGET', 'linear', 'META') + model_serialized_slave = con2.execute_command('AI.MODELGET', 'linear{1}', 'META') env.assertEqual(len(model_serialized_master), len(model_serialized_slave)) previous_duration = 0 for call in range(1, 10): - res = con.execute_command('AI.MODELRUN', 'linear', 'INPUTS', 'features', 'OUTPUTS', 'linear_out') + res = con.execute_command('AI.MODELRUN', 'linear{1}', 'INPUTS', 'features{1}', 'OUTPUTS', 'linear_out{1}') env.assertEqual(res, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'linear') + info = con.execute_command('AI.INFO', 'linear{1}') info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'linear') + env.assertEqual(info_dict_0['key'], 'linear{1}') env.assertEqual(info_dict_0['type'], 'MODEL') env.assertEqual(info_dict_0['backend'], 'ONNX') env.assertEqual(info_dict_0['device'], DEVICE) @@ -326,10 +326,10 @@ def test_onnx_modelinfo(env): previous_duration = info_dict_0['duration'] - res = con.execute_command('AI.INFO', 'linear', 'RESETSTAT') + res = con.execute_command('AI.INFO', 'linear{1}', 'RESETSTAT') env.assertEqual(res, b'OK') - info = con.execute_command('AI.INFO', 'linear') + info = con.execute_command('AI.INFO', 'linear{1}') info_dict_0 = info_to_dict(info) env.assertEqual(info_dict_0['duration'], 0) env.assertEqual(info_dict_0['samples'], 0) @@ -349,20 +349,20 @@ def test_onnx_modelrun_disconnect(env): with open(linear_model_filename, 'rb') as f: linear_model = f.read() - ret = con.execute_command('AI.MODELSET', 'linear', 'ONNX', DEVICE, 'BLOB', linear_model) + ret = con.execute_command('AI.MODELSET', 'linear{1}', 'ONNX', DEVICE, 'BLOB', linear_model) env.assertEqual(ret, b'OK') - model_serialized_master = con.execute_command('AI.MODELGET', 'linear', 'META') - con.execute_command('AI.TENSORSET', 'features', 'FLOAT', 1, 4, 'VALUES', 5.1, 3.5, 1.4, 0.2) + model_serialized_master = con.execute_command('AI.MODELGET', 'linear{1}', 'META') + con.execute_command('AI.TENSORSET', 'features{1}', 'FLOAT', 1, 4, 'VALUES', 5.1, 3.5, 1.4, 0.2) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - model_serialized_slave = con2.execute_command('AI.MODELGET', 'linear', 'META') + model_serialized_slave = con2.execute_command('AI.MODELGET', 'linear{1}', 'META') env.assertEqual(len(model_serialized_master), len(model_serialized_slave)) - ret = send_and_disconnect(('AI.MODELRUN', 'linear', 'INPUTS', 'features', 'OUTPUTS', 'linear_out'), con) + ret = send_and_disconnect(('AI.MODELRUN', 'linear{1}', 'INPUTS', 'features{1}', 'OUTPUTS', 'linear_out{1}'), con) env.assertEqual(ret, None) def test_onnx_model_rdb_save_load(env): @@ -378,10 +378,10 @@ def test_onnx_model_rdb_save_load(env): model_pb = f.read() con = env.getConnection() - ret = con.execute_command('AI.MODELSET', 'linear', 'ONNX', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'linear{1}', 'ONNX', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') - model_serialized_memory = con.execute_command('AI.MODELGET', 'linear', 'BLOB') + model_serialized_memory = con.execute_command('AI.MODELGET', 'linear{1}', 'BLOB') ensureSlaveSynced(con, env) ret = con.execute_command('SAVE') @@ -390,7 +390,7 @@ def test_onnx_model_rdb_save_load(env): env.stop() env.start() con = env.getConnection() - model_serialized_after_rdbload = con.execute_command('AI.MODELGET', 'linear', 'BLOB') + model_serialized_after_rdbload = con.execute_command('AI.MODELGET', 'linear{1}', 'BLOB') env.assertEqual(len(model_serialized_memory), len(model_serialized_after_rdbload)) env.assertEqual(len(model_pb), len(model_serialized_after_rdbload)) # Assert in memory model binary is equal to loaded model binary diff --git a/test/tests_pytorch.py b/test/tests_pytorch.py index b710f87ba..05749f057 100644 --- a/test/tests_pytorch.py +++ b/test/tests_pytorch.py @@ -54,10 +54,10 @@ def test_pytorch_modelrun(env): model_filename = os.path.join(test_data_path, 'pt-minimal.pt') wrong_model_filename = os.path.join(test_data_path, 'graph.pb') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') with open(model_filename, 'rb') as f: @@ -66,13 +66,13 @@ def test_pytorch_modelrun(env): with open(wrong_model_filename, 'rb') as f: wrong_model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) # TODO: enable me. CI is having issues on GPU asserts of TORCH and CPU if DEVICE == "CPU": @@ -85,12 +85,12 @@ def test_pytorch_modelrun(env): env.assertEqual(len(ret[11]), 0) env.assertEqual(len(ret[13]), 0) - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'TAG', 'my:tag:v3', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', DEVICE, 'TAG', 'my:tag:v3', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'my:tag:v3') # TODO: enable me. CI is having issues on GPU asserts of TORCH and CPU @@ -99,7 +99,7 @@ def test_pytorch_modelrun(env): env.assertEqual(ret[3], b'CPU') try: - con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'BLOB', wrong_model_pb) + con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', DEVICE, 'BLOB', wrong_model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -117,37 +117,37 @@ def test_pytorch_modelrun(env): env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'a', 'b', 'OUTPUTS') + con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm_2', 'INPUTS', 'a', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm_2', 'INPUTS', 'a{1}', 'b{1}', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm_3', 'a', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm_3', 'a{1}', 'b{1}', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm_1', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm_1', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -159,21 +159,21 @@ def test_pytorch_modelrun(env): env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c', 'd') + con.execute_command('AI.MODELRUN', 'm_1', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}', 'd{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'c', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values, [b'4', b'6', b'4', b'6']) if env.useSlaves: con2 = env.getSlaveConnection() - values2 = con2.execute_command('AI.TENSORGET', 'c', 'VALUES') + values2 = con2.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values2, values) @@ -186,15 +186,15 @@ def test_pytorch_modelrun_batchdim_mismatch(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 'VALUES', 1, 1) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 'VALUES', 1, 1) + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 'VALUES', 1, 1) + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 'VALUES', 1, 1) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c', 'd') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}', 'd{1}') def test_pytorch_modelrun_autobatch(env): @@ -209,34 +209,34 @@ def test_pytorch_modelrun_autobatch(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', 'CPU', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', 'CPU', 'BATCHSIZE', 4, 'MINBATCHSIZE', 3, 'BLOB', model_pb) env.assertEqual(ret, b'OK') - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'd', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'e', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'd{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'e{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) ensureSlaveSynced(con, env) def run(): con = env.getConnection() - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'd', 'e', 'OUTPUTS', 'f') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'd{1}', 'e{1}', 'OUTPUTS', 'f{1}') ensureSlaveSynced(con, env) t = threading.Thread(target=run) t.start() - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'c', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values, [b'4', b'6', b'4', b'6']) - values = con.execute_command('AI.TENSORGET', 'f', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'f{1}', 'VALUES') env.assertEqual(values, [b'4', b'6', b'4', b'6']) @@ -252,22 +252,22 @@ def test_pytorch_modelrun_autobatch_badbatch(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', 'CPU', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', 'CPU', 'BATCHSIZE', 4, 'MINBATCHSIZE', 3, 'BLOB', model_pb) env.assertEqual(ret, b'OK') - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'd', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'e', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'd{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'e{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) ensureSlaveSynced(con, env) def run(): con = env.getConnection() try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'd', 'e', 'OUTPUTS', 'f1', 'f2') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'd{1}', 'e{1}', 'OUTPUTS', 'f1{1}', 'f2{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -277,7 +277,7 @@ def run(): t.start() try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c1', 'c2') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c1{1}', 'c2{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -294,31 +294,35 @@ def test_pytorch_modelinfo(env): test_data_path = os.path.join(os.path.dirname(__file__), 'test_data') model_filename = os.path.join(test_data_path, 'pt-minimal.pt') + model_key = 'm{1}' + tensor_a_key = 'a{1}' + tensor_b_key = 'b{1}' + tensor_c_key = 'c{1}' with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'TAG', 'asdf', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', model_key, 'TORCH', DEVICE, 'TAG', 'asdf', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', tensor_a_key, 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', tensor_b_key, 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) previous_duration = 0 - for call in range(1, 10): - ret = con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + for call in range(1, 100): + ret = con.execute_command('AI.MODELRUN', model_key, 'INPUTS', tensor_a_key, tensor_b_key, 'OUTPUTS', tensor_c_key) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'm') + info = con.execute_command('AI.INFO', model_key) info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'm') + env.assertEqual(info_dict_0['key'], model_key) env.assertEqual(info_dict_0['type'], 'MODEL') env.assertEqual(info_dict_0['backend'], 'TORCH') env.assertEqual(info_dict_0['device'], DEVICE) @@ -330,9 +334,9 @@ def test_pytorch_modelinfo(env): previous_duration = info_dict_0['duration'] - res = con.execute_command('AI.INFO', 'm', 'RESETSTAT') + res = con.execute_command('AI.INFO', model_key, 'RESETSTAT') env.assertEqual(res, b'OK') - info = con.execute_command('AI.INFO', 'm') + info = con.execute_command('AI.INFO', model_key) info_dict_0 = info_to_dict(info) env.assertEqual(info_dict_0['duration'], 0) env.assertEqual(info_dict_0['samples'], 0) @@ -348,7 +352,7 @@ def test_pytorch_scriptset(env): con = env.getConnection() try: - con.execute_command('AI.SCRIPTSET', 'ket', DEVICE, 'SOURCE', 'return 1') + con.execute_command('AI.SCRIPTSET', 'ket{1}', DEVICE, 'SOURCE', 'return 1') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -377,7 +381,7 @@ def test_pytorch_scriptset(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket', DEVICE, 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket{1}', DEVICE, 'SOURCE', script) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) @@ -385,20 +389,11 @@ def test_pytorch_scriptset(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket', DEVICE, 'TAG', 'asdf', 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket{1}', DEVICE, 'TAG', 'asdf', 'SOURCE', script) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - # TODO: Check why this COMMAND is hanging CI - # ret = con.execute_command('AI.SCRIPTGET', 'ket') - # env.assertEqual([b'CPU',script],ret) - # - # if env.useSlaves: - # con2 = env.getSlaveConnection() - # script_slave = con2.execute_command('AI.SCRIPTGET', 'ket') - # env.assertEqual(ret, script_slave) - def test_pytorch_scriptdel(env): if not TEST_PT: @@ -413,21 +408,21 @@ def test_pytorch_scriptdel(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket', DEVICE, 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket{1}', DEVICE, 'SOURCE', script) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.SCRIPTDEL', 'ket') + ret = con.execute_command('AI.SCRIPTDEL', 'ket{1}') env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - env.assertFalse(con.execute_command('EXISTS', 'ket')) + env.assertFalse(con.execute_command('EXISTS', 'ket{1}')) if env.useSlaves: con2 = env.getSlaveConnection() - env.assertFalse(con2.execute_command('EXISTS', 'ket')) + env.assertFalse(con2.execute_command('EXISTS', 'ket{1}')) # ERR no script at key from SCRIPTDEL try: @@ -461,28 +456,28 @@ def test_pytorch_scriptrun(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'myscript', DEVICE, 'TAG', 'version1', 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'myscript{1}', DEVICE, 'TAG', 'version1', 'SOURCE', script) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) for _ in range( 0,100): - ret = con.execute_command('AI.SCRIPTRUN', 'myscript', 'bar', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + ret = con.execute_command('AI.SCRIPTRUN', 'myscript{1}', 'bar', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'myscript') + info = con.execute_command('AI.INFO', 'myscript{1}') info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'myscript') + env.assertEqual(info_dict_0['key'], 'myscript{1}') env.assertEqual(info_dict_0['type'], 'SCRIPT') env.assertEqual(info_dict_0['backend'], 'TORCH') env.assertEqual(info_dict_0['tag'], 'version1') @@ -491,14 +486,14 @@ def test_pytorch_scriptrun(env): env.assertEqual(info_dict_0['calls'], 100) env.assertEqual(info_dict_0['errors'], 0) - values = con.execute_command('AI.TENSORGET', 'c', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values, [b'4', b'6', b'4', b'6']) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - values2 = con2.execute_command('AI.TENSORGET', 'c', 'VALUES') + values2 = con2.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values2, values) @@ -515,28 +510,28 @@ def test_pytorch_scriptrun_variadic(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'myscript', DEVICE, 'TAG', 'version1', 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'myscript{$}', DEVICE, 'TAG', 'version1', 'SOURCE', script) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{$}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b1', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b1{$}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b2', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b2{$}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) for _ in range( 0,100): - ret = con.execute_command('AI.SCRIPTRUN', 'myscript', 'bar_variadic', 'INPUTS', 'a', '$', 'b1', 'b2', 'OUTPUTS', 'c') + ret = con.execute_command('AI.SCRIPTRUN', 'myscript{$}', 'bar_variadic', 'INPUTS', 'a{$}', '$', 'b1{$}', 'b2{$}', 'OUTPUTS', 'c{$}') env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'myscript') + info = con.execute_command('AI.INFO', 'myscript{$}') info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'myscript') + env.assertEqual(info_dict_0['key'], 'myscript{$}') env.assertEqual(info_dict_0['type'], 'SCRIPT') env.assertEqual(info_dict_0['backend'], 'TORCH') env.assertEqual(info_dict_0['tag'], 'version1') @@ -545,14 +540,14 @@ def test_pytorch_scriptrun_variadic(env): env.assertEqual(info_dict_0['calls'], 100) env.assertEqual(info_dict_0['errors'], 0) - values = con.execute_command('AI.TENSORGET', 'c', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'c{$}', 'VALUES') env.assertEqual(values, [b'4', b'6', b'4', b'6']) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - values2 = con2.execute_command('AI.TENSORGET', 'c', 'VALUES') + values2 = con2.execute_command('AI.TENSORGET', 'c{$}', 'VALUES') env.assertEqual(values2, values) @@ -569,20 +564,20 @@ def test_pytorch_scriptrun_errors(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket', DEVICE, 'TAG', 'asdf', 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket{1}', DEVICE, 'TAG', 'asdf', 'SOURCE', script) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) # ERR no script at key from SCRIPTGET try: - con.execute_command('DEL', 'EMPTY') - con.execute_command('AI.SCRIPTGET', 'EMPTY') + con.execute_command('DEL', 'EMPTY{1}') + con.execute_command('AI.SCRIPTGET', 'EMPTY{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -590,8 +585,8 @@ def test_pytorch_scriptrun_errors(env): # ERR wrong type from SCRIPTGET try: - con.execute_command('SET', 'NOT_SCRIPT', 'BAR') - con.execute_command('AI.SCRIPTGET', 'NOT_SCRIPT') + con.execute_command('SET', 'NOT_SCRIPT{1}', 'BAR') + con.execute_command('AI.SCRIPTGET', 'NOT_SCRIPT{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -599,8 +594,8 @@ def test_pytorch_scriptrun_errors(env): # ERR no script at key from SCRIPTRUN try: - con.execute_command('DEL', 'EMPTY') - con.execute_command('AI.SCRIPTRUN', 'EMPTY', 'bar', 'INPUTS', 'b', 'OUTPUTS', 'c') + con.execute_command('DEL', 'EMPTY{1}') + con.execute_command('AI.SCRIPTRUN', 'EMPTY{1}', 'bar', 'INPUTS', 'b{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -608,8 +603,8 @@ def test_pytorch_scriptrun_errors(env): # ERR wrong type from SCRIPTRUN try: - con.execute_command('SET', 'NOT_SCRIPT', 'BAR') - con.execute_command('AI.SCRIPTRUN', 'NOT_SCRIPT', 'bar', 'INPUTS', 'b', 'OUTPUTS', 'c') + con.execute_command('SET', 'NOT_SCRIPT{1}', 'BAR') + con.execute_command('AI.SCRIPTRUN', 'NOT_SCRIPT{1}', 'bar', 'INPUTS', 'b{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -617,8 +612,8 @@ def test_pytorch_scriptrun_errors(env): # ERR Input key is empty try: - con.execute_command('DEL', 'EMPTY') - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar', 'INPUTS', 'EMPTY', 'b', 'OUTPUTS', 'c') + con.execute_command('DEL', 'EMPTY{1}') + con.execute_command('AI.SCRIPTRUN', 'ket{1}', 'bar', 'INPUTS', 'EMPTY{1}', 'b{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -626,33 +621,33 @@ def test_pytorch_scriptrun_errors(env): # ERR Input key not tensor try: - con.execute_command('SET', 'NOT_TENSOR', 'BAR') - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar', 'INPUTS', 'NOT_TENSOR', 'b', 'OUTPUTS', 'c') + con.execute_command('SET', 'NOT_TENSOR{1}', 'BAR') + con.execute_command('AI.SCRIPTRUN', 'ket{1}', 'bar', 'INPUTS', 'NOT_TENSOR{1}', 'b{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("WRONGTYPE Operation against a key holding the wrong kind of value", exception.__str__()) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar', 'INPUTS', 'b', 'OUTPUTS', 'c') + con.execute_command('AI.SCRIPTRUN', 'ket{1}', 'bar', 'INPUTS', 'b{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + con.execute_command('AI.SCRIPTRUN', 'ket{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar', 'INPUTS', 'b', 'OUTPUTS') + con.execute_command('AI.SCRIPTRUN', 'ket{1}', 'bar', 'INPUTS', 'b{1}', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar', 'INPUTS', 'OUTPUTS') + con.execute_command('AI.SCRIPTRUN', 'ket{1}', 'bar', 'INPUTS', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -671,20 +666,20 @@ def test_pytorch_scriptrun_variadic_errors(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket', DEVICE, 'TAG', 'asdf', 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket{$}', DEVICE, 'TAG', 'asdf', 'SOURCE', script) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{$}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{$}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) # ERR Variadic input key is empty try: - con.execute_command('DEL', 'EMPTY') - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar_variadic', 'INPUTS', 'a', '$', 'EMPTY', 'b', 'OUTPUTS', 'c') + con.execute_command('DEL', 'EMPTY{$}') + con.execute_command('AI.SCRIPTRUN', 'ket{$}', 'bar_variadic', 'INPUTS', 'a{$}', '$', 'EMPTY{$}', 'b{$}', 'OUTPUTS', 'c{$}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -692,34 +687,34 @@ def test_pytorch_scriptrun_variadic_errors(env): # ERR Variadic input key not tensor try: - con.execute_command('SET', 'NOT_TENSOR', 'BAR') - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar_variadic', 'INPUTS', 'a', '$' , 'NOT_TENSOR', 'b', 'OUTPUTS', 'c') + con.execute_command('SET', 'NOT_TENSOR{$}', 'BAR') + con.execute_command('AI.SCRIPTRUN', 'ket{$}', 'bar_variadic', 'INPUTS', 'a{$}', '$' , 'NOT_TENSOR{$}', 'b{$}', 'OUTPUTS', 'c{$}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("WRONGTYPE Operation against a key holding the wrong kind of value", exception.__str__()) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar_variadic', 'INPUTS', 'b', '$', 'OUTPUTS', 'c') + con.execute_command('AI.SCRIPTRUN', 'ket{$}', 'bar_variadic', 'INPUTS', 'b{$}', '${$}', 'OUTPUTS', 'c{$}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar_variadic', 'INPUTS', 'b', '$', 'OUTPUTS') + con.execute_command('AI.SCRIPTRUN', 'ket{$}', 'bar_variadic', 'INPUTS', 'b{$}', '$', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.SCRIPTRUN', 'ket', 'bar_variadic', 'INPUTS', '$', 'OUTPUTS') + con.execute_command('AI.SCRIPTRUN', 'ket{$}', 'bar_variadic', 'INPUTS', '$', 'OUTPUTS') 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') + 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) @@ -741,26 +736,26 @@ def test_pytorch_scriptinfo(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket_script', DEVICE, 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket_script{1}', DEVICE, 'SOURCE', script) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) previous_duration = 0 for call in range(1, 100): - ret = con.execute_command('AI.SCRIPTRUN', 'ket_script', 'bar', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + ret = con.execute_command('AI.SCRIPTRUN', 'ket_script{1}', 'bar', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'ket_script') + info = con.execute_command('AI.INFO', 'ket_script{1}') info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'ket_script') + env.assertEqual(info_dict_0['key'], 'ket_script{1}') env.assertEqual(info_dict_0['type'], 'SCRIPT') env.assertEqual(info_dict_0['backend'], 'TORCH') env.assertEqual(info_dict_0['device'], DEVICE) @@ -771,9 +766,9 @@ def test_pytorch_scriptinfo(env): previous_duration = info_dict_0['duration'] - res = con.execute_command('AI.INFO', 'ket_script', 'RESETSTAT') + res = con.execute_command('AI.INFO', 'ket_script{1}', 'RESETSTAT') env.assertEqual(res, b'OK') - info = con.execute_command('AI.INFO', 'ket_script') + info = con.execute_command('AI.INFO', 'ket_script{1}') info_dict_0 = info_to_dict(info) env.assertEqual(info_dict_0['duration'], 0) env.assertEqual(info_dict_0['samples'], -1) @@ -798,17 +793,17 @@ def test_pytorch_scriptrun_disconnect(env): with open(script_filename, 'rb') as f: script = f.read() - ret = con.execute_command('AI.SCRIPTSET', 'ket_script', DEVICE, 'SOURCE', script) + ret = con.execute_command('AI.SCRIPTSET', 'ket_script{1}', DEVICE, 'SOURCE', script) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = send_and_disconnect(('AI.SCRIPTRUN', 'ket_script', 'bar', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c'), con) + ret = send_and_disconnect(('AI.SCRIPTRUN', 'ket_script{1}', 'bar', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}'), con) env.assertEqual(ret, None) @@ -829,18 +824,18 @@ def test_pytorch_modelrun_disconnect(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + ret = con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = send_and_disconnect(('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c'), con) + ret = send_and_disconnect(('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}'), con) env.assertEqual(ret, None) @@ -906,15 +901,15 @@ def test_pytorch_model_rdb_save_load(env): con = env.getConnection() - ret = con.execute_command('AI.MODELSET', 'm', 'TORCH', DEVICE, 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TORCH', DEVICE, 'BLOB', model_pb) env.assertEqual(ret, b'OK') - model_serialized_memory = con.execute_command('AI.MODELGET', 'm', 'BLOB') + model_serialized_memory = con.execute_command('AI.MODELGET', 'm{1}', 'BLOB') - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') - _, dtype_memory, _, shape_memory, _, data_memory = con.execute_command('AI.TENSORGET', 'c', 'META', 'VALUES') + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') + _, dtype_memory, _, shape_memory, _, data_memory = con.execute_command('AI.TENSORGET', 'c{1}', 'META', 'VALUES') ensureSlaveSynced(con, env) ret = con.execute_command('SAVE') @@ -923,9 +918,9 @@ def test_pytorch_model_rdb_save_load(env): env.stop() env.start() con = env.getConnection() - model_serialized_after_rdbload = con.execute_command('AI.MODELGET', 'm', 'BLOB') - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') - _, dtype_after_rdbload, _, shape_after_rdbload, _, data_after_rdbload = con.execute_command('AI.TENSORGET', 'c', 'META', 'VALUES') + model_serialized_after_rdbload = con.execute_command('AI.MODELGET', 'm{1}', 'BLOB') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') + _, dtype_after_rdbload, _, shape_after_rdbload, _, data_after_rdbload = con.execute_command('AI.TENSORGET', 'c{1}', 'META', 'VALUES') # Assert in memory model metadata is equal to loaded model metadata env.assertTrue(model_serialized_memory[1:6] == model_serialized_after_rdbload[1:6]) diff --git a/test/tests_sanitizer.py b/test/tests_sanitizer.py index 8d0584f9f..29c4bae79 100644 --- a/test/tests_sanitizer.py +++ b/test/tests_sanitizer.py @@ -17,7 +17,7 @@ def test_sanitizer_dagrun_mobilenet_v1(env): print("exiting sanitizer test given we're not using stdlib allocator") return - model_name = 'mobilenet_v1' + model_name = 'mobilenet_v1{s}' model_pb, input_var, output_var, labels, img = load_mobilenet_v1_test_data() ret = con.execute_command('AI.MODELSET', model_name, 'TF', DEVICE, @@ -27,8 +27,8 @@ def test_sanitizer_dagrun_mobilenet_v1(env): env.assertEqual(ret, b'OK') for opnumber in range(1, MAX_ITERATIONS): - image_key = 'image{}'.format(opnumber) - class_key = 'output' + image_key = 'image{{s}}{}'.format(opnumber) + class_key = 'output{s}' ret = con.execute_command( 'AI.DAGRUN', '|>', @@ -53,7 +53,7 @@ def test_sanitizer_modelrun_mobilenet_v1(env): print("exiting sanitizer test given we're not using stdlib allocator") return - model_name = 'mobilenet_v1' + model_name = 'mobilenet_v1{s}' model_pb, input_var, output_var, labels, img = load_mobilenet_v1_test_data() ret = con.execute_command('AI.MODELSET', model_name, 'TF', DEVICE, @@ -63,10 +63,10 @@ def test_sanitizer_modelrun_mobilenet_v1(env): env.assertEqual(ret, b'OK') for opnumber in range(1, MAX_ITERATIONS): - image_key = 'image' - temp_key1 = 'temp_key1' - temp_key2 = 'temp_key2' - class_key = 'output' + image_key = 'image{s}' + temp_key1 = 'temp_key1{s}' + temp_key2 = 'temp_key2{s}' + class_key = 'output{s}' ret = con.execute_command( 'AI.TENSORSET', image_key, 'FLOAT', 1, 224, 224, 3, 'BLOB', img.tobytes() ) diff --git a/test/tests_tensorflow.py b/test/tests_tensorflow.py index f9e3a9b8f..68bc2de73 100644 --- a/test/tests_tensorflow.py +++ b/test/tests_tensorflow.py @@ -26,28 +26,28 @@ def test_run_mobilenet(env): model_pb, input_var, output_var, labels, img = load_mobilenet_v2_test_data() - con.execute_command('AI.MODELSET', 'mobilenet', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'mobilenet{1}', 'TF', DEVICE, 'INPUTS', input_var, 'OUTPUTS', output_var, 'BLOB', model_pb) ensureSlaveSynced(con, env) mobilenet_model_serialized = con.execute_command( - 'AI.MODELGET', 'mobilenet', 'META') + 'AI.MODELGET', 'mobilenet{1}', 'META') ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() slave_mobilenet_model_serialized = con2.execute_command( - 'AI.MODELGET', 'mobilenet', 'META') + 'AI.MODELGET', 'mobilenet{1}', 'META') env.assertEqual(len(mobilenet_model_serialized), len(slave_mobilenet_model_serialized)) - con.execute_command('AI.TENSORSET', 'input', + con.execute_command('AI.TENSORSET', 'input{1}', 'FLOAT', 1, img.shape[1], img.shape[0], img.shape[2], 'BLOB', img.tobytes()) ensureSlaveSynced(con, env) - input_tensor_meta = con.execute_command('AI.TENSORGET', 'input', 'META') + input_tensor_meta = con.execute_command('AI.TENSORGET', 'input{1}', 'META') env.assertEqual( [b'dtype', b'FLOAT', b'shape', [1, img.shape[1], img.shape[0], img.shape[2]]], input_tensor_meta) @@ -55,15 +55,15 @@ def test_run_mobilenet(env): if env.useSlaves: con2 = env.getSlaveConnection() slave_tensor_meta = con2.execute_command( - 'AI.TENSORGET', 'input', 'META') + 'AI.TENSORGET', 'input{1}', 'META') env.assertEqual(input_tensor_meta, slave_tensor_meta) - con.execute_command('AI.MODELRUN', 'mobilenet', - 'INPUTS', 'input', 'OUTPUTS', 'output') + con.execute_command('AI.MODELRUN', 'mobilenet{1}', + 'INPUTS', 'input{1}', 'OUTPUTS', 'output{1}') ensureSlaveSynced(con, env) - _, dtype, _, shape, _, data = con.execute_command('AI.TENSORGET', 'output', 'META', 'BLOB') + _, dtype, _, shape, _, data = con.execute_command('AI.TENSORGET', 'output{1}', 'META', 'BLOB') dtype_map = {b'FLOAT': np.float32} tensor = np.frombuffer(data, dtype=dtype_map[dtype]).reshape(shape) @@ -76,7 +76,7 @@ def test_run_mobilenet(env): if env.useSlaves: con2 = env.getSlaveConnection() _, slave_dtype, _, slave_shape, _, slave_data = con2.execute_command( - 'AI.TENSORGET', 'output', 'META', 'BLOB') + 'AI.TENSORGET', 'output{1}', 'META', 'BLOB') env.assertEqual(dtype, slave_dtype) env.assertEqual(shape, slave_shape) env.assertEqual(data, slave_data) @@ -92,7 +92,7 @@ def test_run_mobilenet_multiproc(env): con = env.getConnection() model_pb, input_var, output_var, labels, img = load_mobilenet_v2_test_data() - con.execute_command('AI.MODELSET', 'mobilenet', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'mobilenet{1}', 'TF', DEVICE, 'INPUTS', input_var, 'OUTPUTS', output_var, 'BLOB', model_pb) ensureSlaveSynced(con, env) @@ -100,7 +100,7 @@ def test_run_mobilenet_multiproc(env): ensureSlaveSynced(con, env) - _, dtype, _, shape, _, data = con.execute_command('AI.TENSORGET', 'output', 'META', 'BLOB') + _, dtype, _, shape, _, data = con.execute_command('AI.TENSORGET', 'output{1}', 'META', 'BLOB') dtype_map = {b'FLOAT': np.float32} tensor = np.frombuffer(data, dtype=dtype_map[dtype]).reshape(shape) @@ -115,7 +115,7 @@ def test_run_mobilenet_multiproc(env): if env.useSlaves: con2 = env.getSlaveConnection() _, slave_dtype, _, slave_shape, _, slave_data = con2.execute_command( - 'AI.TENSORGET', 'output', 'META', 'BLOB') + 'AI.TENSORGET', 'output{1}', 'META', 'BLOB') env.assertEqual(dtype, slave_dtype) env.assertEqual(shape, slave_shape) env.assertEqual(data, slave_data) @@ -131,23 +131,23 @@ def test_del_tf_model(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - con.execute_command('AI.MODELDEL', 'm') - env.assertFalse(con.execute_command('EXISTS', 'm')) + con.execute_command('AI.MODELDEL', 'm{1}') + env.assertFalse(con.execute_command('EXISTS', 'm{1}')) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - env.assertFalse(con2.execute_command('EXISTS', 'm')) + env.assertFalse(con2.execute_command('EXISTS', 'm{1}')) # ERR no model at key try: - con.execute_command('AI.MODELDEL', 'm') + con.execute_command('AI.MODELDEL', 'm{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -155,8 +155,8 @@ def test_del_tf_model(env): # ERR wrong type try: - con.execute_command('SET', 'NOT_MODEL', 'BAR') - con.execute_command('AI.MODELDEL', 'NOT_MODEL') + con.execute_command('SET', 'NOT_MODEL{1}', 'BAR') + con.execute_command('AI.MODELDEL', 'NOT_MODEL{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -174,26 +174,26 @@ def test_run_tf_model(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'') env.assertEqual(ret[11][0], b'a') env.assertEqual(ret[11][1], b'b') env.assertEqual(ret[13][0], b'mul') - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, 'TAG', 'version:1', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'TAG', 'version:1', 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) # TODO: enable me. CI is having issues on GPU asserts of TF and CPU if DEVICE == "CPU": @@ -204,40 +204,40 @@ def test_run_tf_model(env): env.assertEqual(ret[11][1], b'b') env.assertEqual(ret[13][0], b'mul') - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) ensureSlaveSynced(con, env) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'c', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values, [b'4', b'9', b'4', b'9']) if env.useSlaves: con2 = env.getSlaveConnection() - values2 = con2.execute_command('AI.TENSORGET', 'c', 'VALUES') + values2 = con2.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values2, values) for _ in env.reloadingIterator(): - env.assertExists('m') - env.assertExists('a') - env.assertExists('b') - env.assertExists('c') + env.assertExists('m{1}') + env.assertExists('a{1}') + env.assertExists('b{1}') + env.assertExists('c{1}') - con.execute_command('AI.MODELDEL', 'm') + con.execute_command('AI.MODELDEL', 'm{1}') ensureSlaveSynced(con, env) - env.assertFalse(con.execute_command('EXISTS', 'm')) + env.assertFalse(con.execute_command('EXISTS', 'm{1}')) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - env.assertFalse(con2.execute_command('EXISTS', 'm')) + env.assertFalse(con2.execute_command('EXISTS', 'm{1}')) @skip_if_no_TF @@ -250,25 +250,25 @@ def test_run_tf2_model(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'x', 'OUTPUTS', 'Identity', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'') env.assertEqual(ret[11][0], b'x') env.assertEqual(ret[13][0], b'Identity') - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, 'TAG', 'asdf', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'TAG', 'asdf', 'INPUTS', 'x', 'OUTPUTS', 'Identity', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'asdf') env.assertEqual(ret[11][0], b'x') @@ -276,38 +276,38 @@ def test_run_tf2_model(env): zero_values = [0] * (28 * 28) - con.execute_command('AI.TENSORSET', 'x', 'FLOAT', + con.execute_command('AI.TENSORSET', 'x{1}', 'FLOAT', 1, 1, 28, 28, 'VALUES', *zero_values) ensureSlaveSynced(con, env) - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'x', 'OUTPUTS', 'y') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'x{1}', 'OUTPUTS', 'y{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'y', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'y{1}', 'VALUES') for value in values: env.assertAlmostEqual(float(value), 0.1, 1E-4) if env.useSlaves: con2 = env.getSlaveConnection() - values2 = con2.execute_command('AI.TENSORGET', 'y', 'VALUES') + values2 = con2.execute_command('AI.TENSORGET', 'y{1}', 'VALUES') env.assertEqual(values2, values) for _ in env.reloadingIterator(): - env.assertExists('m') - env.assertExists('x') - env.assertExists('y') + env.assertExists('m{1}') + env.assertExists('x{1}') + env.assertExists('y{1}') - con.execute_command('AI.MODELDEL', 'm') + con.execute_command('AI.MODELDEL', 'm{1}') ensureSlaveSynced(con, env) - env.assertFalse(con.execute_command('EXISTS', 'm')) + env.assertFalse(con.execute_command('EXISTS', 'm{1}')) ensureSlaveSynced(con, env) if env.useSlaves: con2 = env.getSlaveConnection() - env.assertFalse(con2.execute_command('EXISTS', 'm')) + env.assertFalse(con2.execute_command('EXISTS', 'm{1}')) @skip_if_no_TF @@ -324,7 +324,7 @@ def test_run_tf_model_errors(env): with open(wrong_model_filename, 'rb') as f: wrong_model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') @@ -339,28 +339,28 @@ def test_run_tf_model_errors(env): "wrong number of arguments for 'AI.MODELGET' command", exception.__str__()) # ERR WRONGTYPE - con.execute_command('SET', 'NOT_MODEL', 'BAR') + con.execute_command('SET', 'NOT_MODEL{1}', 'BAR') try: - con.execute_command('AI.MODELGET', 'NOT_MODEL') + con.execute_command('AI.MODELGET', 'NOT_MODEL{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual( "WRONGTYPE Operation against a key holding the wrong kind of value", exception.__str__()) # cleanup - con.execute_command('DEL', 'NOT_MODEL') + con.execute_command('DEL', 'NOT_MODEL{1}') # ERR model key is empty - con.execute_command('DEL', 'DONT_EXIST') + con.execute_command('DEL', 'DONT_EXIST{1}') try: - con.execute_command('AI.MODELGET', 'DONT_EXIST') + con.execute_command('AI.MODELGET', 'DONT_EXIST{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("model key is empty", exception.__str__()) try: - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', wrong_model_pb) except Exception as e: exception = e @@ -368,7 +368,7 @@ def test_run_tf_model_errors(env): env.assertEqual("Invalid GraphDef", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_1', 'TF', + con.execute_command('AI.MODELSET', 'm_1{1}', 'TF', 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) except Exception as e: exception = e @@ -376,7 +376,7 @@ def test_run_tf_model_errors(env): env.assertEqual("Invalid DEVICE", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_2', 'PORCH', DEVICE, + con.execute_command('AI.MODELSET', 'm_2{1}', 'PORCH', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) except Exception as e: exception = e @@ -384,14 +384,14 @@ def test_run_tf_model_errors(env): env.assertEqual("unsupported backend", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_3', 'TORCH', DEVICE, + con.execute_command('AI.MODELSET', 'm_3{1}', 'TORCH', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) try: - con.execute_command('AI.MODELSET', 'm_4', 'TF', + con.execute_command('AI.MODELSET', 'm_4{1}', 'TF', 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) except Exception as e: exception = e @@ -399,7 +399,7 @@ def test_run_tf_model_errors(env): env.assertEqual("Invalid DEVICE", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_5', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'm_5{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'c', 'OUTPUTS', 'mul', 'BLOB', model_pb) except Exception as e: exception = e @@ -407,7 +407,7 @@ def test_run_tf_model_errors(env): env.assertEqual("WRONGTYPE Operation against a key holding the wrong kind of value", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_6', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'm_6{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mult', 'BLOB', model_pb) except Exception as e: exception = e @@ -415,14 +415,14 @@ def test_run_tf_model_errors(env): env.assertEqual("Output node named \"mult\" not found in TF graph", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_7', 'TF', DEVICE, 'BLOB', model_pb) + con.execute_command('AI.MODELSET', 'm_7{1}', 'TF', DEVICE, 'BLOB', model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Insufficient arguments, INPUTS and OUTPUTS not specified", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_8', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'm_8{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul') except Exception as e: exception = e @@ -430,7 +430,7 @@ def test_run_tf_model_errors(env): env.assertEqual("Insufficient arguments, missing model BLOB", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_8', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'm_8{1}', 'TF', DEVICE, 'INPUTS', 'a_', 'b', 'OUTPUTS', 'mul') except Exception as e: exception = e @@ -438,15 +438,15 @@ def test_run_tf_model_errors(env): env.assertEqual("Insufficient arguments, missing model BLOB", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_8', 'TF', DEVICE, - 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul_') + con.execute_command('AI.MODELSET', 'm_8{1}', 'TF', DEVICE, + 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'mul_') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Insufficient arguments, missing model BLOB", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_8', 'TF', DEVICE, + con.execute_command('AI.MODELSET', 'm_8{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS') except Exception as e: exception = e @@ -454,14 +454,14 @@ def test_run_tf_model_errors(env): env.assertEqual("Insufficient arguments, missing model BLOB",exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Number of names given as OUTPUTS during MODELSET and keys given as OUTPUTS here do not match", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -481,40 +481,40 @@ def test_run_tf_model_autobatch(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TF', 'CPU', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', 'CPU', 'BATCHSIZE', 4, 'MINBATCHSIZE', 3, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - con.execute_command('AI.TENSORSET', 'a', 'FLOAT', + con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'b', 'FLOAT', + con.execute_command('AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'd', 'FLOAT', + con.execute_command('AI.TENSORSET', 'd{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) - con.execute_command('AI.TENSORSET', 'e', 'FLOAT', + con.execute_command('AI.TENSORSET', 'e{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) ensureSlaveSynced(con, env) def run(): con = env.getConnection() - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', - 'd', 'e', 'OUTPUTS', 'f') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', + 'd{1}', 'e{1}', 'OUTPUTS', 'f{1}') ensureSlaveSynced(con, env) t = threading.Thread(target=run) t.start() - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'c', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'c{1}', 'VALUES') env.assertEqual(values, [b'4', b'9', b'4', b'9']) - values = con.execute_command('AI.TENSORGET', 'f', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'f{1}', 'VALUES') env.assertEqual(values, [b'4', b'9', b'4', b'9']) @@ -527,29 +527,29 @@ def test_tensorflow_modelinfo(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - info = con.execute_command('AI.INFO', 'm') # Getting initial info before modelrun + info = con.execute_command('AI.INFO', 'm{1}') # Getting initial info before modelrun info_dict0 = info_to_dict(info) - expected = {'key': 'm', 'type': 'MODEL', 'backend': 'TF', 'device': DEVICE, + expected = {'key': 'm{1}', 'type': 'MODEL', 'backend': 'TF', 'device': DEVICE, 'tag': '', 'duration': 0, 'samples': 0, 'calls': 0, 'errors': 0} env.assertEqual(info_dict0, expected) # second modelset; a corner case - ret = con.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - info = con.execute_command('AI.INFO', 'm') # this will fail + info = con.execute_command('AI.INFO', 'm{1}') # this will fail info_dict1 = info_to_dict(info) env.assertEqual(info_dict1, info_dict0) ret = con.execute_command( - 'AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + 'AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ret = con.execute_command( - 'AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + 'AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) @@ -557,14 +557,14 @@ def test_tensorflow_modelinfo(env): previous_duration = 0 for call in range(1, 10): ret = con.execute_command( - 'AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c') + 'AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}') env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'm') + info = con.execute_command('AI.INFO', 'm{1}') info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'm') + env.assertEqual(info_dict_0['key'], 'm{1}') env.assertEqual(info_dict_0['type'], 'MODEL') env.assertEqual(info_dict_0['backend'], 'TF') env.assertEqual(info_dict_0['device'], DEVICE) @@ -575,9 +575,9 @@ def test_tensorflow_modelinfo(env): previous_duration = info_dict_0['duration'] - res = con.execute_command('AI.INFO', 'm', 'RESETSTAT') + res = con.execute_command('AI.INFO', 'm{1}', 'RESETSTAT') env.assertEqual(res, b'OK') - info = con.execute_command('AI.INFO', 'm') + info = con.execute_command('AI.INFO', 'm{1}') info_dict_0 = info_to_dict(info) env.assertEqual(info_dict_0['duration'], 0) env.assertEqual(info_dict_0['samples'], 0) @@ -595,22 +595,22 @@ def test_tensorflow_modelrun_disconnect(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = red.execute_command('AI.MODELSET', 'm', 'TF', DEVICE, + ret = red.execute_command('AI.MODELSET', 'm{1}', 'TF', DEVICE, 'INPUTS', 'a', 'b', 'OUTPUTS', 'mul', 'BLOB', model_pb) env.assertEqual(ret, b'OK') ret = red.execute_command( - 'AI.TENSORSET', 'a', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + 'AI.TENSORSET', 'a{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ret = red.execute_command( - 'AI.TENSORSET', 'b', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) + 'AI.TENSORSET', 'b{1}', 'FLOAT', 2, 2, 'VALUES', 2, 3, 2, 3) env.assertEqual(ret, b'OK') ensureSlaveSynced(red, env) ret = send_and_disconnect( - ('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b', 'OUTPUTS', 'c'), red) + ('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}', 'OUTPUTS', 'c{1}'), red) env.assertEqual(ret, None) @@ -619,8 +619,8 @@ def test_tensorflow_modelrun_with_batch_and_minbatch(env): con = env.getConnection() batch_size = 2 minbatch_size = 2 - model_name = 'model' - another_model_name = 'another_model' + model_name = 'model{1}' + another_model_name = 'another_model{1}' model_pb, input_var, output_var, labels, img = load_mobilenet_v2_test_data() con.execute_command('AI.MODELSET', model_name, 'TF', DEVICE, @@ -628,14 +628,14 @@ def test_tensorflow_modelrun_with_batch_and_minbatch(env): 'INPUTS', input_var, 'OUTPUTS', output_var, 'BLOB', model_pb) - con.execute_command('AI.TENSORSET', 'input', + con.execute_command('AI.TENSORSET', 'input{1}', 'FLOAT', 1, img.shape[1], img.shape[0], img.shape[2], 'BLOB', img.tobytes()) - def run(name=model_name, output_name='output'): + def run(name=model_name, output_name='output{1}'): con = env.getConnection() con.execute_command('AI.MODELRUN', name, - 'INPUTS', 'input', 'OUTPUTS', output_name) + 'INPUTS', 'input{1}', 'OUTPUTS', output_name) # Running thrice since minbatchsize = 2 p1 = mp.Process(target=run) @@ -653,12 +653,12 @@ def run(name=model_name, output_name='output'): 'OUTPUTS', output_var, 'BLOB', model_pb) - p1b = mp.Process(target=run, args=(another_model_name, 'final1')) + p1b = mp.Process(target=run, args=(another_model_name, 'final1{1}')) p1b.start() - run(another_model_name, 'final2') + run(another_model_name, 'final2{1}') - _, dtype, _, shape, _, data = con.execute_command('AI.TENSORGET', 'final1', 'META', 'BLOB') + _, dtype, _, shape, _, data = con.execute_command('AI.TENSORGET', 'final1{1}', 'META', 'BLOB') dtype_map = {b'FLOAT': np.float32} tensor = np.frombuffer(data, dtype=dtype_map[dtype]).reshape(shape) label_id = np.argmax(tensor) - 1 @@ -678,7 +678,7 @@ def test_tensorflow_modelrun_financialNet(env): tensor_number = 1 for transaction_tensor in creditcard_transactions[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'transactionTensor:{0}'.format(tensor_number), + ret = con.execute_command('AI.TENSORSET', 'transactionTensor{{1}}:{0}'.format(tensor_number), 'FLOAT', 1, 30, 'BLOB', transaction_tensor.tobytes()) env.assertEqual(ret, b'OK') @@ -686,22 +686,22 @@ def test_tensorflow_modelrun_financialNet(env): tensor_number = 1 for reference_tensor in creditcard_referencedata[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), + ret = con.execute_command('AI.TENSORSET', 'referenceTensor{{1}}:{0}'.format(tensor_number), 'FLOAT', 1, 256, 'BLOB', reference_tensor.tobytes()) env.assertEqual(ret, b'OK') tensor_number = tensor_number + 1 - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'financialNet{1}', 'TF', DEVICE, 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') for tensor_number in range(1, MAX_TRANSACTIONS): for repetition in range(0, 10): - ret = con.execute_command('AI.MODELRUN', 'financialNet', 'INPUTS', - 'transactionTensor:{}'.format(tensor_number), - 'referenceTensor:{}'.format(tensor_number), 'OUTPUTS', - 'classificationTensor:{}_{}'.format(tensor_number, repetition)) + ret = con.execute_command('AI.MODELRUN', 'financialNet{1}', 'INPUTS', + 'transactionTensor{{1}}:{}'.format(tensor_number), + 'referenceTensor{{1}}:{}'.format(tensor_number), 'OUTPUTS', + 'classificationTensor{{1}}:{}_{}'.format(tensor_number, repetition)) env.assertEqual(ret, b'OK') @@ -712,7 +712,7 @@ def test_tensorflow_modelrun_financialNet_multiproc(env): tensor_number = 1 for transaction_tensor in creditcard_transactions[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'transactionTensor:{0}'.format(tensor_number), + ret = con.execute_command('AI.TENSORSET', 'transactionTensor{{1}}:{0}'.format(tensor_number), 'FLOAT', 1, 30, 'BLOB', transaction_tensor.tobytes()) env.assertEqual(ret, b'OK') @@ -720,23 +720,23 @@ def test_tensorflow_modelrun_financialNet_multiproc(env): tensor_number = 1 for reference_tensor in creditcard_referencedata[:MAX_TRANSACTIONS]: - ret = con.execute_command('AI.TENSORSET', 'referenceTensor:{0}'.format(tensor_number), + ret = con.execute_command('AI.TENSORSET', 'referenceTensor{{1}}:{0}'.format(tensor_number), 'FLOAT', 1, 256, 'BLOB', reference_tensor.tobytes()) env.assertEqual(ret, b'OK') tensor_number = tensor_number + 1 - ret = con.execute_command('AI.MODELSET', 'financialNet', 'TF', DEVICE, + ret = con.execute_command('AI.MODELSET', 'financialNet{1}', 'TF', DEVICE, 'INPUTS', 'transaction', 'reference', 'OUTPUTS', 'output', 'BLOB', model_pb) env.assertEqual(ret, b'OK') def functor_financialNet(env, key_max, repetitions): for tensor_number in range(1, key_max): for repetition in range(1, repetitions): - ret = env.execute_command('AI.MODELRUN', 'financialNet', 'INPUTS', - 'transactionTensor:{}'.format(tensor_number), - 'referenceTensor:{}'.format(tensor_number), 'OUTPUTS', - 'classificationTensor:{}_{}'.format(tensor_number, repetition)) + ret = env.execute_command('AI.MODELRUN', 'financialNet{1}', 'INPUTS', + 'transactionTensor{{1}}:{}'.format(tensor_number), + 'referenceTensor{{1}}:{}'.format(tensor_number), 'OUTPUTS', + 'classificationTensor{{1}}:{}_{}'.format(tensor_number, repetition)) t = time.time() run_test_multiproc(env, 10, @@ -751,8 +751,8 @@ def test_tensorflow_modelrun_scriptrun_resnet(env): if (not TEST_TF or not TEST_PT): return con = env.getConnection() - model_name = 'imagenet_model' - script_name = 'imagenet_script' + model_name = 'imagenet_model{1}' + script_name = 'imagenet_script{1}' inputvar = 'images' outputvar = 'output' @@ -768,9 +768,10 @@ def test_tensorflow_modelrun_scriptrun_resnet(env): ret = con.execute_command('AI.SCRIPTSET', script_name, DEVICE, 'SOURCE', script) env.assertEqual(ret, b'OK') - image_key = 'image1' - temp_key1 = 'temp_key1' - temp_key2 = 'temp_key2' + image_key = 'image1{1}' + temp_key1 = 'temp_key1{1}' + temp_key2 = 'temp_key2{1}' + output_key = 'output{1}' ret = con.execute_command('AI.TENSORSET', image_key, 'UINT8', img.shape[1], img.shape[0], 3, @@ -786,11 +787,11 @@ def test_tensorflow_modelrun_scriptrun_resnet(env): env.assertEqual(ret, b'OK') ret = con.execute_command('AI.SCRIPTRUN', script_name, - 'post_process', 'INPUTS', temp_key2, 'OUTPUTS', outputvar ) + 'post_process', 'INPUTS', temp_key2, 'OUTPUTS', output_key ) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.TENSORGET', outputvar, 'VALUES' ) + ret = con.execute_command('AI.TENSORGET', output_key, 'VALUES' ) # tf model has 100 classes [0,999] env.assertEqual(ret[0]>=0 and ret[0]<1001, True) diff --git a/test/tests_tflite.py b/test/tests_tflite.py index 947e486a9..a6f2c40b6 100644 --- a/test/tests_tflite.py +++ b/test/tests_tflite.py @@ -31,37 +31,37 @@ def test_run_tflite_model(env): with open(sample_filename, 'rb') as f: sample_raw = f.read() - ret = con.execute_command('AI.MODELSET', 'm', 'TFLITE', 'CPU', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TFLITE', 'CPU', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'') - ret = con.execute_command('AI.MODELSET', 'm', 'TFLITE', 'CPU', 'TAG', 'asdf', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TFLITE', 'CPU', 'TAG', 'asdf', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) env.assertEqual(ret[5], b'asdf') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - ret = con.execute_command('AI.MODELGET', 'm', 'META') + ret = con.execute_command('AI.MODELGET', 'm{1}', 'META') env.assertEqual(len(ret), 14) # TODO: enable me. CI is having issues on GPU asserts of TFLITE and CPU if DEVICE == "CPU": env.assertEqual(ret[1], b'TFLITE') env.assertEqual(ret[3], b'CPU') - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'OUTPUTS', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}', 'c{1}') ensureSlaveSynced(con, env) - values = con.execute_command('AI.TENSORGET', 'b', 'VALUES') + values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES') env.assertEqual(values[0], 1) @@ -90,40 +90,40 @@ def test_run_tflite_model_errors(env): with open(sample_filename, 'rb') as f: sample_raw = f.read() - ret = con.execute_command('AI.MODELSET', 'm_2', 'TFLITE', 'CPU', 'BLOB', model_pb2) + ret = con.execute_command('AI.MODELSET', 'm_2{1}', 'TFLITE', 'CPU', 'BLOB', model_pb2) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.MODELSET', 'm', 'TFLITE', 'CPU', 'TAG', 'asdf', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TFLITE', 'CPU', 'TAG', 'asdf', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) try: - con.execute_command('AI.MODELSET', 'm_1', 'TFLITE', model_pb) + con.execute_command('AI.MODELSET', 'm_1{1}', 'TFLITE', model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Insufficient arguments, missing model BLOB", exception.__str__()) try: - con.execute_command('AI.MODELSET', 'm_2', 'BLOB', model_pb) + con.execute_command('AI.MODELSET', 'm_2{1}', 'BLOB', model_pb) except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("unsupported backend", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_2', 'INPUTS', 'EMPTY_TENSOR', 'OUTPUTS') + con.execute_command('AI.MODELRUN', 'm_2{1}', 'INPUTS', 'EMPTY_TENSOR{1}', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("tensor key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_2') + con.execute_command('AI.MODELRUN', 'm_2{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -137,56 +137,56 @@ def test_run_tflite_model_errors(env): env.assertEqual("model key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_2', 'INPUTS', 'a', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm_2{1}', 'INPUTS', 'a{1}', 'b{1}', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("tensor key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_2', 'a', 'b', 'c') + con.execute_command('AI.MODELRUN', 'm_2{1}', 'a{1}', 'b{1}', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("INPUTS not specified", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm_2', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm_2{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("INPUTS not specified", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'OUTPUTS', 'c') + con.execute_command('AI.MODELRUN', 'm{1}', 'OUTPUTS', 'c{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("INPUTS not specified", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'b{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("tensor key is empty", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'OUTPUTS') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Inconsistent number of inputs", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'OUTPUTS') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'OUTPUTS') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) env.assertEqual("Inconsistent number of outputs", exception.__str__()) try: - con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'OUTPUTS', 'b') + con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}') except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) @@ -213,7 +213,7 @@ def test_run_tflite_model_autobatch(env): sample_raw = f.read() try: - ret = con.execute_command('AI.MODELSET', 'm', 'TFLITE', 'CPU', + ret = con.execute_command('AI.MODELSET', 'm{1}', 'TFLITE', 'CPU', 'BATCHSIZE', 2, 'MINBATCHSIZE', 2, 'BLOB', model_pb) except Exception as e: exception = e @@ -222,19 +222,19 @@ def test_run_tflite_model_autobatch(env): # env.assertEqual(ret, b'OK') - # con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) - # con.execute_command('AI.TENSORSET', 'c', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + # con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + # con.execute_command('AI.TENSORSET', 'c{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) # def run(): # con = env.getConnection() - # con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'c', 'OUTPUTS', 'd', 'd2') + # con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'c{1}', 'OUTPUTS', 'd', 'd2') # t = threading.Thread(target=run) # t.start() - # con.execute_command('AI.MODELRUN', 'm', 'INPUTS', 'a', 'OUTPUTS', 'b', 'b2') + # con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}', 'b2') - # values = con.execute_command('AI.TENSORGET', 'b', 'VALUES') + # values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES') # env.assertEqual(values[0], 1) @@ -263,24 +263,24 @@ def test_tflite_modelinfo(env): with open(sample_filename, 'rb') as f: sample_raw = f.read() - ret = con.execute_command('AI.MODELSET', 'mnist', 'TFLITE', 'CPU', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'mnist{1}', 'TFLITE', 'CPU', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = con.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + ret = con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) previous_duration = 0 for call in range(1, 10): - ret = con.execute_command('AI.MODELRUN', 'mnist', 'INPUTS', 'a', 'OUTPUTS', 'b', 'c') + ret = con.execute_command('AI.MODELRUN', 'mnist{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}', 'c{1}') env.assertEqual(ret, b'OK') ensureSlaveSynced(con, env) - info = con.execute_command('AI.INFO', 'mnist') + info = con.execute_command('AI.INFO', 'mnist{1}') info_dict_0 = info_to_dict(info) - env.assertEqual(info_dict_0['key'], 'mnist') + env.assertEqual(info_dict_0['key'], 'mnist{1}') env.assertEqual(info_dict_0['type'], 'MODEL') env.assertEqual(info_dict_0['backend'], 'TFLITE') env.assertEqual(info_dict_0['device'], DEVICE) @@ -291,9 +291,9 @@ def test_tflite_modelinfo(env): previous_duration = info_dict_0['duration'] - res = con.execute_command('AI.INFO', 'mnist', 'RESETSTAT') + res = con.execute_command('AI.INFO', 'mnist{1}', 'RESETSTAT') env.assertEqual(res, b'OK') - info = con.execute_command('AI.INFO', 'mnist') + info = con.execute_command('AI.INFO', 'mnist{1}') info_dict_0 = info_to_dict(info) env.assertEqual(info_dict_0['duration'], 0) env.assertEqual(info_dict_0['samples'], 0) @@ -317,15 +317,15 @@ def test_tflite_modelrun_disconnect(env): with open(sample_filename, 'rb') as f: sample_raw = f.read() - ret = red.execute_command('AI.MODELSET', 'mnist', 'TFLITE', 'CPU', 'BLOB', model_pb) + ret = red.execute_command('AI.MODELSET', 'mnist{1}', 'TFLITE', 'CPU', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - ret = red.execute_command('AI.TENSORSET', 'a', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) + ret = red.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw) env.assertEqual(ret, b'OK') ensureSlaveSynced(red, env) - ret = send_and_disconnect(('AI.MODELRUN', 'mnist', 'INPUTS', 'a', 'OUTPUTS', 'b', 'c'), red) + ret = send_and_disconnect(('AI.MODELRUN', 'mnist{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}', 'c{1}'), red) env.assertEqual(ret, None) @@ -342,10 +342,10 @@ def test_tflite_model_rdb_save_load(env): with open(model_filename, 'rb') as f: model_pb = f.read() - ret = con.execute_command('AI.MODELSET', 'mnist', 'TFLITE', 'CPU', 'BLOB', model_pb) + ret = con.execute_command('AI.MODELSET', 'mnist{1}', 'TFLITE', 'CPU', 'BLOB', model_pb) env.assertEqual(ret, b'OK') - model_serialized_memory = con.execute_command('AI.MODELGET', 'mnist', 'BLOB') + model_serialized_memory = con.execute_command('AI.MODELGET', 'mnist{1}', 'BLOB') ensureSlaveSynced(con, env) ret = con.execute_command('SAVE') @@ -354,7 +354,7 @@ def test_tflite_model_rdb_save_load(env): env.stop() env.start() con = env.getConnection() - model_serialized_after_rdbload = con.execute_command('AI.MODELGET', 'mnist', 'BLOB') + model_serialized_after_rdbload = con.execute_command('AI.MODELGET', 'mnist{1}', 'BLOB') env.assertEqual(len(model_serialized_memory), len(model_serialized_after_rdbload)) env.assertEqual(len(model_pb), len(model_serialized_after_rdbload)) # Assert in memory model binary is equal to loaded model binary