Skip to content

Commit 3c5de6b

Browse files
committed
[add] added support for scriptset, scriptget, scriptrun, scriptdel, modeldel, and modelget
1 parent e05df1e commit 3c5de6b

File tree

8 files changed

+443
-63
lines changed

8 files changed

+443
-63
lines changed

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,28 @@ var fs = require("fs");
8686
```
8787

8888

89+
### Supported RedisAI Commands
90+
91+
| Command | Recommended API and JSDoc |
92+
| :--- | ----: |
93+
AI.TENSORSET | tensorset
94+
AI.TENSORGET | tensorget
95+
AI.MODELSET | modelset
96+
AI.MODELGET | modelget
97+
AI.MODELDEL | modeldet
98+
AI.MODELRUN | modelrun
99+
AI._MODELSCAN | N/A
100+
AI.SCRIPTSET | scriptset
101+
AI.SCRIPTGET | scriptget
102+
AI.SCRIPTDEL | scriptdel
103+
AI.SCRIPTRUN | scriptrun
104+
AI._SCRIPTSCAN | N/A
105+
AI.DAGRUN | N/A
106+
AI.DAGRUN_RO | N/A
107+
AI.INFO |
108+
AI.CONFIG * | N/A
109+
110+
89111
### Running tests
90112

91113
A simple test suite is provided, and can be run with:

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"types": "lib/index.d.ts",
77
"scripts": {
88
"build": "tsc",
9-
"format": "prettier --write \"src/**/*.ts\" ",
9+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" ",
1010
"lint": "tslint -p tsconfig.json",
1111
"prepare": "npm run build",
1212
"prepublishOnly": "npm test && npm run lint",

src/client.ts

+114
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Tensor } from './tensor';
33
import { Model } from './model';
44
import * as util from 'util';
55
import { DTypeMap } from './dtype';
6+
import { Script } from './script';
7+
import { BackendMap } from './backend';
68

79
export class Client {
810
private _sendCommand: any;
@@ -67,6 +69,10 @@ export class Client {
6769

6870
public modelset(keName: string, m: Model): Promise<any> {
6971
const args = [keName, m.backend, m.device];
72+
if (m.tag !== undefined) {
73+
args.push('TAG');
74+
args.push(m.tag.toString());
75+
}
7076
if (m.inputs.length > 0) {
7177
args.push('INPUTS');
7278
m.inputs.forEach((value) => args.push(value));
@@ -87,4 +93,112 @@ export class Client {
8793
outputs.forEach((value) => args.push(value));
8894
return this._sendCommand('ai.modelrun', args);
8995
}
96+
97+
public modeldel(modelName: string): Promise<any> {
98+
const args = [modelName];
99+
return this._sendCommand('ai.modeldel', args);
100+
}
101+
102+
public modelget(modelName: string): Promise<any> {
103+
const args = [modelName, 'META', 'BLOB'];
104+
return this._sendCommand('ai.modelget', args)
105+
.then((reply: any[]) => {
106+
let backend = null;
107+
let device = null;
108+
let tag = null;
109+
let blob = null;
110+
for (let i = 0; i < reply.length; i += 2) {
111+
const key = reply[i];
112+
const obj = reply[i + 1];
113+
switch (key.toString()) {
114+
case 'backend':
115+
backend = BackendMap[obj.toString()];
116+
break;
117+
case 'device':
118+
// @ts-ignore
119+
device = obj.toString();
120+
break;
121+
case 'tag':
122+
tag = obj.toString();
123+
break;
124+
case 'blob':
125+
// blob = obj;
126+
blob = Buffer.from(obj);
127+
break;
128+
}
129+
}
130+
if (backend == null || device == null || blob == null) {
131+
throw Error('modelget reply did not had the full elements to build the tensor');
132+
}
133+
const model = new Model(backend, device, [], [], blob);
134+
if (tag !== null) {
135+
model.tag = tag;
136+
}
137+
return model;
138+
})
139+
.catch((error: any) => {
140+
throw error;
141+
});
142+
}
143+
144+
public scriptset(keName: string, s: Script): Promise<any> {
145+
const args = [keName, s.device];
146+
if (s.tag !== undefined) {
147+
args.push('TAG');
148+
args.push(s.tag);
149+
}
150+
args.push('SOURCE');
151+
args.push(s.script);
152+
return this._sendCommand('ai.scriptset', args);
153+
}
154+
155+
public scriptrun(scriptName: string, functionName: string, inputs: string[], outputs: string[]): Promise<any> {
156+
const args = [scriptName, functionName, 'INPUTS'];
157+
inputs.forEach((value) => args.push(value));
158+
args.push('OUTPUTS');
159+
outputs.forEach((value) => args.push(value));
160+
return this._sendCommand('ai.scriptrun', args);
161+
}
162+
163+
public scriptdel(scriptName: string): Promise<any> {
164+
const args = [scriptName];
165+
return this._sendCommand('ai.scriptdel', args);
166+
}
167+
168+
public scriptget(scriptName: string): Promise<any> {
169+
const args = [scriptName, 'META', 'SOURCE'];
170+
return this._sendCommand('ai.scriptget', args)
171+
.then((reply: any[]) => {
172+
let device = null;
173+
let tag = null;
174+
let source = null;
175+
for (let i = 0; i < reply.length; i += 2) {
176+
const key = reply[i];
177+
const obj = reply[i + 1];
178+
switch (key.toString()) {
179+
case 'device':
180+
// @ts-ignore
181+
device = obj.toString();
182+
break;
183+
case 'tag':
184+
tag = obj.toString();
185+
break;
186+
case 'source':
187+
source = obj.toString();
188+
break;
189+
}
190+
}
191+
if (device == null || source == null) {
192+
throw Error('scriptget reply did not had the full elements to build the tensor');
193+
}
194+
const script = new Script(device, source);
195+
if (tag !== null) {
196+
script.tag = tag;
197+
}
198+
return script;
199+
})
200+
.catch((error: any) => {
201+
throw error;
202+
});
203+
}
90204
}

src/index.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { DTypeMap, Dtype } from './dtype';
2-
import { Model } from './model';
3-
import { BackendMap, Backend } from './backend';
1+
import { Dtype, DTypeMap } from './dtype';
2+
import { Backend, BackendMap } from './backend';
43
import { Tensor } from './tensor';
4+
import { Model } from './model';
5+
import { Script } from './script';
56
import { Client } from './client';
67

7-
export { DTypeMap, Dtype, BackendMap, Backend, Model, Tensor, Client };
8+
export { DTypeMap, Dtype, BackendMap, Backend, Model, Script, Tensor, Client };

src/model.ts

+24
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,36 @@
44
import { Backend } from './backend';
55

66
export class Model {
7+
/**
8+
*
9+
* @param backend - the backend for the model. can be one of TF, TFLITE, TORCH or ONNX
10+
* @param device - the device that will execute the model. can be of CPU or GPU
11+
* @param inputs - one or more names of the model's input nodes (applicable only for TensorFlow models)
12+
* @param outputs - one or more names of the model's output nodes (applicable only for TensorFlow models)
13+
* @param blob - the Protobuf-serialized model
14+
*/
715
constructor(backend: Backend, device: string, inputs: string[], outputs: string[], blob: Buffer | undefined) {
816
this._backend = backend;
917
this._device = device;
1018
this._inputs = inputs;
1119
this._outputs = outputs;
1220
this._blob = blob;
21+
this._tag = undefined;
22+
}
23+
24+
// tag is an optional string for tagging the model such as a version number or any arbitrary identifier
25+
private _tag: string | undefined;
26+
27+
get tag(): string | undefined {
28+
return this._tag;
29+
}
30+
31+
/**
32+
* sets an optional string for tagging the model such as a version number or any arbitrary identifier
33+
* @param value
34+
*/
35+
set tag(value: string | undefined) {
36+
this._tag = value;
1337
}
1438

1539
private _backend: Backend;

src/script.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Direct mapping to RedisAI Script
3+
*/
4+
5+
export class Script {
6+
/**
7+
*
8+
* @param device - the device that will execute the model. can be of CPU or GPU
9+
* @param script - a string containing TorchScript source code
10+
*/
11+
constructor(device: string, script: string) {
12+
this._device = device;
13+
this._script = script;
14+
this._tag = undefined;
15+
}
16+
17+
// tag is an optional string for tagging the model such as a version number or any arbitrary identifier
18+
private _tag: string | undefined;
19+
20+
get tag(): string | undefined {
21+
return this._tag;
22+
}
23+
24+
/**
25+
* sets an optional string for tagging the model such as a version number or any arbitrary identifier
26+
* @param value
27+
*/
28+
set tag(value: string | undefined) {
29+
this._tag = value;
30+
}
31+
32+
private _device: string;
33+
34+
get device(): string {
35+
return this._device;
36+
}
37+
38+
set device(value: string) {
39+
this._device = value;
40+
}
41+
42+
private _script: string;
43+
44+
get script(): string {
45+
return this._script;
46+
}
47+
48+
set script(value: string) {
49+
this._script = value;
50+
}
51+
}

src/tensor.ts

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import { Dtype } from './dtype';
44
* Direct mapping to RedisAI Tensors - represents an n-dimensional array of values
55
*/
66
export class Tensor {
7+
/**
8+
* Creates a tensor - represents an n-dimensional array of values
9+
* @param dtype the tensor's data type
10+
* @param shape one or more dimensions, or the number of elements per axis, for the tensor
11+
* @param data numeric data provided by one or more subsequent val arguments
12+
*/
713
constructor(dtype: Dtype, shape: number[], data: number[] | null) {
814
this._shape = shape;
915
this._dtype = dtype;

0 commit comments

Comments
 (0)