Skip to content

Commit

Permalink
[add] added support for scriptset, scriptget, scriptrun, scriptdel, m…
Browse files Browse the repository at this point in the history
…odeldel, and modelget
  • Loading branch information
filipecosta90 committed May 15, 2020
1 parent e05df1e commit 3c5de6b
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 63 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,28 @@ var fs = require("fs");
```


### Supported RedisAI Commands

| Command | Recommended API and JSDoc |
| :--- | ----: |
AI.TENSORSET | tensorset
AI.TENSORGET | tensorget
AI.MODELSET | modelset
AI.MODELGET | modelget
AI.MODELDEL | modeldet
AI.MODELRUN | modelrun
AI._MODELSCAN | N/A
AI.SCRIPTSET | scriptset
AI.SCRIPTGET | scriptget
AI.SCRIPTDEL | scriptdel
AI.SCRIPTRUN | scriptrun
AI._SCRIPTSCAN | N/A
AI.DAGRUN | N/A
AI.DAGRUN_RO | N/A
AI.INFO |
AI.CONFIG * | N/A


### Running tests

A simple test suite is provided, and can be run with:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"types": "lib/index.d.ts",
"scripts": {
"build": "tsc",
"format": "prettier --write \"src/**/*.ts\" ",
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" ",
"lint": "tslint -p tsconfig.json",
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run lint",
Expand Down
114 changes: 114 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Tensor } from './tensor';
import { Model } from './model';
import * as util from 'util';
import { DTypeMap } from './dtype';
import { Script } from './script';
import { BackendMap } from './backend';

export class Client {
private _sendCommand: any;
Expand Down Expand Up @@ -67,6 +69,10 @@ export class Client {

public modelset(keName: string, m: Model): Promise<any> {
const args = [keName, m.backend, m.device];
if (m.tag !== undefined) {
args.push('TAG');
args.push(m.tag.toString());
}
if (m.inputs.length > 0) {
args.push('INPUTS');
m.inputs.forEach((value) => args.push(value));
Expand All @@ -87,4 +93,112 @@ export class Client {
outputs.forEach((value) => args.push(value));
return this._sendCommand('ai.modelrun', args);
}

public modeldel(modelName: string): Promise<any> {
const args = [modelName];
return this._sendCommand('ai.modeldel', args);
}

public modelget(modelName: string): Promise<any> {
const args = [modelName, 'META', 'BLOB'];
return this._sendCommand('ai.modelget', args)
.then((reply: any[]) => {
let backend = null;
let device = null;
let tag = null;
let blob = null;
for (let i = 0; i < reply.length; i += 2) {
const key = reply[i];
const obj = reply[i + 1];
switch (key.toString()) {
case 'backend':
backend = BackendMap[obj.toString()];
break;
case 'device':
// @ts-ignore
device = obj.toString();
break;
case 'tag':
tag = obj.toString();
break;
case 'blob':
// blob = obj;
blob = Buffer.from(obj);
break;
}
}
if (backend == null || device == null || blob == null) {
throw Error('modelget reply did not had the full elements to build the tensor');
}
const model = new Model(backend, device, [], [], blob);
if (tag !== null) {
model.tag = tag;
}
return model;
})
.catch((error: any) => {
throw error;
});
}

public scriptset(keName: string, s: Script): Promise<any> {
const args = [keName, s.device];
if (s.tag !== undefined) {
args.push('TAG');
args.push(s.tag);
}
args.push('SOURCE');
args.push(s.script);
return this._sendCommand('ai.scriptset', args);
}

public scriptrun(scriptName: string, functionName: string, inputs: string[], outputs: string[]): Promise<any> {
const args = [scriptName, functionName, 'INPUTS'];
inputs.forEach((value) => args.push(value));
args.push('OUTPUTS');
outputs.forEach((value) => args.push(value));
return this._sendCommand('ai.scriptrun', args);
}

public scriptdel(scriptName: string): Promise<any> {
const args = [scriptName];
return this._sendCommand('ai.scriptdel', args);
}

public scriptget(scriptName: string): Promise<any> {
const args = [scriptName, 'META', 'SOURCE'];
return this._sendCommand('ai.scriptget', args)
.then((reply: any[]) => {
let device = null;
let tag = null;
let source = null;
for (let i = 0; i < reply.length; i += 2) {
const key = reply[i];
const obj = reply[i + 1];
switch (key.toString()) {
case 'device':
// @ts-ignore
device = obj.toString();
break;
case 'tag':
tag = obj.toString();
break;
case 'source':
source = obj.toString();
break;
}
}
if (device == null || source == null) {
throw Error('scriptget reply did not had the full elements to build the tensor');
}
const script = new Script(device, source);
if (tag !== null) {
script.tag = tag;
}
return script;
})
.catch((error: any) => {
throw error;
});
}
}
9 changes: 5 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { DTypeMap, Dtype } from './dtype';
import { Model } from './model';
import { BackendMap, Backend } from './backend';
import { Dtype, DTypeMap } from './dtype';
import { Backend, BackendMap } from './backend';
import { Tensor } from './tensor';
import { Model } from './model';
import { Script } from './script';
import { Client } from './client';

export { DTypeMap, Dtype, BackendMap, Backend, Model, Tensor, Client };
export { DTypeMap, Dtype, BackendMap, Backend, Model, Script, Tensor, Client };
24 changes: 24 additions & 0 deletions src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,36 @@
import { Backend } from './backend';

export class Model {
/**
*
* @param backend - the backend for the model. can be one of TF, TFLITE, TORCH or ONNX
* @param device - the device that will execute the model. can be of CPU or GPU
* @param inputs - one or more names of the model's input nodes (applicable only for TensorFlow models)
* @param outputs - one or more names of the model's output nodes (applicable only for TensorFlow models)
* @param blob - the Protobuf-serialized model
*/
constructor(backend: Backend, device: string, inputs: string[], outputs: string[], blob: Buffer | undefined) {
this._backend = backend;
this._device = device;
this._inputs = inputs;
this._outputs = outputs;
this._blob = blob;
this._tag = undefined;
}

// tag is an optional string for tagging the model such as a version number or any arbitrary identifier
private _tag: string | undefined;

get tag(): string | undefined {
return this._tag;
}

/**
* sets an optional string for tagging the model such as a version number or any arbitrary identifier
* @param value
*/
set tag(value: string | undefined) {
this._tag = value;
}

private _backend: Backend;
Expand Down
51 changes: 51 additions & 0 deletions src/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Direct mapping to RedisAI Script
*/

export class Script {
/**
*
* @param device - the device that will execute the model. can be of CPU or GPU
* @param script - a string containing TorchScript source code
*/
constructor(device: string, script: string) {
this._device = device;
this._script = script;
this._tag = undefined;
}

// tag is an optional string for tagging the model such as a version number or any arbitrary identifier
private _tag: string | undefined;

get tag(): string | undefined {
return this._tag;
}

/**
* sets an optional string for tagging the model such as a version number or any arbitrary identifier
* @param value
*/
set tag(value: string | undefined) {
this._tag = value;
}

private _device: string;

get device(): string {
return this._device;
}

set device(value: string) {
this._device = value;
}

private _script: string;

get script(): string {
return this._script;
}

set script(value: string) {
this._script = value;
}
}
6 changes: 6 additions & 0 deletions src/tensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { Dtype } from './dtype';
* Direct mapping to RedisAI Tensors - represents an n-dimensional array of values
*/
export class Tensor {
/**
* Creates a tensor - represents an n-dimensional array of values
* @param dtype the tensor's data type
* @param shape one or more dimensions, or the number of elements per axis, for the tensor
* @param data numeric data provided by one or more subsequent val arguments
*/
constructor(dtype: Dtype, shape: number[], data: number[] | null) {
this._shape = shape;
this._dtype = dtype;
Expand Down
Loading

0 comments on commit 3c5de6b

Please sign in to comment.