diff --git a/README.md b/README.md
index bb276cefa6..8fcd639473 100644
--- a/README.md
+++ b/README.md
@@ -29,24 +29,41 @@ For more information, see our [paper](http://www.arxiv.org/abs/1902.10345).
See an example SDFG [in the standalone viewer (SDFV)](https://spcl.github.io/dace/sdfv.html?url=https://spcl.github.io/dace/examples/gemm.sdfg).
-Tutorials
----------
+Quick Start
+-----------
+
+Install DaCe with pip: `pip install dace`
+
+Using DaCe in Python is as simple as adding a `@dace` decorator:
+```python
+import dace
+import numpy as np
+
+@dace
+def myprogram(a):
+ for i in range(a.shape[0]):
+ a[i] += i
+ return np.sum(a)
+```
+
+Calling `myprogram` with any NumPy array or `__{cuda_}array_interface__`-supporting tensor (e.g., PyTorch, Numba) will generate data-centric code, compile, and run it. From here on out, you can _optimize_ (interactively or automatically), _instrument_, and _distribute_ your code. The code creates a shared library (DLL/SO file) that can readily be used in any C ABI compatible language (C/C++, FORTRAN, etc.).
+
+For more information on how to use DaCe, see the [samples](samples) or tutorials below:
* [Getting Started](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/getting_started.ipynb)
+* [Benchmarks, Instrumentation, and Performance Comparison with Other Python Compilers](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/benchmarking.ipynb)
* [Explicit Dataflow in Python](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/explicit.ipynb)
* [NumPy API Reference](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/numpy_frontend.ipynb)
* [SDFG API](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/sdfg_api.ipynb)
* [Using and Creating Transformations](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/transformations.ipynb)
* [Extending the Code Generator](https://nbviewer.jupyter.org/github/spcl/dace/blob/master/tutorials/codegen.ipynb)
-Installation and Dependencies
------------------------------
-
-To install: `pip install dace`
+Dependencies
+------------
Runtime dependencies:
* A C++14-capable compiler (e.g., gcc 5.3+)
- * Python 3.6 or newer
+ * Python 3.7 or newer (Python 3.6 is supported but not actively tested)
* CMake 3.15 or newer
Running
diff --git a/tutorials/benchmarking.ipynb b/tutorials/benchmarking.ipynb
new file mode 100644
index 0000000000..4e7e048bca
--- /dev/null
+++ b/tutorials/benchmarking.ipynb
@@ -0,0 +1,1511 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "6d9dce90",
+ "metadata": {},
+ "source": [
+ "# Benchmarking\n",
+ "\n",
+ "In this tutorial we will compare DaCe with other popular Python-accelerating libraries. The NumPy results should be a bit faster if an optimized version is installed (for example, compiled with Intel MKL).\n",
+ "\n",
+ "Table of Contents:\n",
+ "* [Dependencies](#Dependencies)\n",
+ "* [Simple programs](#Simple-programs-with-multiple-operators)\n",
+ "* [Loops](#Loops)\n",
+ " * [Varying sizes](#Varying-sizes)\n",
+ "* [Auto-parallelization](#Auto-parallelization)\n",
+ "* [Example: 3D Heat Diffusion](#3D-Heat-Diffusion)\n",
+ "* [Benchmarking and Instrumentation API](#Benchmarking-and-Instrumentation-API)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d0a07e84",
+ "metadata": {},
+ "source": [
+ "TL;DR DaCe is fast:\n",
+ "\n",
+ "![performance](performance.png \"performance\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "93f7d90c",
+ "metadata": {},
+ "source": [
+ "## Dependencies\n",
+ "\n",
+ "First, let's make sure we have all the frameworks ready to go:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "dbb480ef",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "...\n"
+ ]
+ }
+ ],
+ "source": [
+ "%pip install jax jaxlib\n",
+ "%pip install numba\n",
+ "%pip install pythran\n",
+ "# Your library here"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "b2b10c42",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "...\n"
+ ]
+ }
+ ],
+ "source": [
+ "# MKL for performance\n",
+ "%conda install mkl mkl-include mkl-devel\n",
+ "\n",
+ "# matplotlib to draw the results\n",
+ "%pip install matplotlib"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "927781f2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Setup code for plotting\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "def barplot(title, labels=False):\n",
+ " x = ['numpy'] + list(sorted(TIMES.keys() - {'numpy'}))\n",
+ " bars = [np.median(TIMES[key].timings) for key in x]\n",
+ " yerr = [np.std(TIMES[key].timings) for key in x]\n",
+ " color = [('#86add9' if 'dace' in key else 'salmon') for key in x]\n",
+ "\n",
+ " p = plt.bar(x, bars, yerr=yerr, color=color)\n",
+ " plt.ylabel('Runtime [s]'); plt.xlabel('Implementation'); plt.title(title); \n",
+ " if labels:\n",
+ " plt.gca().bar_label(p)\n",
+ " pass"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "317721fd",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Setup code for benchmarked frameworks\n",
+ "import numpy as np\n",
+ "import jax\n",
+ "import numba\n",
+ "import dace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "46238b6e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Pythran loads in a separate cell\n",
+ "%load_ext pythran.magic"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0e44fb94",
+ "metadata": {},
+ "source": [
+ "## Simple programs with multiple operators\n",
+ "\n",
+ "Let's start with a basic program with three different operations. This example program was taken from the [JAX README](https://github.com/google/jax#compilation-with-jit):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "d9828ae7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def slow_f(x):\n",
+ " return x * x + x * 2.0"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "74047bc8",
+ "metadata": {},
+ "source": [
+ "First, let's measure the performance of NumPy as-is on this function:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "afe8910d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "68.6 ms ± 2.36 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "a = np.random.rand(5000, 5000)\n",
+ "\n",
+ "TIMES = {}\n",
+ "\n",
+ "TIMES['numpy'] = %timeit -o slow_f(a)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0d5afed2",
+ "metadata": {},
+ "source": [
+ "Now we can construct Just-In-Time (JIT) compiled versions of this function, for each framework:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "f66e04d1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "jax_f = jax.jit(slow_f)\n",
+ "numba_f = numba.jit(slow_f)\n",
+ "dace_f = dace.program(auto_optimize=True)(slow_f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "8b6f4f7b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%%pythran\n",
+ "#pythran export pythran_f(float64[:,:])\n",
+ "def pythran_f(x):\n",
+ " return x * x + x * 2.0"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "de148d29",
+ "metadata": {},
+ "source": [
+ "Before we measure the time, we will run the functions first as a warmup, to allow compilers to run JIT compilation:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "99491394",
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1.29 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
+ "323 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
+ "1.23 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "# On your marks...\n",
+ "%timeit -r 1 -n 1 jax_f(a).block_until_ready()\n",
+ "%timeit -r 1 -n 1 numba_f(a)\n",
+ "%timeit -r 1 -n 1 dace_f(a)\n",
+ "%timeit -r 1 -n 1 pythran_f(a)\n",
+ "pass\n",
+ "# ...get set..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "067febc9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "43.6 ms ± 4.87 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "# ...Go!\n",
+ "TIMES['jax'] = %timeit -o jax_f(a).block_until_ready()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "e7f811ff",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "27.8 ms ± 3.97 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['numba'] = %timeit -o numba_f(a)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "e6d98ce6",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "31.3 ms ± 5.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['pythran'] = %timeit -o pythran_f(a)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "9db35692",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "25.7 ms ± 2.61 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['dace_jit'] = %timeit -o dace_f(a)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4bb9be46",
+ "metadata": {},
+ "source": [
+ "You could also precompile the program for faster runtimes (be aware that the return value is retained across calls!):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "a3c0702e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Either provide type annotations on the `@dace.program`, or call `compile` with sample arguments\n",
+ "cprog = dace_f.compile(a)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "d0754f47",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "21.5 ms ± 1.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['dace'] = %timeit -o cprog(a)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "78d0830a",
+ "metadata": {},
+ "source": [
+ "We can now plot the results:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "01ae5917",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "barplot('Simple program, multiple operators')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "16be4882",
+ "metadata": {},
+ "source": [
+ "## Loops\n",
+ "\n",
+ "Here we test how interpreter overhead can be mitigated by the Python compiling frameworks. Let's take another application from Numba's [5 minute guide](https://numba.readthedocs.io/en/stable/user/5minguide.html):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "c7134a92",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def go_fast(a):\n",
+ " trace = 0.0\n",
+ " for i in range(a.shape[0]):\n",
+ " trace += np.tanh(a[i, i])\n",
+ " return a + trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "844c1c84",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "b = np.random.rand(1000, 1000)\n",
+ "\n",
+ "TIMES = {}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "69ef66f2",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1.94 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['numpy'] = %timeit -o go_fast(b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "1b6aef84",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "numba_fast = numba.jit(go_fast)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "e74804c4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import jax.numpy as jnp\n",
+ "\n",
+ "@jax.jit\n",
+ "def jax_fast(a):\n",
+ " trace = 0.0\n",
+ " for i in range(a.shape[0]):\n",
+ " trace += jnp.tanh(a[i, i])\n",
+ " return a + trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "f88a24c6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "N = dace.symbol('N')\n",
+ "\n",
+ "@dace.program(auto_optimize=True)\n",
+ "def dace_fast(a: dace.float64[N, N]):\n",
+ " trace = 0.0\n",
+ " for i in range(N):\n",
+ " trace += np.tanh(a[i, i])\n",
+ " return a + trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "e6f18b89",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "%%pythran\n",
+ "from numpy import tanh\n",
+ "\n",
+ "#pythran export pythran_fast(float64[:,:])\n",
+ "def pythran_fast(a):\n",
+ " trace = 0.0\n",
+ " for i in range(a.shape[0]):\n",
+ " trace += tanh(a[i, i])\n",
+ " return a + trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "e7e5ab60",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "DaCe compilation time: 0.5581727027893066 seconds\n"
+ ]
+ }
+ ],
+ "source": [
+ "import time\n",
+ "start = time.time()\n",
+ "csdfg = dace_fast.compile(b)\n",
+ "print('DaCe compilation time:', time.time() - start, 'seconds')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "a67d01ac",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "11.8 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
+ "147 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "%timeit -r 1 -n 1 jax_fast(b).block_until_ready()\n",
+ "%timeit -r 1 -n 1 numba_fast(b)\n",
+ "%timeit -r 1 -n 1 pythran_fast(b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7e0ffab9",
+ "metadata": {},
+ "source": [
+ "Note that the slow JAX first run time is due to the inspector/executor model, in which the compilation time depends on the size of the array."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "97657722",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.28 ms ± 538 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['jax'] = %timeit -o jax_fast(b).block_until_ready()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "6696626d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "970 µs ± 130 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['numba'] = %timeit -o numba_fast(b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "98a80c82",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "673 µs ± 54.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['pythran'] = %timeit -o pythran_fast(b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "7a741c90",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "668 µs ± 56.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['dace'] = %timeit -o csdfg(b, N=b.shape[0])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "fc4c6fb2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "barplot('Loops')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e888f1f6",
+ "metadata": {},
+ "source": [
+ "### Varying sizes\n",
+ "\n",
+ "Since the DaCe program was defined symbolically, the input array size can be changed without recompilation:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "fbdc52c3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sizes = [np.random.randint(700, 5000) for _ in range(10)]\n",
+ "arrays = [np.random.rand(n, n) for n in sizes]\n",
+ "\n",
+ "def vary_size(call):\n",
+ " for a in arrays:\n",
+ " call(a)\n",
+ "\n",
+ "def vary_size_dace(call):\n",
+ " for a, n in zip(arrays, sizes):\n",
+ " call(a, N=n)\n",
+ " \n",
+ "def vary_size_jax(call):\n",
+ " for a in arrays:\n",
+ " call(a).block_until_ready()\n",
+ " \n",
+ "TIMES = {}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "2aa26e86",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "155 ms ± 2.63 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
+ "125 ms ± 3.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
+ "124 ms ± 2.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
+ "114 ms ± 8.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
+ "334 ms ± 166 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "TIMES['numpy'] = %timeit -o vary_size(go_fast)\n",
+ "TIMES['numba'] = %timeit -o vary_size(numba_fast)\n",
+ "TIMES['pythran'] = %timeit -o vary_size(pythran_fast)\n",
+ "TIMES['dace'] = %timeit -o vary_size_dace(csdfg)\n",
+ "TIMES['jax'] = %timeit -o vary_size_jax(jax_fast)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "144b470a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "barplot('Loop - Varying sizes')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "16405894",
+ "metadata": {},
+ "source": [
+ "## Auto-parallelization\n",
+ "\n",
+ "DaCe can use data-centric dependency analysis to not only track and reduce data movement, but also automatically extract parallel regions in code. Here we look at a simple program and how it is run in parallel. We use the `auto_optimize` flag in the `dace.program` decorator to automatically apply optimization heuristics."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "eb5b28ca",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def element_update(a):\n",
+ " return a * 5\n",
+ "\n",
+ "def someforloop(A):\n",
+ " for i in range(A.shape[0]):\n",
+ " for j in range(A.shape[1]):\n",
+ " A[i, j] = element_update(A[i, j])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "d80217b2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a = np.random.rand(1000, 1000)\n",
+ "daceloop = dace.program(auto_optimize=True)(someforloop)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f2ba2545",
+ "metadata": {},
+ "source": [
+ "Here it is compared with numpy and numba's similar capability:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "8420d1f0",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "446 ms ± 41.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ ":4: NumbaWarning: \u001b[1m\n",
+ "Compilation is falling back to object mode WITH looplifting enabled because Function \"someforloop\" failed type inference due to: \u001b[1mUntyped global name 'element_update':\u001b[0m \u001b[1m\u001b[1mCannot determine Numba type of \u001b[0m\n",
+ "\u001b[1m\n",
+ "File \"\", line 7:\u001b[0m\n",
+ "\u001b[1mdef someforloop(A):\n",
+ "