From aae343a39fc9412ed78c66241f45926c3e02bc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= <berykubik@gmail.com> Date: Fri, 5 Mar 2021 10:45:48 +0100 Subject: [PATCH] Add Dask documentation --- .spelling | 2 + docs.it4i/software/data-science/dask.md | 280 ++++++ .../software/data-science/imgs/dask-arch.svg | 920 ++++++++++++++++++ .../debuggers/intel-vtune-amplifier.md | 2 +- mkdocs.yml | 2 + 5 files changed, 1205 insertions(+), 1 deletion(-) create mode 100644 docs.it4i/software/data-science/dask.md create mode 100644 docs.it4i/software/data-science/imgs/dask-arch.svg diff --git a/.spelling b/.spelling index 4af97d892..60cb19a94 100644 --- a/.spelling +++ b/.spelling @@ -804,3 +804,5 @@ npm - node_modules/spawn-sync/README.md iojs >>>>>>> readme +UCX +Dask-ssh diff --git a/docs.it4i/software/data-science/dask.md b/docs.it4i/software/data-science/dask.md new file mode 100644 index 000000000..01fb64099 --- /dev/null +++ b/docs.it4i/software/data-science/dask.md @@ -0,0 +1,280 @@ +# Dask + +[Dask](https://docs.dask.org/en/latest/) is a popular open-source library that allows you to +parallelize your Python code using a distributed cluster easily. It can parallelize arbitrary +Python code in the form of a task DAG (Directed Acyclic Graph), but it also offers parallelized +versions of popular Python data science libraries like +[numpy](https://docs.dask.org/en/latest/array.html) or +[Pandas](https://docs.dask.org/en/latest/dataframe.html). + +## Installation + +To install Dask, load a recent version of Python 3 and install Dask using `pip`. We heavily +recommend you to install Python packages inside a Python virtual environment. + +```bash +# Load Python (preferably use a specific Python version) +$ ml Python3 + +# Create a virtual environment +$ python3 -m venv dask + +# Activate and update the virtual environment +$ source dask/bin/activate +(dask) $ pip install -U setuptools pip wheel + +# Install Dask +(dask) $ pip install distributed +``` + +## Starting a Dask Cluster + +Before you can use Dask, you need to set up a Dask cluster, which consists of a single server +component which coordinates the cluster, and an arbitrary number of workers, which actually +execute your tasks. + + + +After you start a PBS job, you should therefore first start the server and the workers on the +available computing nodes and then run your Python program that uses Dask. There are multiple ways +of deploying the cluster. A common scenario is to run a Dask server on a single computing node, +run a single worker per node on all remaining computing nodes and then run your program on the node +with the server. + +> There are some performance considerations to be taken into account regarding Dask cluster +> deployment, see [below](#dask-performance-considerations) for more information. + +!!! note + All the following deployment methods assume that you are inside a Python environment that has + Dask installed. Do not forget to load Python and activate the correct virtual environment at + the beginning of your PBS job! And also do the same after connecting to any worker nodes + manually using SSH. + +### Manual Deployment + +Both the server and the worker nodes can be started using a CLI command. If you prefer manual +deployment, you can manually start the server on a selected node and then start the workers on +other nodes available inside your PBS job. + +```bash +# Start the server on some node N +$ dask-scheduler + +# Start a single worker on some other node, pass it the address of the server +$ dask-worker tcp://<hostname-of-N>:8786 +``` + +### Dask-ssh Deployment + +Dask actually contains [built-in support](https://docs.dask.org/en/latest/setup/ssh.html) for +automating Dask deployment using SSH. It also supports nodefiles provided by PBS, so inside of your +PBS job, you can simply run + +```bash +$ dask-ssh --hostfile $PBS_NODEFILE +``` + +to start the Dask cluster on all available computing nodes. This will start the server on the first +node of your PBS job and then a single worker on each node. The first node will therefore be shared +by a server and a worker, which might not be ideal from a performance point of view. + +> Note that for this to work, the `paramiko` Python library has to be installed inside your Python +> environment (you can install it using `$ pip install paramiko`). + +You can also start the Cluster directly from your +[Python script](https://docs.dask.org/en/latest/setup/ssh.html#python-interface). In this way you +can start the scheduler and the workers on separate nodes to avoid overcrowding the server node. + +### Other Deployment Options + +Dask has a lot of other ways of being deployed, e.g. using MPI, or using a shared file on the +network file system. It also allows you to create a PBS job directly, wait for it to be started and +then it starts the whole cluster inside the PBS job. You can find more information about Dask HPC +deployment [here](https://docs.dask.org/en/latest/setup/hpc.html). + +## Connecting to the Cluster + +Once you have deployed your cluster, you must create a `Client` at the beginning of your program +and pass it the address of the server. + +```python +from distributed import Client + +client = Client("<hostname-of-server>:8786") +``` + +Once the client connects to the server successfully, all subsequent Dask computations will be +parallelized using the cluster. + +Below are some examples of computations that you can perform with Dask. Note that the code should +only be executed after a client was connected to a server! + +### Parallelize Arbitrary Python Code Using `Delayed` + +The `delayed` function (or a decorator) turns a Python function into a lazy computation. If you +call such a function, it will not execute right away. It will only return a future object that can +be composed with other futures to build a DAG of tasks. After you describe your whole computation, +you can actually execute it using `dask.compute(<future>)`. + +```python +import dask + +@dask.delayed +def inc(x): + return x + 1 + +@dask.delayed +def double(x): + return x * 2 + +@dask.delayed +def add(x, y): + return x + y + +data = [1, 2, 3, 4, 5] + +output = [] +for x in data: + a = inc(x) + b = double(x) + c = add(a, b) + output.append(c) + +total = dask.delayed(sum)(output) + +# `total` is just a lazy computation +# To get the actual value, call dask.compute +result = dask.compute(total) +``` + +You can find more information about the `delayed` API +[here](https://docs.dask.org/en/latest/delayed.html). + +### Parallelize `Pandas` + +Dask contains a module called `dataframe` which mirrors the API of `pandas`, a popular library for +tabular analysis. Using `dataframe` you can distribute your `pandas` code to multiple nodes easily. +You can find more information about it [here](https://docs.dask.org/en/latest/dataframe.html). + +Here is an example of its usage: + +```python +import dask.dataframe as pd + +# Load CSV +df = pd.read_csv("table.csv") + +# Describe a lazy computation (this is not computed yet) +df2 = df[df.y == "a"].x + 1 + +# Actually compute the table operations on worker nodes +result = df2.compute() +``` + +### Parallelize `Numpy` + +Dask contains a module called `array` which mirrors the API of `numpy`, a popular library for +n-dimensional array computations. Using `array` you can distribute your `numpy` code to multiple +nodes easily. You can find more information about it +[here](https://examples.dask.org/array.html). + +Here is an example of its usage: + +```python +import dask.array as np +x = np.random.random((10000, 10000), chunks=(1000, 1000)) + +# Describe a lazy computation (this is not computed yet) +y = x + x.T +z = y[::2, 5000:].mean(axis=1) + +# Actually compute the arary operations on worker nodes +result = z.compute() +``` + +## Dask Performance Considerations + +Dask should be fast enough by default for most use cases, but there are some considerations that +should be taken into account. + +### Selecting the Number of Processes and Threads Per Worker + +When starting a Dask worker on a node, it will by default use a number of threads equal to the +number of cores on the given machine. At the same time, (C)Python uses a global lock +([GIL](https://realpython.com/python-gil/)) that prevents more than a single thread to execute at +once. This is fine if your computational tasks are I/O bound or if they spend most of their time +inside C libraries that release the GIL. + +However, if your tasks executed with Dask are heavily compute-bound, and they hold the GIL (e.g. +the heavy computation is performed directly inside Python), you might not be able to fully harness +all cores of the worker node. + +To solve this, you can run multiple workers (each with a reduced number of threads) per node. This +is a trade-off. With more workers on a node, you will be able to utilize more cores (assuming +your tasks are compute-bound). However, you will also increase the pressure on the central server +and on the network, because there will be more workers that will communicate with each other and +with the server. + +You can choose the number of workers and threads per each worker using the `--nprocs` and +`--nthreads` parameters of `dask-worker` (there are similar arguments when using other deployment +methods). + +Some examples (assuming a node with 24 cores): + +```bash +# Run a single worker using 24 threads. Reduces network and server traffic, but may not utilize all cores. +$ dask-worker --nprocs 1 --nthreads 24 + +# Run 24 workers, each with a single thread. Maximizes core usage, but may overload server or network. +$ dask-worker --nprocs 24 --nthreads 1 + +# Run 6 workers, each with 4 threads. Strikes a balance between core usage and network/server pressure. +$ dask-worker --nprocs 6 --nthreads 4 +``` + +From our experiments, we found that often it is best to run a single worker per each core of a +node to achieve the best performance. With this configuration, we found that Dask scales reasonably +up to 200 workers (e.g. <10 Barbora nodes). If you start to run into performance problems because +of the amount of workers, try to use [RSDS](#rsds) to achieve better scaling. + +### Memory Considerations + +A common reason to use Dask is that your computation does not fit inside the memory of a single +node. Dask can alleviate this, but you still have to be careful about your memory usage. For +example, when you use the `dataframe` or `array` API, you should pay attention into how many +partitions (or chunks) is your data split it. If you use a single partition, it will probably take +a lot of memory, and it will not offer many possibilities for parallelization. You can find more +information [here](https://docs.dask.org/en/latest/dataframe-design.html#partitions). + +By default, multiple workers on a node will split the available memory. Therefore, if the node +has 100 GiB of RAM and you start the Dask worker on a single node like this: + +```bash +$ dask-worker --nprocs 10 +``` + +Each worker will have around 10 GiB memory available. You can set the memory requirements of each +worker manually using the `--memory-limit` argument. + +If your program is strictly memory-bound, you can also try alternative approaches to Dask. +As an example, [Vaex](https://github.com/vaexio/vaex) is a library that allows you to easily +process dataframes that do not fit inside your operating memory. + +### UCX + +In some cases (especially with many workers), the network can be a bottleneck. By default, Dask +uses TCP/IP for communication, but it also has support for UCX, which enables more efficient usage +of the available InfiniBand interfaces. It is a bit cumbersome to set up, but if you want to try, +check [this tutorial](https://ucx-py.readthedocs.io/en/latest/dask.html). + +### Nvidia + +Dask has built-in support for GPU workers. You can find more information about this use case +[here](https://docs.dask.org/en/latest/gpu.html). + +### RSDS + +If you need to run a large amount of tasks and Dask does not perform well enough, you can try to +use [RSDS](https://github.com/It4innovations/rsds). It is our version of Dask which is optimized +for HPC use cases, and it should provide better scaling than Dask. You can read more about RSDS +in this [article](https://arxiv.org/abs/2010.11105). diff --git a/docs.it4i/software/data-science/imgs/dask-arch.svg b/docs.it4i/software/data-science/imgs/dask-arch.svg new file mode 100644 index 000000000..dc8e36cc1 --- /dev/null +++ b/docs.it4i/software/data-science/imgs/dask-arch.svg @@ -0,0 +1,920 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:export-ydpi="96" + inkscape:export-xdpi="96" + inkscape:export-filename="/home/spirali/tmp/arch.png" + sodipodi:docname="arch1.svg" + inkscape:version="1.0.2 (1.0.2+r75+1)" + id="svg8" + version="1.1" + viewBox="0 0 234.37095 116.09758" + height="116.09756mm" + width="234.37096mm"> + <defs + id="defs2"> + <marker + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0" + refX="0" + id="marker8919" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path8917" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow2Lstart" + orient="auto" + refY="0" + refX="0" + id="marker8909" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path8907" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(1.1,0,0,1.1,1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker8197" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path8195" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker8187" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path8185" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker7243" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path7241" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker7233" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path7231" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5579" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path5577" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5569" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path5567" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5221" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path5219" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5211" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path5209" /> + </marker> + <marker + inkscape:collect="always" + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0" + refX="0" + id="marker4895" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4893" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:collect="always" + inkscape:stockid="Arrow2Lstart" + orient="auto" + refY="0" + refX="0" + id="marker4885" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4883" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(1.1,0,0,1.1,1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker4505" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path4503" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker4495" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path4493" /> + </marker> + <marker + inkscape:collect="always" + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0" + refX="0" + id="marker4375" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4373" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:collect="always" + inkscape:stockid="Arrow2Lstart" + orient="auto" + refY="0" + refX="0" + id="marker4365" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4363" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(1.1,0,0,1.1,1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:collect="always" + inkscape:isstock="true" + style="overflow:visible" + id="marker3649" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path3647" /> + </marker> + <marker + inkscape:collect="always" + inkscape:isstock="true" + style="overflow:visible" + id="marker3639" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path3637" /> + </marker> + <marker + inkscape:collect="always" + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0" + refX="0" + id="marker3323" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path3321" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:collect="always" + inkscape:stockid="Arrow2Lstart" + orient="auto" + refY="0" + refX="0" + id="marker3313" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path3311" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(1.1,0,0,1.1,1.1,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker1869" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1867" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker1859" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1857" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:collect="always" + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow1Lend" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-0.8,0,0,-0.8,-10,0)" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path1449" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker1709" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Lstart"> + <path + inkscape:connector-curvature="0" + transform="matrix(0.8,0,0,0.8,10,0)" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path1446" /> + </marker> + <marker + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0" + refX="0" + id="marker5201" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path5199" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0" + refX="0" + id="marker4135" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4133" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="matrix(0.8,0,0,0.8,10,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker3541" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path3539" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0" + refX="0" + id="marker3471" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path3469" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="matrix(0.8,0,0,0.8,10,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0" + refX="0" + id="marker2271" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path2269" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="matrix(0.8,0,0,0.8,10,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker2153" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path2151" /> + </marker> + <marker + inkscape:collect="always" + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lend" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend"> + <path + inkscape:connector-curvature="0" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path880" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart-9" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464-3" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart-9-7" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464-3-8" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart-9-7-3" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464-3-8-6" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart-9-7-3-3" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464-3-8-6-2" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart-9-7-5" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464-3-8-5" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow2Lstart-9-7-3-6" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lstart"> + <path + transform="matrix(1.1,0,0,1.1,1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + id="path1464-3-8-6-9" + inkscape:connector-curvature="0" /> + </marker> + </defs> + <sodipodi:namedview + inkscape:document-rotation="0" + fit-margin-bottom="2" + fit-margin-right="10" + fit-margin-left="10" + fit-margin-top="2" + inkscape:window-maximized="1" + inkscape:window-y="32" + inkscape:window-x="0" + inkscape:window-height="1131" + inkscape:window-width="1600" + showgrid="false" + inkscape:current-layer="layer1" + inkscape:document-units="mm" + inkscape:cy="346.18045" + inkscape:cx="145.60755" + inkscape:zoom="0.70710678" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + transform="translate(-49.357762,-18.315286)" + id="layer1" + inkscape:groupmode="layer" + inkscape:label="Layer 1"> + <g + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="rotate(-90,98.055536,42.96916)" + id="g1036"> + <rect + rx="4.5357141" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + id="rect815" + width="34.773808" + height="24.568455" + x="4.7662115" + y="-109.93287" + ry="4.5357141" + transform="rotate(90)" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + x="11.947762" + y="-94.813812" + id="text819" + transform="rotate(90)"><tspan + sodipodi:role="line" + id="tspan817" + x="11.947762" + y="-94.813812" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1">Client</tspan></text> + </g> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path857" + d="M 136.8065,43.376049 H 95.424473" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2Lstart);marker-end:url(#Arrow2Lend)" /> + <g + transform="rotate(-90,106.55797,34.466718)" + id="g1041"> + <text + id="text843" + y="-95.569778" + x="73.935844" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="rotate(90)"><tspan + style="stroke-width:0.264583px" + y="-95.569778" + x="73.935844" + id="tspan841" + sodipodi:role="line">Server</tspan></text> + <rect + rx="4.5357141" + ry="4.5357141" + y="-109.93287" + x="65.620377" + height="24.568459" + width="37.797623" + id="rect920" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + transform="rotate(90)" /> + </g> + <g + id="g3273" + transform="rotate(-90,143.24932,0.81892398)"> + <text + transform="rotate(90)" + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="75.80127" + y="-98.484352" + id="text3269"><tspan + sodipodi:role="line" + id="tspan3267" + x="75.80127" + y="-98.484352" + style="stroke-width:0.264583px">Worker</tspan></text> + <rect + transform="rotate(90)" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.00000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + id="rect3271" + width="43.929955" + height="17.480896" + x="65.620377" + y="-109.93287" + ry="4.5357141" + rx="4.5357141" /> + <text + id="text3277" + y="-76.44973" + x="75.80127" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="rotate(90)"><tspan + style="stroke-width:0.264583px" + y="-76.44973" + x="75.80127" + id="tspan3275" + sodipodi:role="line">Worker</tspan></text> + <rect + rx="4.5357141" + ry="4.5357141" + y="-87.898247" + x="65.620377" + height="17.480896" + width="43.929955" + id="rect3279" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.00000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + transform="rotate(90)" /> + <rect + rx="0" + ry="0" + y="-113.58769" + x="57.881962" + height="46.451172" + width="62.246155" + id="rect3295" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.16103995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + transform="rotate(90)" /> + </g> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker3313);marker-end:url(#marker3323)" + d="M 207.3022,43.376049 175.69463,39.148507" + id="path3309" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <g + transform="rotate(-90,169.26264,26.83224)" + id="g3621"> + <text + id="text3609" + y="-98.484352" + x="75.80127" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="rotate(90)"><tspan + style="stroke-width:0.264583px" + y="-98.484352" + x="75.80127" + id="tspan3607" + sodipodi:role="line">Worker</tspan></text> + <rect + rx="4.5357141" + ry="4.5357141" + y="-109.93287" + x="65.620377" + height="17.480896" + width="43.929955" + id="rect3611" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.00000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + transform="rotate(90)" /> + <text + transform="rotate(90)" + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="75.80127" + y="-76.44973" + id="text3615"><tspan + sodipodi:role="line" + id="tspan3613" + x="75.80127" + y="-76.44973" + style="stroke-width:0.264583px">Worker</tspan></text> + <rect + transform="rotate(90)" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.00000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + id="rect3617" + width="43.929955" + height="17.480896" + x="65.620377" + y="-87.898247" + ry="4.5357141" + rx="4.5357141" /> + <rect + transform="rotate(90)" + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.16103995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" + id="rect3619" + width="62.246155" + height="46.451172" + x="57.881962" + y="-113.58769" + ry="0" + rx="0" /> + </g> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path3635" + d="M 207.3022,65.549829 175.69463,42.960123" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker3639);marker-end:url(#marker3649)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4365);marker-end:url(#marker4375)" + d="M 207.3022,94.825981 175.69463,47.511548" + id="path3901" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path4491" + d="M 207.3022,117.1646 175.69463,53.755312" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4495);marker-end:url(#marker4505)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4885);marker-end:url(#marker4895)" + d="m 253.55589,65.568192 c 18.19456,-0.990507 34.05618,-18.885798 -0.55595,-23.043826" + id="path4881" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path5565" + d="M 253.55589,117.68378 C 264.33601,106.90366 275.1499,91.650086 252.99994,69.500126" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker5569);marker-end:url(#marker5579)" /> + <g + id="g5961" + transform="rotate(-90,127.91362,60.358087)"> + <text + transform="rotate(90)" + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="133.41148" + y="-162.54834" + id="text5957"><tspan + sodipodi:role="line" + id="tspan5955" + x="133.41148" + y="-162.54834" + style="stroke-width:0.264583px">Computing Node</tspan></text> + </g> + <g + id="g5969" + transform="rotate(-90,104.10113,112.75608)"> + <text + transform="rotate(90)" + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="73.935844" + y="-95.569778" + id="text5965" /> + </g> + <text + id="text5981" + y="133.43214" + x="65.54464" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.40833px;line-height:125%;font-family:Raleway-v4020;-inkscape-font-specification:Raleway-v4020;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.35px;line-height:1.25;font-family:Raleway;-inkscape-font-specification:'Raleway, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:lining-nums;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="105.69199" + y="41.064568" + id="text1510"><tspan + sodipodi:role="line" + id="tspan1508" + x="105.69199" + y="41.064568" + style="font-size:6.35px;stroke-width:0.264583">TCP/IP</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.35px;line-height:1.25;font-family:Raleway;-inkscape-font-specification:'Raleway, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:lining-nums;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="176.5417" + y="36.430691" + id="text1510-5"><tspan + sodipodi:role="line" + id="tspan1508-0" + x="176.5417" + y="36.430691" + style="font-size:6.35px;stroke-width:0.264583">TCP/IP</tspan></text> + <image + width="50.874741" + height="50.874741" + preserveAspectRatio="none" + style="image-rendering:optimizeQuality" + xlink:href="data:image/png;base64,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 " + id="image12799" + x="51.80212" + y="19.917583" /> + </g> +</svg> diff --git a/docs.it4i/software/debuggers/intel-vtune-amplifier.md b/docs.it4i/software/debuggers/intel-vtune-amplifier.md index a60815c6d..e1322d330 100644 --- a/docs.it4i/software/debuggers/intel-vtune-amplifier.md +++ b/docs.it4i/software/debuggers/intel-vtune-amplifier.md @@ -11,7 +11,7 @@ Intel*®* VTune™ Amplifier, part of Intel Parallel studio, is a GUI profiling  -## Installed Versions +## Installed Versions For the current list of installed versions, use: diff --git a/mkdocs.yml b/mkdocs.yml index 2ec8238d9..518e7ae7a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -125,6 +125,8 @@ nav: - Orca: software/chemistry/orca.md - Phono3py: software/chemistry/phono3py.md - Compilers: software/compilers.md + - Data Science: + - Dask: software/data-science/dask.md - Debuggers: - Introduction: software/debuggers/introduction.md - Aislinn: software/debuggers/aislinn.md -- GitLab