|
514 | 514 | The `AI.SCRIPTDEL` is equivalent to the [Redis `DEL` command](https://redis.io/commands/del) and should be used in its stead. This ensures compatibility with all deployment options (i.e., stand-alone vs. cluster, OSS vs. Enterprise). |
515 | 515 |
|
516 | 516 |
|
| 517 | +## AI.SCRIPTEXECUTE |
| 518 | + |
| 519 | +The **`AI.SCRIPTEXECUTE`** command runs a script stored as a key's value on its specified device. It accepts one or more inputs, where the inputs could be tensors stored in RedisAI, int, float, or strings and stores the script outputs as RedisAI tensors if required. |
| 520 | + |
| 521 | +The run request is put in a queue and is executed asynchronously by a worker thread. The client that had issued the run request is blocked until the script run is completed. When needed, tensors data is automatically copied to the device prior to execution. |
| 522 | + |
| 523 | +A `TIMEOUT t` argument can be specified to cause a request to be removed from the queue after it sits there `t` milliseconds, meaning that the client won't be interested in the result being computed after that time (`TIMEDOUT` is returned in that case). |
| 524 | + |
| 525 | +!!! warning "Intermediate memory overhead" |
| 526 | + The execution of models will generate intermediate tensors that are not allocated by the Redis allocator, but by whatever allocator is used in the TORCH backend (which may act on main memory or GPU memory, depending on the device), thus not being limited by `maxmemory` configuration settings of Redis. |
| 527 | + |
| 528 | +**Redis API** |
| 529 | + |
| 530 | +``` |
| 531 | +AI.SCRIPTEXECUTE <key> <function> |
| 532 | +KEYS n <key> [keys...] |
| 533 | +[INPUTS m <input> [input ...] | [LIST_INPUTS l <input> [input ...]]*] |
| 534 | +[OUTPUTS k <output> [output ...] [TIMEOUT t]]+ |
| 535 | +``` |
| 536 | + |
| 537 | +_Arguments_ |
| 538 | + |
| 539 | +* **key**: the script's key name |
| 540 | +* **function**: the name of the function to run |
| 541 | +* **KEYS**: Either a squence of key names that the script will access before, during and after its execution, or a tag which all those keys share. `KEYS` is a mandatory scope in this command. Redis will verify that all potional key accesses are done to the right shard. |
| 542 | +* **INPUTS**: Denotes the beginning of the input parameters list, followed by its length and one or more inputs; The inputs can be tensor key name, `string`, `int` or `float`. The order of the input should be aligned with the order of their respected parameter at the function signature. Note that list inputs are treated in the **LIST_INPUTS** scope. |
| 543 | +* **LIST_INPUTS** Denotes the beginning of a list, followed by its length and one or more inputs; The inputs can be tensor key name, `string`, `int` or `float`. The order of the input should be aligned with the order of their respected parameter at the function signature. Note that if more than one list is provided, their order should be aligned with the order of their respected paramter at the function signature. |
| 544 | + |
| 545 | +* **OUTPUTS**: denotes the beginning of the output tensors keys' list, followed by its length and one or more key names. |
| 546 | +* **TIMEOUT**: the time (in ms) after which the client is unblocked and a `TIMEDOUT` string is returned |
| 547 | + |
| 548 | +_Return_ |
| 549 | + |
| 550 | +A simple 'OK' string, a simple `TIMEDOUT` string, or an error. |
| 551 | + |
| 552 | +**Examples** |
| 553 | + |
| 554 | +The following is an example of running the previously-created 'myscript' on two input tensors: |
| 555 | + |
| 556 | +``` |
| 557 | +redis> AI.TENSORSET mytensor1 FLOAT 1 VALUES 40 |
| 558 | +OK |
| 559 | +redis> AI.TENSORSET mytensor2 FLOAT 1 VALUES 2 |
| 560 | +OK |
| 561 | +redis> AI.SCRIPTEXECUTE myscript addtwo KEYS 3 mytensor1 mytensor2 result INPUTS 2 mytensor1 mytensor2 OUTPUTS 1 result |
| 562 | +OK |
| 563 | +redis> AI.TENSORGET result VALUES |
| 564 | +1) FLOAT |
| 565 | +2) 1) (integer) 1 |
| 566 | +3) 1) "42" |
| 567 | +``` |
| 568 | + |
| 569 | +Note: The above command could be executed with a shorter version, given all the keys are tagged with the same tag: |
| 570 | + |
| 571 | +``` |
| 572 | +redis> AI.TENSORSET mytensor1{tag} FLOAT 1 VALUES 40 |
| 573 | +OK |
| 574 | +redis> AI.TENSORSET mytensor2{tag} FLOAT 1 VALUES 2 |
| 575 | +OK |
| 576 | +redis> AI.SCRIPTEXECUTE myscript{tag} addtwo KEYS 1 {tag} INPUTS 2 mytensor1{tag} mytensor2{tag} OUTPUTS 1 result{tag} |
| 577 | +OK |
| 578 | +redis> AI.TENSORGET result{tag} VALUES |
| 579 | +1) FLOAT |
| 580 | +2) 1) (integer) 1 |
| 581 | +3) 1) "42" |
| 582 | +``` |
| 583 | + |
| 584 | +If 'myscript' supports `List[Tensor]` arguments: |
| 585 | +```python |
| 586 | +def addn(a, args : List[Tensor]): |
| 587 | + return a + torch.stack(args).sum() |
| 588 | +``` |
| 589 | + |
| 590 | +``` |
| 591 | +redis> AI.TENSORSET mytensor1{tag} FLOAT 1 VALUES 40 |
| 592 | +OK |
| 593 | +redis> AI.TENSORSET mytensor2{tag} FLOAT 1 VALUES 1 |
| 594 | +OK |
| 595 | +redis> AI.TENSORSET mytensor3{tag} FLOAT 1 VALUES 1 |
| 596 | +OK |
| 597 | +redis> AI.SCRIPTEXECUTE myscript{tag} addn keys 1 {tag} INPUTS 1 mytensor1{tag} LIST_INPUTS 2 mytensor2{tag} mytensor3{tag} OUTPUTS 1 result{tag} |
| 598 | +OK |
| 599 | +redis> AI.TENSORGET result{tag} VALUES |
| 600 | +1) FLOAT |
| 601 | +2) 1) (integer) 1 |
| 602 | +3) 1) "42" |
| 603 | +``` |
| 604 | + |
| 605 | +### Redis Commands support. |
| 606 | +In RedisAI TorchScript now supports simple (non-blocking) Redis commnands via the `redis.execute` API. The following (usless) script gets a key name (`x{1}`), and an `int` value (3). First, the script `SET`s the value in the key. Next, the script `GET`s the value back from the key, and sets it in a tensor which is eventually stored under the key 'y{1}'. Note that the inputs are `str` and `int`. The script sets and gets the value and set it into a tensor. |
| 607 | + |
| 608 | +``` |
| 609 | +def redis_int_to_tensor(redis_value: int): |
| 610 | + return torch.tensor(redis_value) |
| 611 | +
|
| 612 | +def int_set_get(key:str, value:int): |
| 613 | + redis.execute("SET", key, str(value)) |
| 614 | + res = redis.execute("GET", key) |
| 615 | + return redis_string_int_to_tensor(res) |
| 616 | +``` |
| 617 | +``` |
| 618 | +redis> AI.SCRIPTEXECUTE redis_scripts{1} int_set_get KEYS 1 {1} INPUTS 2 x{1} 3 OUTPUTS 1 y{1} |
| 619 | +OK |
| 620 | +redis> AI.TENSORGET y{1} VALUES |
| 621 | +1) (integer) 3 |
| 622 | +``` |
| 623 | + |
| 624 | +!!! warning "Intermediate memory overhead" |
| 625 | + The execution of scripts may generate intermediate tensors that are not allocated by the Redis allocator, but by whatever allocator is used in the backends (which may act on main memory or GPU memory, depending on the device), thus not being limited by `maxmemory` configuration settings of Redis. |
| 626 | + |
517 | 627 | ## AI.SCRIPTRUN |
| 628 | +_This command is deprecated and will not be available in future versions. consider using AI.MODELEXECUTE command instead._ |
| 629 | + |
518 | 630 | The **`AI.SCRIPTRUN`** command runs a script stored as a key's value on its specified device. It accepts one or more input tensors and store output tensors. |
519 | 631 |
|
520 | 632 | The run request is put in a queue and is executed asynchronously by a worker thread. The client that had issued the run request is blocked until the script run is completed. When needed, tensors data is automatically copied to the device prior to execution. |
|
0 commit comments