Skip to content

Commit 8b53bef

Browse files
authored
Merge branch 'master' into patch-1
2 parents e03d1df + dce636b commit 8b53bef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1595
-1110
lines changed

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ WORKDIR /build
2929
COPY --from=redis /usr/local/ /usr/local/
3030

3131
COPY ./opt/ opt/
32-
COPY ./tests/flow/test_requirements.txt tests/flow/
32+
ADD ./tests/flow/ tests/flow/
3333

3434
RUN FORCE=1 ./opt/readies/bin/getpy3
3535
RUN ./opt/system-setup.py
@@ -67,7 +67,7 @@ ARG REDIS_VER
6767
ARG PACK
6868

6969
RUN if [ ! -z $(command -v apt-get) ]; then apt-get -qq update; apt-get -q install -y libgomp1; fi
70-
RUN if [ ! -z $(command -v yum) ]; then yum install -y libgomp; fi
70+
RUN if [ ! -z $(command -v yum) ]; then yum install -y libgomp; fi
7171

7272
ENV REDIS_MODULES /usr/lib/redis/modules
7373
ENV LD_LIBRARY_PATH $REDIS_MODULES

Dockerfile.arm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ WORKDIR /build
3131
COPY --from=redis /usr/local/ /usr/local/
3232

3333
COPY ./opt/ opt/
34-
COPY ./tests/flow/test_requirements.txt tests/flow
34+
COPY ./tests/flow/tests_setup/test_requirements.txt tests/flow
3535

3636
RUN ./opt/readies/bin/getpy3
3737
RUN ./opt/system-setup.py

Dockerfile.gpu

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ ARG TEST=0
1818

1919
#----------------------------------------------------------------------------------------------
2020
FROM redisfab/redis:${REDIS_VER}-${ARCH}-${OSNICK} AS redis
21-
FROM nvidia/cuda:10.2-cudnn8-devel-${OS} AS cuda_10.2
2221
FROM nvidia/cuda:${CUDA_VER}-devel-${OS} AS builder
2322

2423
ARG OSNICK
@@ -35,13 +34,10 @@ ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
3534
WORKDIR /build
3635
COPY --from=redis /usr/local/ /usr/local/
3736

38-
COPY --from=cuda_10.2 /usr/local/cuda-10.2 /usr/local/cuda-10.2
39-
COPY --from=cuda_10.2 /usr/lib/x86_64-linux-gnu/libcu* /usr/lib/x86_64-linux-gnu/
40-
41-
RUN echo export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda-11.0/lib64:/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH > /etc/profile.d/cuda.sh
37+
RUN echo export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda-11.0/lib64:$LD_LIBRARY_PATH > /etc/profile.d/cuda.sh
4238

4339
COPY ./opt/ opt/
44-
COPY ./tests/flow/test_requirements.txt tests/flow/
40+
ADD ./tests/flow/ tests/flow/
4541

4642
RUN FORCE=1 ./opt/readies/bin/getpy3
4743
RUN ./opt/system-setup.py
@@ -75,13 +71,12 @@ FROM nvidia/cuda:${CUDA_VER}-runtime-${OS}
7571
ARG OS
7672

7773
RUN if [ ! -z $(command -v apt-get) ]; then apt-get -qq update; apt-get -q install -y libgomp1; fi
78-
RUN if [ ! -z $(command -v yum) ]; then yum install -y libgomp; fi
74+
RUN if [ ! -z $(command -v yum) ]; then yum install -y libgomp; fi
7975

8076
ENV REDIS_MODULES /usr/lib/redis/modules
8177
RUN mkdir -p $REDIS_MODULES/
8278

8379
COPY --from=redis /usr/local/ /usr/local/
84-
COPY --from=builder /usr/local/cuda-10.2 /usr/local/cuda-10.2
8580
COPY --from=builder /usr/lib/x86_64-linux-gnu/libcu* /usr/lib/x86_64-linux-gnu/
8681
COPY --from=builder /build/install-gpu/ $REDIS_MODULES/
8782

Dockerfile.gpu-test

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ ARG PACK=1
1717

1818
#----------------------------------------------------------------------------------------------
1919
FROM redisfab/redis:${REDIS_VER}-${ARCH}-${OSNICK} AS redis
20-
FROM nvidia/cuda:10.2-cudnn8-devel-${OS} AS cuda_10.2
2120
FROM nvidia/cuda:${CUDA_VER}-devel-${OS} AS builder
2221

2322
SHELL ["/bin/bash", "-c"]
@@ -28,14 +27,11 @@ ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
2827
WORKDIR /build
2928
COPY --from=redis /usr/local/ /usr/local/
3029

31-
COPY --from=cuda_10.2 /usr/local/cuda-10.2 /usr/local/cuda-10.2
32-
COPY --from=cuda_10.2 /usr/lib/x86_64-linux-gnu/libcu* /usr/lib/x86_64-linux-gnu/
33-
34-
RUN echo export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda-11.0/lib64:/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH > /etc/profile.d/cuda.sh
30+
RUN echo export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda-11.0/lib64:$LD_LIBRARY_PATH > /etc/profile.d/cuda.sh
3531

3632
COPY ./opt/ opt/
37-
COPY ./tests/flow/test_requirements.txt tests/flow/
38-
COPY ./tests/flow/Install_RedisGears.sh tests/flow/
33+
COPY ./tests/flow/tests_setup/test_requirements.txt tests/flow/tests_setup/
34+
COPY ./tests/flow/tests_setup/Install_RedisGears.sh tests/flow/tests_setup/
3935

4036
RUN VENV=venv FORCE=1 ./opt/readies/bin/getpy3
4137

Dockerfile.jetson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ WORKDIR /build
3838
COPY --from=redis /usr/local/ /usr/local/
3939

4040
COPY ./opt/ opt/
41-
COPY ./tests/flow/test_requirements.txt tests/flow/
41+
COPY ./tests/flow/tests_setup/test_requirements.txt tests/flow/
4242

4343
RUN FORCE=1 ./opt/readies/bin/getpy3
4444
RUN ./opt/system-setup.py

docs/commands.md

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ OK
337337

338338
## AI.MODELRUN
339339

340-
_This command is deprecated and will not be available in future versions. consider using AI.MODELEXECUTE command instead._
340+
_This command is deprecated and will not be available in future versions. consider using `AI.MODELEXECUTE` command instead._
341341

342342
The **`AI.MODELRUN`** command runs a model stored as a key's value using its specified backend and device. It accepts one or more input tensors and store output tensors.
343343

@@ -730,7 +730,110 @@ redis> > AI._SCRIPTSCAN
730730
2) "myscript:v0.1"
731731
```
732732

733+
## AI.DAGEXECUTE
734+
The **`AI.DAGEXECUTE`** command specifies a direct acyclic graph of operations to run within RedisAI.
735+
736+
It accepts one or more operations, split by the pipe-forward operator (`|>`).
737+
738+
By default, the DAG execution context is local, meaning that tensor keys appearing in the DAG only live in the scope of the command. That is, setting a tensor with `TENSORSET` will store it local memory and not set it to an actual database key. One can refer to that key in subsequent commands within the DAG, but that key won't be visible outside the DAG or to other clients - no keys are open at the database level.
739+
740+
Loading and persisting tensors from/to keyspace should be done explicitly. The user should specify which key tensors to load from keyspace using the `LOAD` keyword, and which command outputs to persist to the keyspace using the `PERSIST` keyspace. The user can also specify keys in Redis that are going to be accessed for read/write operations (for example, from within `AI.SCRIPTEXECUTE` command), by using the keyword `KEYS`.
741+
742+
As an example, if `command 1` sets a tensor, it can be referenced by any further command on the chaining.
743+
744+
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). Note that individual `MODELEXECUTE` or `SCRIPTEXECUTE` commands within the DAG do not support `TIMEOUT`. `TIMEOUT` only applies to the `DAGEXECUTE` request as a whole.
745+
746+
747+
**Redis API**
748+
749+
```
750+
AI.DAGEXECUTE [[LOAD <n> <key-1> <key-2> ... <key-n>] |
751+
[PERSIST <n> <key-1> <key-2> ... <key-n>] |
752+
[KEYS <n> <key-1> <key-2> ... <key-n>]]+
753+
[TIMEOUT t]
754+
|> <command> [|> command ...]
755+
```
756+
757+
_Arguments_
758+
759+
* **LOAD**: denotes the beginning of the input tensors keys' list, followed by the number of keys, and one or more key names
760+
* **PERSIST**: denotes the beginning of the output tensors keys' list, followed by the number of keys, and one or more key names
761+
* **KEYS**: denotes the beginning of keys' list which are used within this command, followed by the number of keys, and one or more key names. Alternately, the keys names list can be replaced with a tag which all of those keys share. Redis will verify that all potential key accesses are done to the right shard.
762+
763+
_While each of the LOAD, PERSIST and KEYS sections are optional (and may appear at most once in the command), the command must contain **at least one** of these 3 keywords._
764+
* **TIMEOUT**: an optional argument, denotes the time (in ms) after which the client is unblocked and a `TIMEDOUT` string is returned
765+
* **|> command**: the chaining operator, that denotes the beginning of a RedisAI command, followed by one of RedisAI's commands. Command splitting is done by the presence of another `|>`. The supported commands are:
766+
* `AI.TENSORSET`
767+
* `AI.TENSORGET`
768+
* `AI.MODELEXECUTE`
769+
* `AI.SCRIPTEXECUTE`
770+
771+
772+
`AI.MODELEXECUTE` and `AI.SCRIPTEXECUTE` commands can run on models or scripts that were set on different devices. RedisAI will analyze the DAG and execute commands in parallel if they are located on different devices and their inputs are available.
773+
Note that KEYS should not be specified in `AI.SCRIPTEXECUTE` commands of the DAG.
774+
775+
_Return_
776+
777+
An array with an entry per command's reply. Each entry format respects the specified command reply.
778+
In case the `DAGEXEUTE` request times out, a `TIMEDOUT` simple string is returned.
779+
780+
**Examples**
781+
782+
Assuming that running the model that's stored at 'mymodel', we define a temporary tensor 'mytensor' and use it as input, and persist only one of the two outputs - discarding 'classes' and persisting 'predictions'. In the same command return the tensor value of 'predictions'. The following command does that:
783+
784+
785+
```
786+
redis> AI.DAGEXECUTE PERSIST 1 predictions{tag} |>
787+
AI.TENSORSET mytensor FLOAT 1 2 VALUES 5 10 |>
788+
AI.MODELEXECUTE mymodel{tag} INPUTS 1 mytensor OUTPUTS 2 classes predictions{tag} |>
789+
AI.TENSORGET predictions{tag} VALUES
790+
1) OK
791+
2) OK
792+
3) 1) FLOAT
793+
2) 1) (integer) 2
794+
2) (integer) 2
795+
3) "\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@"
796+
```
797+
798+
A common pattern is enqueuing multiple SCRIPTEXECUTE and MODELEXECUTE commands within a DAG. The following example uses ResNet-50,to classify images into 1000 object categories. Given that our input tensor contains each color represented as a 8-bit integer and that neural networks usually work with floating-point tensors as their input we need to cast a tensor to floating-point and normalize the values of the pixels - for that we will use `pre_process_3ch` function.
799+
800+
To optimize the classification process we can use a post process script to return only the category position with the maximum classification - for that we will use `post_process` script. Using the DAG capabilities we've removed the necessity of storing the intermediate tensors in the keyspace. You can even run the entire process without storing the output tensor, as follows:
801+
802+
```
803+
redis> AI.DAGEXECUTE KEYS 1 {tag} |>
804+
AI.TENSORSET image UINT8 224 224 3 BLOB b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00....' |>
805+
AI.SCRIPTEXECUTE imagenet_script{tag} pre_process_3ch INPUTS 1 image OUTPUTS 1 temp_key1 |>
806+
AI.MODELEXECUTE imagenet_model{tag} INPUTS 1 temp_key1 OUTPUTS 1 temp_key2 |>
807+
AI.SCRIPTEXECUTE imagenet_script{tag} post_process INPUTS 1 temp_key2 OUTPUTS 1 output |>
808+
AI.TENSORGET output VALUES
809+
1) OK
810+
2) OK
811+
3) OK
812+
4) OK
813+
5) 1) 1) (integer) 111
814+
```
815+
816+
As visible on the array reply, the label position with higher classification was 111.
817+
818+
By combining DAG with multiple SCRIPTEXECUTE and MODELEXECUTE commands we've substantially removed the overall required bandwith and network RX ( we're now returning a tensor with 1000 times less elements per classification ).
819+
820+
821+
822+
!!! warning "Intermediate memory overhead"
823+
The execution of models and scripts within the DAG 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.
824+
825+
## AI.DAGEXECUTE_RO
826+
827+
The **`AI.DAGEXEUTE_RO`** command is a read-only variant of `AI.DAGEXECUTE`.
828+
`AI.DAGEXECUTE` is flagged as a 'write' command in the Redis command table (as it provides the `PERSIST` option, for example). Hence, read-only cluster replicas will refuse to run the command and it will be redirected to the master even if the connection is using read-only mode.
829+
830+
`AI.DAGEXECUTE_RO` behaves exactly like the original command, excluding the `PERSIST` option and `AI.SCRIPTEXECUTE` commands. It is a read-only command that can safely be with read-only replicas.
831+
832+
!!! info "Further reference"
833+
Refer to the Redis [`READONLY` command](https://redis.io/commands/readonly) for further information about read-only cluster replicas.
834+
733835
## AI.DAGRUN
836+
_This command is deprecated and will not be available in future versions. consider using `AI.DAGEXECUTE` command instead._
734837
The **`AI.DAGRUN`** command specifies a direct acyclic graph of operations to run within RedisAI.
735838

736839
It accepts one or more operations, split by the pipe-forward operator (`|>`).
@@ -817,7 +920,7 @@ By combining DAG with multiple SCRIPTRUN and MODELRUN commands we've substantial
817920
The execution of models and scripts within the DAG 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.
818921

819922
## AI.DAGRUN_RO
820-
923+
_This command is deprecated and will not be available in future versions. consider using `AI.DAGEXECUTE_RO` command instead._
821924
The **`AI.DAGRUN_RO`** command is a read-only variant of `AI.DAGRUN`.
822925

823926
Because `AI.DAGRUN` provides the `PERSIST` option it is flagged as a 'write' command in the Redis command table. However, even when `PERSIST` isn't used, read-only cluster replicas will refuse to run the command and it will be redirected to the master even if the connection is using read-only mode.

docs/developer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ To run all tests in a Python virtualenv, follow these steps:
121121
$ mkdir -p .env
122122
$ virtualenv .env
123123
$ source .env/bin/activate
124-
$ pip install -r tests/flow/test_requirements.txt
124+
$ pip install -r tests/flow/tests_setup/test_requirements.txt
125125
$ make -C opt test
126126

127127
**Integration tests**

opt/Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ MODULE=$(realpath $(INSTALLED_TARGET)) \
248248
CLUSTER=$(CLUSTER) \
249249
GEN=$(GEN) AOF=$(AOF) SLAVES=$(SLAVES) \
250250
VALGRIND=$(VALGRIND) \
251-
$(ROOT)/tests/flow/tests.sh
251+
$(ROOT)/tests/flow/tests_setup/tests.sh
252252
endef
253253

254254
unit_tests: build
@@ -265,7 +265,7 @@ flow_tests: build
265265
GEN=$(GEN) AOF=$(AOF) SLAVES=$(SLAVES) \
266266
VALGRIND=$(VALGRIND) \
267267
REDIS=$(REDIS) \
268-
$(ROOT)/tests/flow/tests.sh
268+
$(ROOT)/tests/flow/tests_setup/tests.sh
269269

270270
$(COVERAGE_COLLECT_REPORT)
271271

@@ -283,16 +283,16 @@ test: build
283283
GEN=$(GEN) AOF=$(AOF) SLAVES=$(SLAVES) \
284284
VALGRIND=$(VALGRIND) \
285285
REDIS=$(REDIS) \
286-
$(ROOT)/tests/flow/tests.sh
286+
$(ROOT)/tests/flow/tests_setup/tests.sh
287287
$(COVERAGE_COLLECT_REPORT)
288288

289289
#----------------------------------------------------------------------------------------------
290290

291291
valgrind:
292-
$(SHOW)$(ROOT)/tests/flow/valgrind.sh $(realpath $(INSTALLED_TARGET))
292+
$(SHOW)$(ROOT)/tests/flow/tests_setup/valgrind.sh $(realpath $(INSTALLED_TARGET))
293293

294294
callgrind:
295-
$(SHOW)CALLGRIND=1 $(ROOT)/tests/flow/valgrind.sh $(realpath $(INSTALLED_TARGET))
295+
$(SHOW)CALLGRIND=1 $(ROOT)/tests/flow/tests_setup/valgrind.sh $(realpath $(INSTALLED_TARGET))
296296

297297
#----------------------------------------------------------------------------------------------
298298

opt/pack.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ BINDIR=$(realpath $BINDIR)
5151
INSTALL_DIR=$(realpath $INSTALL_DIR)
5252

5353
$READIES/enable-utf8
54-
source /etc/profile.d/utf8.sh
54+
if [ -f /etc/profile.d/utf8.sh ]; then
55+
source /etc/profile.d/utf8.sh
56+
else
57+
echo export LC_ALL=C.UTF-8 >> /etc/profile.d/utf8.sh
58+
echo export LANG=C.UTF-8 >> /etc/profile.d/utf8.sh
59+
source /etc/profile.d/utf8.sh
60+
fi
5561

5662
export ARCH=$($READIES/platform --arch)
5763
export OS=$($READIES/platform --os)

opt/readies

0 commit comments

Comments
 (0)