Dagger's DArray has a variety of ways to parallelize operations like map, reduce, *, and more. These operations are built on a few different mechanisms that Dagger provides for parallelism, but there is one among them that is particularly powerful: the Datadeps system (short for "data dependencies").
Datadeps builds on Dagger's task model and the DArray abstraction to provide a way to turn ordinary sequential algorithms into parallel, scalable algorithms. Datadeps was originally built to closely mirror OpenMP's "depend" clause, which allows parallelizing algorithms by specifying how each operation accesses their arguments (read, write, or read+write). This model is extraordinarily powerful for parallelizing algorithms that have complex dependencies between operations, where simpler parallelism models (such as Map-Reduce, broadcast, etc.) are insufficient. Dagger's Datadeps further extends the model to support parallelizing operations which access only a portion of their arguments (such as views of an array or a matrix wrapped in UpperTriangular), which can prove invaluable for parallelizing a huge variety of algorithms. Let's see how to work with Datadeps by parallelizing a simple array algorithm, a vector sum:
SHOW CODE
In this example, we can see a key feature of Datadeps: the Out wrapper, which tells Datadeps that a task writes to some or all of its argument. In this case, our sum! call is writing to a single element of Dtemp (through a view), so we use Out(Dtemp_view) to tell Datadeps that this task writes to that element. This allows Datadeps to correctly order tasks, and thus recogize that all of these calls to sum! can be executed in parallel.
Another key feature of Datadeps is not so obvious: each argument to a Dagger.@spawn call that doesn't specify Out (or its friends, In, InOut, and Deps) is assumed to be read-only. This is the same as wrapping an argument with In, which tells Datadeps that a task only reads from some or all of its argument, but never writes to it.