Skip to content
Alexey Khudyakov edited this page Sep 1, 2015 · 17 revisions

DNA is a data flow DSL aimed at expressing data movement and initiation of computational kernels for numerical calculations. We use the "actor/channel" paradigm, which allows for a descriptive approach that separates definition from execution strategy. Our target is data intensive high performance computing applications that employ hierarchical cluster scheduling techniques. Furthermore, we provide infrastructure for detailed profiling and high availability, allowing recovery for certain types of failures.

DNA is presently implemented as an embedded monadic DSL on top of the well-established distributed programming framework "Cloud Haskell". This document describes the structure of the language at a high level, followed by detailed specifications and use cases for the introduced primitives. We will give examples at several points.

High level structure

DNA programs are composed of actors and channels. DNA provides means for defining an abstract data flow graph using programming language primitives.

Actors are executed concurrently, don't share state and can only communicate using a restricted message passing scheme.

Every actor can receive either one or many inputs of the same type and produce either one or multiple outputs. This depends on the type of the actor: For example, a single Actor will only ever accept one input parameter and produce one result. On the other hand, a group of Actors will produce an unordered set of values of same type. Finally, a CollectActor receives a group of values while producing a single result. In general, actors have no knowledge where their input parameters come from or where result will be sent, these connections will be made from the outside.

Actors are spawned hierarchically, so every actor but the first will be created by a parent actor. Communication is forced to flow along these hierarchies: Both inputs and results can only be sent to and received from either the parent actor or sibling actors on the same level.

Furthermore, DNA offers the possibility to spawn groups of actors. Every actor in a group will run the same code, but using different input parameters. To distinguish actors in a group, they get assigned ranks from 0 to N-1. Conceptually, a group of actors is treated as single actor which runs on several execution elements simultaneously.

To illustrate this, here is example of distributed dot product. We assume that ddpComputeVector, ddpReadVector and splitSlice are already defined:

-- Calculate dot product of slice of full vector
ddpProductSlice = actor $ \(fullSlice) -> duration "vector slice" $ do
 -- Calculate offsets
 slices <- scatterSlice <$> groupSize
 slice  <- (slices !!)  <$> rank
 -- First we need to generate files on tmpfs
 fname <- duration "generate" $ eval ddpGenerateVector n
 -- Start local processes
 shellVA <- startActor (N 0) $ useLocal >> return $(mkStaticClosure 'ddpComputeVector)
 shellVB <- startActor (N 0) $ useLocal >> return $(mkStaticClosure 'ddpReadVector)
 -- Connect actors
 sendParam slice              shellVA
 sendParam (fname, Slice 0 n) shellVB
 futVA <- delay Local shellVA
 futVB <- delay Local shellVB
 -- Await results
 va <- duration "receive compute" $ await futVA
 vb <- duration "receive read"    $ await futVB
 -- Clean up, compute sum
 kernel "compute sum" [FloatHint 0 (2 * fromIntegral n)] $
 return (S.sum $ S.zipWith (*) va vb :: Double)

-- Calculate dot product of full vector
ddpDotProduct :: Actor Int64 Double
ddpDotProduct = actor $ \size -> do
    -- Chunk & send out
    shell <- startGroup (Frac 1) (NNodes 1) $ do
    useLocal
    return $(mkStaticClosure 'ddpProductSlice)
    broadcast (Slice 0 size) shell
    -- Collect results
    partials <- delayGroup shell
    duration "collecting vectors" $ gather partials (+) 0

main :: IO ()
main = dnaRun (...) $ d
  liftIO . print =<<  eval ddpDotProduct (400*1000*1000)

This generates an actor tree of the following shape:

    ddpDotProduct
          |
   ddpProductSlice
   /             \
ddpComputeVector  ddpReadVector

Here ddpDotProduct is a single actor, which takes exactly one parameter size and produces exactly the sum as its output. On the other hand, ddpProductSlice is an actor group, which sums up a portion of the full dot-product. Each actor in group spawns two child actors: ddpComputeVector and ddpReadVector are two child actors, which for our example are supposed to generate or read the requested vector slice from the hard desk, respectively.

Scheduling data flow programs for execution.

Scheduling, spawning and generation of the runtime data flow graph are handled separately. The starting point for scheduling is the cluster architecture descriptor, which describes the resources available to the program.

For DNA, we are using the following simple algorithm: First a control actor starts the program. It's actor which passed to runDna as parameter. This actor will be assigned exclusively all resources available to the program, which it can then in turn allocate to it spawn child actors. When a child actor finishes execution (either normally or abnormally), its resources are returned to parent actor's resource pool and can be reused.

High Availability

We must account for the fact that every actor could fail at any point. This could not only happen because of hardware failures, but also due to programming errors. In order to maintain the liveness of the data flow network, we must detect such failures, no matter the concrete reason. In the worst case, our only choice is to simply terminate all child processes and propagate the error to actors which depend on the failed actor. This approach is obviously problematic for achieving fault tolerance since we always have a single point of failure.

To improve stability, we need to make use of special cases. For example, let us assume that a single actor instance in large group fails. Then in some case it makes sense to simply ignore the failure and discard the partial result. This is the "failout" model. To use these semantics in the DNA program, all we need to do is to specify failout when spawning the actor with startGroup. To make use of failout example above should be changed to:

...
shell <- startGroup (Frac 1) (NNodes 1) $ do
    useLocal
    failout
    return $(mkStaticClosure 'ddpProductSlice)
...

Another important recovery technique is restarting failed processes. This obviously loses the current state of the restarted process, so any accumulated data is lost. In the current design, we only support this approach for CollectActors. Similarly only change to program is addition of respawnOnFail to parameters of actors.

Profiling

For maintaing a robust system performance, we track the performance of all actors and channels. This should allow us to assess exactly how performance is shaped by not only scheduling and resource allocation, but also performance of individual software and hardware components. For example, we might decide to change the scheduling with the goal of eliminating idle times, optimise kernels better or decide to run a kernel on more suitable computation hardware were available.

However, in order to facilitate making informed decisions about such changes, it is not only important to collect raw performance numbers such as time spent or memory consumed. For understanding the performance of the whole system we need to put our measurements into context. This means that we should associate them from the ground up with the data flow structure of the program.

Our approach is therefore to implement profiling as an integral service of the DNA runtime. The generated profile will automatically track the overall performance of the system, capturing timings of all involved actors and channels. Furthermore, wherever possible the data flow program should contribute extra information about its activity, such as number of floating point operations expected or amount of raw data transferred. In the end, we will use the key performance metrics derived from these values in order to visualise the whole system performance in a way that will hopefully allow for painless optimisation of the whole system.

DNA monad

data DNA a

<div class="doc">
  Monad for defining the behaviour of a cluster application. This concerns resource allocations as well as
  steering data and control flow.
</div>

<div class="subs instances">
  <p id="control.i:DNA" class="caption collapser" onclick="toggleSection('i:DNA')">Instances

  <div id="section.i:DNA" class="show">
    <table>
      <tr>
        <td class="src">Monad <a href="DNA.html#t:DNA">DNA</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Functor <a href="DNA.html#t:DNA">DNA</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Applicative <a href="DNA.html#t:DNA">DNA</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

dnaRun

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (RemoteTable -&gt; RemoteTable)</td>

      <td class="doc">
        Cloud haskell's remote tablse
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> ()</td>

      <td class="doc">
        DNA program
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; IO ()</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Execute DNA program. First parameter is list of remote tables. Each invocation of <code><a href=
  "DNA.html#v:remotable">remotable</a></code> generate <code>__remoteTable</code> top level identifier with
  type <code>RemoteTable -&gt; RemoteTable</code>. All such remote tables must composed using <code>.</code>
  and passed to <code>dnaRun</code> as in following example:
  <pre>

dnaRun (ModuleA.__remoteTable . ModuleB.__remoteTable) program

  UNIX startup. If command line parameter '--nprocs=N' is given. Program will create N processes on same
  machine and execute program using these processes as cloud haskell's nodes.

  SLURM startup. Jobs of starting processes is handled to SLURM and processes learn addresses of other
  processes from environment variables set by SLURM. No command line parameters is required in this case.
</div>

Groups of actors

Actor could run in groups. These groups are treated as single logical actor. Each actor in group is assigned rank from 0 to N-1 where N is group size. For uniformity single actors are treated as members of group of size 1. Both group size and rank could be accessed using rank and groupSize

rank :: DNA Int

<div class="doc">
  Obtains the rank of the current process in its group. Every process in a group of size <em>N</em> has
  assigned a rank from <em>0</em> to <em>N-1</em>. Single processes always have rank <em>0</em>. It should be
  used as follows:
  <pre>

do ... n <- rank ...

groupSize :: DNA Int

<div class="doc">
  Obtains the size of the group that the current process belongs to. For single processes this is always
  <em>1</em>. It should be used as follows:
  <pre>

do ... n <- groupSize ...

Logging and profiling

DNA programs write logs in GHC's eventlog format for recording execution progress and performance monitoring. Logs are written in following locations: ~/_dna/logs/PID-u/{N}/program-name.eventlog if program was started using UNIX startup or ~/_dna/logs/SLURM_JOB_ID-s/{N}/program-name.eventlog if it was started by SLURM (see runDna for detail of starting DNA program). They're stored in GHC's eventlog format.

logMessage :: String -> DNA ()

<div class="doc">
  Outputs a message to the eventlog as well as <code>stdout</code>. Useful for documenting progress and
  providing debugging information.

  For example, we could have an actor log the amount of resource it has available:
  <pre>

do avail <- availableNodes logMessage $ "Actor is running on " ++ show (avail+1) ++ " nodes."

  It will produce eventlog output similar to this
  <pre>

713150762: cap 0: MSG [pid=pid://localhost:40000:0:10] Actor is running on 8 node

duration

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: String</td>

      <td class="doc">
        Computation name for profiling
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> a</td>

      <td class="doc">
        <code><a href="DNA.html#t:DNA">DNA</a></code> code to profile
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Basic profiling for <code><a href="DNA.html#t:DNA">DNA</a></code> actions. Works basically the same way as
  <code><a href="DNA.html#v:kernel">kernel</a></code>, but without the specialised profiling support. Instead,
  the profiling report will only contain the wall clock time the contained <code><a href=
  "DNA.html#t:DNA">DNA</a></code> action took.

  For example, in the DNA example we used <code><a href="DNA.html#v:duration">duration</a></code> to profile
  how long a <code><a href="DNA.html#t:Promise">Promise</a></code> was <code><a href=
  "DNA.html#v:await">await</a></code>ed:
  <pre>

va <- duration "receive compute" $ await futVA

  It will result in eventlog output similar to:
  <pre>

941813583: cap 0: START [pid=pid://localhost:40000:0:12] receive compute ... 945372376: cap 0: END [pid=pid://localhost:40000:0:12] receive compute

Kernels

data Kern a

<div class="doc">
  Monad for actual calculation code. We expect all significant work of the cluster application to be
  encapsulated in this monad. In fact, the only way to perform arbitrary <code>IO</code> actions from
  <code><a href="DNA.html#t:DNA">DNA</a></code> is to use <code><a href="DNA.html#v:kernel">kernel</a></code>
  or <code><a href="DNA.html#v:unboundKernel">unboundKernel</a></code> and then <code><a href=
  "DNA.html#v:liftIO">liftIO</a></code> the desired code:
  <pre>

kernel "do IO" $ liftIO $ do someIoComputation

  Pure computations should be lifted into the <code><a href="DNA.html#t:Kern">Kern</a></code> monad as well
  whenever they are likely to require a significant amount of computation. However care needs to be taken that
  no thunks escape due to lazy evaluation. Ideally, the result should be fully evaluated:
  <pre>

kernel "pure computation" $ do let pure = pureCode return $! pure using rdeepseq

<div class="subs instances">
  <p id="control.i:Kern" class="caption collapser" onclick="toggleSection('i:Kern')">Instances

  <div id="section.i:Kern" class="show">
    <table>
      <tr>
        <td class="src">Monad <a href="DNA.html#t:Kern">Kern</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Functor <a href="DNA.html#t:Kern">Kern</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Applicative <a href="DNA.html#t:Kern">Kern</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> <a href="DNA.html#t:Kern">Kern</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

kernel

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: String</td>

      <td class="doc">
        Kernel name. This name will be used in profile analysis to refer to profiling data collected about
        the contained code.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; [<a href="DNA.html#t:ProfileHint">ProfileHint</a>]</td>

      <td class="doc">
        Kernel performance characteristics. This will prompt the framework to track specialised performance
        metrics, allowing in-depth analysis later.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Kern">Kern</a> a</td>

      <td class="doc">
        Th kernel code to execute.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Executes a kernel computation. The computation will be bound to an operating system thread by default (see
  also <code><a href="DNA.html#v:unboundKernel">unboundKernel</a></code>). The function will block until
  computation is done. Profile hints can be used to request profiling where desired.

  For example, we could define <code>ddpReadVector</code> as used in the DNA example as follows:
  <pre>

ddpReadVector = actor $ (fname, Slice off n) -> kernel "read vector" [iOHint{hintReadBytes = fromIntegral (n * 8)}] $ liftIO $ readData n off fname

  This "actor" reads a certain slice of a file from the disk, which is implemented using a "kernel" calling
  the <code>readData</code> <code>IO</code> action. As with most kernels, this could potentially become a
  bottleneck, therefore we supply DNA with a meaningful name (<code>read vector</code>) as well as a hint about
  how much I/O activity we expect. This will prompt the profiling framework to gather evidence about the actual
  I/O activity so we can compare it with our expectations.
</div>

unboundKernel

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: String</td>

      <td class="doc">
        Kernel name
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; [<a href="DNA.html#t:ProfileHint">ProfileHint</a>]</td>

      <td class="doc">
        Kernel performance characteristics
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Kern">Kern</a> a</td>

      <td class="doc">
        Kernel code
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  A variant of <code><a href="DNA.html#v:kernel">kernel</a></code> that executes the kernel in an
  <em>unbound</em> thread. Haskell runtime could migrate unbound haskell threads between OS threads. This is
  generally faster, but less safe. Especially profiling can be unreliable in this mode.

  The most likely use for this is cheap kernels that are unlikely to run for a significant time. For
  example, we could use an unbound kernel for cleaning up data:
  <pre>

unboundKernel "delete vector" [] $ liftIO $ removeFile fname

  Here we know that <code>removeFile</code> is safe to be called from unbound kernels, and likely cheap
  enough that allocating a full operating system thread can be considered overkill.
</div>

data ProfileHint

<div class="doc">
  A program annotation providing additional information about how much work we expect the program to be
  doing in a certain phase. The purpose of this hint is that we can set-up measurements to match these numbers
  to the program's real performance. Note that the hint must only be a best-effort estimate. As a rule of
  thumb, it is better to use a more conservative estimate, as this will generally result in lower performance
  estimates. These hints are passed to <code><a href="DNA.html#v:kernel">kernel</a></code> or <code><a href=
  "DNA.html#v:unboundKernel">unboundKernel</a></code>.

  Hints should preferably be constructed using the default constructors: <code><a href=
  "DNA.html#v:floatHint">floatHint</a></code>, <code><a href="DNA.html#v:memHint">memHint</a></code>,
  <code><a href="DNA.html#v:ioHint">ioHint</a></code>, <code><a href=
  "DNA.html#v:haskellHint">haskellHint</a></code> and <code><a href="DNA.html#v:cudaHint">cudaHint</a></code>.
  See their definitions for examples.
</div>

<div class="subs constructors">
  <p class="caption">Constructors

  <table>
    <tr>
      <td class="src"><a name="v:FloatHint" class="def" id="v:FloatHint">FloatHint</a></td>

      <td class="doc">
        Estimate for how many floating point operations the code is executing. Profiling will use
        <code>perf_event</code> in order to take measurements. Keep in mind that this has double-counting
        issues (20%-40% are not uncommon for SSE or AVX code).
      </td>
    </tr>

    <tr>
      <td colspan="2">
        <div class="subs fields">
          <p class="caption">Fields

          <dl>
            <dt class="src"><a name="v:hintFloatOps" class="def" id="v:hintFloatOps">hintFloatOps</a> ::
            !Int</dt>

            <dd class="doc empty">&nbsp;</dd>

            <dt class="src"><a name="v:hintDoubleOps" class="def" id="v:hintDoubleOps">hintDoubleOps</a> ::
            !Int</dt>

            <dd class="doc empty">&nbsp;</dd>
          </dl>

          <div class="clear"></div>
        </div>
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:MemHint" class="def" id="v:MemHint">MemHint</a></td>

      <td class="doc">
        Estimate for the amount of data that will have to be read from RAM over the course of the kernel
        calculation.
      </td>
    </tr>

    <tr>
      <td colspan="2">
        <div class="subs fields">
          <p class="caption">Fields

          <dl>
            <dt class="src"><a name="v:hintMemoryReadBytes" class="def" id=
            "v:hintMemoryReadBytes">hintMemoryReadBytes</a> :: !Int</dt>

            <dd class="doc empty">&nbsp;</dd>
          </dl>

          <div class="clear"></div>
        </div>
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:IOHint" class="def" id="v:IOHint">IOHint</a></td>

      <td class="doc">
        Estimate for how much data the program is reading or writing from/to external sources.
      </td>
    </tr>

    <tr>
      <td colspan="2">
        <div class="subs fields">
          <p class="caption">Fields

          <dl>
            <dt class="src"><a name="v:hintReadBytes" class="def" id="v:hintReadBytes">hintReadBytes</a> ::
            !Int</dt>

            <dd class="doc empty">&nbsp;</dd>

            <dt class="src"><a name="v:hintWriteBytes" class="def" id="v:hintWriteBytes">hintWriteBytes</a> ::
            !Int</dt>

            <dd class="doc empty">&nbsp;</dd>
          </dl>

          <div class="clear"></div>
        </div>
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:HaskellHint" class="def" id="v:HaskellHint">HaskellHint</a></td>

      <td class="doc">
        Rough estimate for how much Haskell work we are doing
      </td>
    </tr>

    <tr>
      <td colspan="2">
        <div class="subs fields">
          <p class="caption">Fields

          <dl>
            <dt class="src"><a name="v:hintAllocation" class="def" id="v:hintAllocation">hintAllocation</a> ::
            !Int</dt>

            <dd class="doc empty">&nbsp;</dd>
          </dl>

          <div class="clear"></div>
        </div>
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:CUDAHint" class="def" id="v:CUDAHint">CUDAHint</a></td>

      <td class="doc">
        CUDA statistics. The values are hints about how much data transfers we expect to be targetting the
        device and the host respectively.

        The FLOP hints will only be checked if logging is running in either <code>"float-ops"</code> or
        <code>"double-ops"</code> mode, respectively. Note that this requires instrumentation, which will
        reduce overall performance!
      </td>
    </tr>

    <tr>
      <td colspan="2">
        <div class="subs fields">
          <p class="caption">Fields

          <dl>
            <dt class="src"><a name="v:hintCopyBytesHost" class="def" id=
            "v:hintCopyBytesHost">hintCopyBytesHost</a> :: !Int</dt>

            <dd class="doc empty">&nbsp;</dd>

            <dt class="src"><a name="v:hintCopyBytesDevice" class="def" id=
            "v:hintCopyBytesDevice">hintCopyBytesDevice</a> :: !Int</dt>

            <dd class="doc empty">&nbsp;</dd>

            <dt class="src"><a name="v:hintCudaFloatOps" class="def" id=
            "v:hintCudaFloatOps">hintCudaFloatOps</a> :: !Int</dt>

            <dd class="doc empty">&nbsp;</dd>

            <dt class="src"><a name="v:hintCudaDoubleOps" class="def" id=
            "v:hintCudaDoubleOps">hintCudaDoubleOps</a> :: !Int</dt>

            <dd class="doc empty">&nbsp;</dd>
          </dl>

          <div class="clear"></div>
        </div>
      </td>
    </tr>
  </table>
</div>

floatHint :: ProfileHint

<div class="doc">
  Default constructor for <code><a href="DNA.html#v:FloatHint">FloatHint</a></code> with hint 0 for all
  metrics. Can be used for requesting FLOP profiling. Hints can be added by overwriting fields values.

  For example, we can use this <code><a href="DNA.html#t:ProfileHint">ProfileHint</a></code> to declare the
  amount of floating point operations involved in computing a sum:
  <pre>

kernel "compute sum" [floatHint{hintDoubleOps = fromIntegral (2n)} ] $ return $ (S.sum $ S.zipWith () va vb :: Double)

memHint :: ProfileHint

<div class="doc">
  Default constructor for <code><a href="DNA.html#v:MemHint">MemHint</a></code> with hint 0 for all metrics.
  Can be used for requesting memory bandwidth profiling. Hints can be added by overwriting field values.

  This could be used to track the bandwidth involved in copying a large buffer:
  <pre>

let size = Vec.length in * sizeOf (Vec.head in) kernel "copy buffer" [memHint{hintMemoryReadBytes=size}] $ liftIO $ VecMut.copy in out

ioHint :: ProfileHint

<div class="doc">
  Default constructor for <code><a href="DNA.html#v:IOHint">IOHint</a></code> with hint 0 for all metrics.
  Can be used for requesting I/O bandwidth profiling. Hints can be added by overwriting field values.

  This can be used to document the amount of data that we expect to read from a hard drive:
  <pre>

kernel "read vector" [iOHint{hintReadBytes = fromIntegral (n * 8)}] $ liftIO $ readData n off fname

haskellHint :: ProfileHint

<div class="doc">
  Default constructor for <code><a href="DNA.html#v:IOHint">IOHint</a></code> with hint 0 for all metrics.
  Can be used for requesting Haskell allocation profiling. Hints can be added by overwriting field values.

  Useful for tracking the amount of allocation Haskell does in a certain computation. This can often be a
  good indicator for whether it has been compiled in an efficient way.
  <pre>

unboundKernel "generate vector" [HaskellHint (fromIntegral $ n * 8)] $ liftIO $ withFileChan out "data" WriteMode $ \h -> BS.hPut h $ runPut $ replicateM_ (fromIntegral n) $ putFloat64le 0.1

  For example, this <code><a href="DNA.html#v:HaskellHint">HaskellHint</a></code> specifies that Haskell is
  allowed to only heap-allocate one <code>Double</code>-object per value written.
</div>

cudaHint :: ProfileHint

<div class="doc">
  Default constructor for <code><a href="DNA.html#v:CUDAHint">CUDAHint</a></code> with hint 0 for all
  metrics. Can be used for requesting Haskell allocation profiling. Hints can be added by overwriting field
  values.

  For instance, we could wrap an <code>accelerate</code> computation as follows:
  <pre>

let size = S.length va kernel "accelerate dot product" [cudaHint{hintCudaDoubleOps=size2}] $ liftIO $ do let sh = S.length va va' = A.fromVectors (A.Z A.:. size) ((), va) :: A.Vector Double vb' = A.fromVectors (A.Z A.:. size) ((), vb) :: A.Vector Double return $ head $ A.toList $ CUDA.run $ A.fold (+) 0 $ A.zipWith () (A.use va') (A.use vb')

Actors

data Actor a b

<div class="doc">
  This is the simplest kind of actor. It receives exactly one message of type <code>a</code> and produce a
  result of type <code>b</code>. It could only be constructed using <code><a href=
  "DNA.html#v:actor">actor</a></code> function.
</div>

<div class="subs instances">
  <p id="control.i:Actor" class="caption collapser" onclick="toggleSection('i:Actor')">Instances

  <div id="section.i:Actor" class="show">
    <table>
      <tr>
        <td class="src">Typeable (* -&gt; * -&gt; *) <a href="DNA.html#t:Actor">Actor</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

actor

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable a, Serializable b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; (a -&gt; <a href="DNA.html#t:DNA">DNA</a> b)</td>

      <td class="doc">
        data flow definition
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Actor">Actor</a> a b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Smart constructor for <code><a href="DNA.html#t:Actor">Actor</a></code>s. As the type signature shows, an
  <code><a href="DNA.html#t:Actor">Actor</a></code> is constructed from a function that takes a parameter
  <code>a</code> and returns a result <code>b</code>. The <code><a href="DNA.html#t:DNA">DNA</a></code> monad
  allows the actor to take further actions, such as spawning other actors or starting data transfers.

  For example following actor adds one to its parameter
  <pre>

succActor :: Actor Int Int succActor = actor $ \i -> return (i+1)

data CollectActor a b

<div class="doc">
  In contrast to a simple <code><a href="DNA.html#t:Actor">Actor</a></code>, actors of this type can receive
  a group of messages. However, it will still produce just a singular message. In functional programming terms,
  this actor corresponds to a <code>fold</code>, which reduces an unordered set of messages into an aggregate
  output value. It could only be constructed using <code><a href=
  "DNA.html#v:collectActor">collectActor</a></code> function.
</div>

<div class="subs instances">
  <p id="control.i:CollectActor" class="caption collapser" onclick="toggleSection('i:CollectActor')">
  Instances

  <div id="section.i:CollectActor" class="show">
    <table>
      <tr>
        <td class="src">Typeable (* -&gt; * -&gt; *) <a href="DNA.html#t:CollectActor">CollectActor</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

collectActor

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable a, Serializable b, Serializable s)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; (s -&gt; a -&gt; <a href="DNA.html#t:Kern">Kern</a> s)</td>

      <td class="doc">
        stepper function
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Kern">Kern</a> s</td>

      <td class="doc">
        start value
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; (s -&gt; <a href="DNA.html#t:Kern">Kern</a> b)</td>

      <td class="doc">
        termination function
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:CollectActor">CollectActor</a> a b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Just like a <code>fold</code>, a <code>CollectorActor</code> is defined in terms of an internal state
  which gets updated for every message received. To be precise, the state first gets initialised using a start
  value, then gets updated successively using the stepper function. Once all results have been received, the
  termination function generates the overall result value of the actor.

  In this example actor sums its parameters. It's very simple actor. In this case type of accumulator
  (<code>s</code> above) is same as type of resulting value (<code>Double</code>) but this isn't necessary. It
  also doesn't do any IO.

  <pre>

sumActor :: CollectorActor Double Double sumActor = collectActor (\sum a -> return (sum + a)) (return 0) (\sum -> return sum)

</div>

Spawning

Actors could be spawned using start* functions. They spawn new actors which are executed asynchronously and usually on remote nodes. Nodes for newly spawned actor(s) are taken from pool of free nodes. If there's not enough nodes it's runtime error. eval* functions allows to execute actor synchronously.

Eval

eval

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable a, Serializable b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Actor">Actor</a> a b</td>

      <td class="doc">
        Actor to execute
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; a</td>

      <td class="doc">
        Value which is passed to an actor as parameter
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  If one don't want to create new actor it's possible to execute simple <code><a href=
  "DNA.html#t:Actor">Actor</a></code> inside current actor. For example:
  <pre>

do ... b <- eval someActor 42 ...

evalClosure

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Typeable a, Typeable b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; Closure (<a href="DNA.html#t:Actor">Actor</a> a b)</td>

      <td class="doc">
        Actor to execute
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; a</td>

      <td class="doc">
        Value which is passed to an actor as parameter
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Like <code><a href="DNA.html#v:eval">eval</a></code>, but uses a <code>Closure</code> of the actor
  code.
</div>

Spawn parameters

data Spawn a

<div class="doc">
  Monad for accumulating optional parameters for spawning processes. It exists only to (ab)use do-notation
  and meant to be used as follows:
  <pre>

do useLocal return $(mkStaticClosure 'actorName)

<div class="subs instances">
  <p id="control.i:Spawn" class="caption collapser" onclick="toggleSection('i:Spawn')">Instances

  <div id="section.i:Spawn" class="show">
    <table>
      <tr>
        <td class="src">Monad <a href="DNA.html#t:Spawn">Spawn</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Functor <a href="DNA.html#t:Spawn">Spawn</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Applicative <a href="DNA.html#t:Spawn">Spawn</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

useLocal :: Spawn ()

<div class="doc">
  With this parameter new actor will be spawned on same node as parent actor. In case of group of actors one
  of newly spawned actors will run on local node. Otherwise it will be spawned on other node. See documentation
  for <code><a href="DNA.html#t:Res">Res</a></code> for description of interaction of this flag with resource
  allocation.
</div>

failout :: Spawn ()

<div class="doc">
  Spawn the process using the "failout" fault-tolerance model. Only valid for group of processes (it's
  ignored for spawning single process actors). If some actor in group fails group will still continue.
</div>

respawnOnFail :: Spawn ()

<div class="doc">
  Try to respawn actor in case of crash.
</div>

debugFlags :: [DebugFlag] -> Spawn ()

<div class="doc">
  Set debugging flags. They are mostly useful for debugging DNA itself.
</div>

data DebugFlag

<div class="doc">
  Flags which could be passed to actors for debugging purposes
</div>

<div class="subs constructors">
  <p class="caption">Constructors

  <table>
    <tr>
      <td class="src"><a name="v:CrashProbably" class="def" id="v:CrashProbably">CrashProbably</a> Double</td>

      <td class="doc">
        Crash during startup with given probability. Not all actors will honor that request
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:EnableDebugPrint" class="def" id="v:EnableDebugPrint">EnableDebugPrint</a>
      Bool</td>

      <td class="doc">
        Enable debug printing. If parameter is true child actors will have debug printing enabled too.
      </td>
    </tr>
  </table>
</div>

<div class="subs instances">
  <p id="control.i:DebugFlag" class="caption collapser" onclick="toggleSection('i:DebugFlag')">Instances

  <div id="section.i:DebugFlag" class="show">
    <table>
      <tr>
        <td class="src">Eq <a href="DNA.html#t:DebugFlag">DebugFlag</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Show <a href="DNA.html#t:DebugFlag">DebugFlag</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Generic <a href="DNA.html#t:DebugFlag">DebugFlag</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Binary <a href="DNA.html#t:DebugFlag">DebugFlag</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Typeable * <a href="DNA.html#t:DebugFlag">DebugFlag</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><span class="keyword">type</span> Rep <a href="DNA.html#t:DebugFlag">DebugFlag</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

Resources

These data types are used for describing how much resources should be allocated to nodes and are passed as parameters to start* functions.

data Res

<div class="doc">
  This describes how many nodes we want to allocate either to a single actor process or to the group of
  processes as whole. We can either request exactly <em>n</em> nodes or a fraction of the total pool of free
  nodes. If there isn't enough nodes in the pool to satisfy request it will cause runtime error.

  For example <code>N 4</code> requests exactly for nodes. And <code>Frac 0.5</code> requests half of all
  currently available nodes.

  Local node (which could be added using <code><a href="DNA.html#v:useLocal">useLocal</a></code>) is added
  in addition to this. If in the end 0 nodes will be allocated it will cause runtime error.
</div>

<div class="subs constructors">
  <p class="caption">Constructors

  <table>
    <tr>
      <td class="src"><a name="v:N" class="def" id="v:N">N</a> Int</td>

      <td class="doc">
        Fixed number of nodes
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:Frac" class="def" id="v:Frac">Frac</a> Double</td>

      <td class="doc">
        Fraction of nodes. Should lie in <em>(0,1]</em> range.
      </td>
    </tr>
  </table>
</div>

<div class="subs instances">
  <p id="control.i:Res" class="caption collapser" onclick="toggleSection('i:Res')">Instances

  <div id="section.i:Res" class="show">
    <table>
      <tr>
        <td class="src">Show <a href="DNA.html#t:Res">Res</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Generic <a href="DNA.html#t:Res">Res</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Binary <a href="DNA.html#t:Res">Res</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Typeable * <a href="DNA.html#t:Res">Res</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><span class="keyword">type</span> Rep <a href="DNA.html#t:Res">Res</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

data ResGroup

<div class="doc">
  Describes how to divide allocated nodes between worker processes.
</div>

<div class="subs constructors">
  <p class="caption">Constructors

  <table>
    <tr>
      <td class="src"><a name="v:NWorkers" class="def" id="v:NWorkers">NWorkers</a> Int</td>

      <td class="doc">
        divide nodes evenly between <em>n</em> actors.
      </td>
    </tr>

    <tr>
      <td class="src"><a name="v:NNodes" class="def" id="v:NNodes">NNodes</a> Int</td>

      <td class="doc">
        Allocate no less that <em>n</em> nodes for each actors. DSL will try to create as many actor as
        possible under given constraint
      </td>
    </tr>
  </table>
</div>

<div class="subs instances">
  <p id="control.i:ResGroup" class="caption collapser" onclick="toggleSection('i:ResGroup')">Instances

  <div id="section.i:ResGroup" class="show">
    <table>
      <tr>
        <td class="src">Show <a href="DNA.html#t:ResGroup">ResGroup</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Generic <a href="DNA.html#t:ResGroup">ResGroup</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Binary <a href="DNA.html#t:ResGroup">ResGroup</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Typeable * <a href="DNA.html#t:ResGroup">ResGroup</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><span class="keyword">type</span> Rep <a href="DNA.html#t:ResGroup">ResGroup</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

data Location

<div class="doc">
  Describes whether some entity should be local to node or could be possibly on remote node.
</div>

<div class="subs constructors">
  <p class="caption">Constructors

  <table>
    <tr>
      <td class="src"><a name="v:Remote" class="def" id="v:Remote">Remote</a></td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src"><a name="v:Local" class="def" id="v:Local">Local</a></td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="subs instances">
  <p id="control.i:Location" class="caption collapser" onclick="toggleSection('i:Location')">Instances

  <div id="section.i:Location" class="show">
    <table>
      <tr>
        <td class="src">Eq <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Ord <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Show <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Generic <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Binary <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Typeable * <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><span class="keyword">type</span> Rep <a href="DNA.html#t:Location">Location</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

availableNodes :: DNA Int

<div class="doc">
  Returns the number of nodes that are available at the moment for spawning of remote processes.
</div>

waitForResources :: Shell a b -> DNA ()

<div class="doc">
  Barrier that ensures that all resources associated with the given actor have been returned to pool and can
  be re-allocated. It will block until resources are returned.
  <pre>

do a <- startActor ... ... waitForResources a

  After <code>waitForResources a</code> it's guaranteed that resources allocated to actor <code>a</code>
  have been returned.

  N.B. It only ensures that actor released resources. They could be taken by another start* function.
</div>

Function to spawn new actors

All functions for starting new actors following same pattern. They take parameter which describe how many nodes should be allocated to actor(s) and Closure to actor to be spawned. They all return handle to running actor (see documentation of Shell for details).
Here is example of spawning single actor on remote node. To be able to create <code>Closure</code> to
execute actor on remote node we need to make it "remotable". For details of <code><a href=
"DNA.html#v:remotable">remotable</a></code> semantics refer to distributed-process documentation,. (This could
change in future version of <code>distributed-process</code> when it start use StaticPointers language
extension)
<pre>

someActor :: Actor Int Int someActor = actor $ \i -> ...

remotable [ 'someActor ]

Finally we start actor and allocate 3 nodes to it:
<pre>

do a <- startActor (N 3) (return $(mkStaticClosure 'someActor)) ...

In next example we start group of actors, use half of available nodes and local node in addition to that.
These nodes will be evenly divided between 4 actors:
<pre>

do a <- startGroup (Frac 0.5) (NWorkers 4) $ do useLocal return $(mkStaticClosure 'someActor) ...

All other start* functions share same pattern and could be used in similar manner.

startActor

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable a, Serializable b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Res">Res</a></td>

      <td class="doc">
        How many nodes do we want to allocate for actor
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Spawn">Spawn</a> (Closure (<a href="DNA.html#t:Actor">Actor</a>
      a b))</td>

      <td class="doc">
        Actor to spawn
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Shell">Shell</a> (<a href=
      "DNA.html#t:Val">Val</a> a) (<a href="DNA.html#t:Val">Val</a> b))</td>

      <td class="doc">
        Handle to spawned actor
      </td>
    </tr>
  </table>
</div>

<div class="doc">
  Starts a single actor as a new process, and returns the handle to the running actor. Spawned actor will
  receive single message and produce single result as described by <code><a href=
  "DNA.html#t:Val">Val</a></code> type tags.
</div>

startGroup

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable a, Serializable b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Res">Res</a></td>

      <td class="doc">
        How many nodes do we want to allocate for actor
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:ResGroup">ResGroup</a></td>

      <td class="doc">
        How to divide nodes between actors in group
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Spawn">Spawn</a> (Closure (<a href="DNA.html#t:Actor">Actor</a>
      a b))</td>

      <td class="doc">
        Actor to spawn
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Shell">Shell</a> (<a href=
      "DNA.html#t:Scatter">Scatter</a> a) (<a href="DNA.html#t:Grp">Grp</a> b))</td>

      <td class="doc">
        Handle to spawned actor
      </td>
    </tr>
  </table>
</div>

<div class="doc">
  Start a group of actor processes. They receive set of values which could be sent to them using
  <code><a href="DNA.html#v:broadcast">broadcast</a></code> or <code><a href=
  "DNA.html#v:distributeWork">distributeWork</a></code> and produce group of values as result.
</div>

startCollector

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable a, Serializable b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Res">Res</a></td>

      <td class="doc">
        How many nodes do we want to allocate for actor
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Spawn">Spawn</a> (Closure (<a href=
      "DNA.html#t:CollectActor">CollectActor</a> a b))</td>

      <td class="doc">
        Actor to spawn
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Shell">Shell</a> (<a href=
      "DNA.html#t:Grp">Grp</a> a) (<a href="DNA.html#t:Val">Val</a> b))</td>

      <td class="doc">
        Handle to spawned actor
      </td>
    </tr>
  </table>
</div>

<div class="doc">
  As <code><a href="DNA.html#v:startActor">startActor</a></code>, but starts collector actor. It receives
  groups of messages from group of actors and produces single result.
</div>

startCollectorTree

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Spawn">Spawn</a> (Closure (<a href=
      "DNA.html#t:CollectActor">CollectActor</a> a a))</td>

      <td class="doc">
        Actor to spawn
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Shell">Shell</a> (<a href=
      "DNA.html#t:Grp">Grp</a> a) (<a href="DNA.html#t:Val">Val</a> a))</td>

      <td class="doc">
        Handle to spawned actor
      </td>
    </tr>
  </table>
</div>

<div class="doc">
  Start a group of collector actor processes. It always require one node.
</div>

startCollectorTreeGroup

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Res">Res</a></td>

      <td class="doc">
        How many nodes do we want to allocate for group of actors
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Spawn">Spawn</a> (Closure (<a href=
      "DNA.html#t:CollectActor">CollectActor</a> a a))</td>

      <td class="doc">
        Actor to spawn
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Shell">Shell</a> (<a href=
      "DNA.html#t:Grp">Grp</a> a) (<a href="DNA.html#t:Grp">Grp</a> a))</td>

      <td class="doc">
        Handle to spawned actor
      </td>
    </tr>
  </table>
</div>

<div class="doc">
  Start a group of collector actor processes to collect data in tree-like fashion. They collect data from
  group of actors and divide it between themselves. So if we have 12 worker actors in a group and 3 actor in
  group of collectors collector with rank 0 will collect results from workers with rank 0..3 etc. Collectors
  will produce 3 result which in turn should be aggregated by another collector.
</div>

Shell

data Shell a b

<div class="doc">
  Handle of a running actor or group. Note that we treat actors and groups of actors uniformly here. Shell
  data type has two type parameters which describe what kind of data actor receives or produces. For
  example:
  <pre>

Shell (InputTag a) (OutputTag b)

  Also both input and output types have tags which describe how many messages data type produces and how
  this actor could be connected with others. It means that shell receives message(s) of type a and produce
  message(s) of type b. We support tags <code><a href="DNA.html#t:Val">Val</a></code>, <code><a href=
  "DNA.html#t:Grp">Grp</a></code> and <code><a href="DNA.html#t:Scatter">Scatter</a></code>.
</div>

<div class="subs instances">
  <p id="control.i:Shell" class="caption collapser" onclick="toggleSection('i:Shell')">Instances

  <div id="section.i:Shell" class="show">
    <table>
      <tr>
        <td class="src">Generic (<a href="DNA.html#t:Shell">Shell</a> a b)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Binary (<a href="DNA.html#t:Shell">Shell</a> a b)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Typeable (* -&gt; * -&gt; *) <a href="DNA.html#t:Shell">Shell</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><span class="keyword">type</span> Rep (<a href="DNA.html#t:Shell">Shell</a> a b)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

data Val a

<div class="doc">
  The actor receives/produces a single value, respectively.
</div>

<div class="subs instances">
  <p id="control.i:Val" class="caption collapser" onclick="toggleSection('i:Val')">Instances

  <div id="section.i:Val" class="show">
    <table>
      <tr>
        <td class="src">Typeable (* -&gt; *) <a href="DNA.html#t:Val">Val</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

data Grp a

<div class="doc">
  The actor receives/produces an unordered group of values.
</div>

<div class="subs instances">
  <p id="control.i:Grp" class="caption collapser" onclick="toggleSection('i:Grp')">Instances

  <div id="section.i:Grp" class="show">
    <table>
      <tr>
        <td class="src">Typeable (* -&gt; *) <a href="DNA.html#t:Grp">Grp</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

data Scatter a

<div class="doc">
  Only appears as an input tag. It means that we may want to scatter values to a set of running actors.
</div>

<div class="subs instances">
  <p id="control.i:Scatter" class="caption collapser" onclick="toggleSection('i:Scatter')">Instances

  <div id="section.i:Scatter" class="show">
    <table>
      <tr>
        <td class="src">Typeable (* -&gt; *) <a href="DNA.html#t:Scatter">Scatter</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

Connecting actors

Each actor must be connected to exactly one destination and consequently could only receive input from a single source. Trying to connect an actor twice will result in a runtime error. Functions sendParam, broadcast, distributeWork, connect, delay, and delayGroup count to this.

sendParam

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; a</td>

      <td class="doc">
        Parameter to send
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Shell">Shell</a> (<a href="DNA.html#t:Val">Val</a> a) b</td>

      <td class="doc">
        Actor to send parameter to
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> ()</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Send input parameter to an actor. Calling this function twice will result in runtime error.
  <pre>

do ... a <- startActor (N 1) (return $(mkStaticClosure 'someActor)) sendParam 100 ...

broadcast

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; a</td>

      <td class="doc">
        Parameter to send
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Shell">Shell</a> (<a href="DNA.html#t:Scatter">Scatter</a> a)
      b</td>

      <td class="doc">
        Group of actors to send parameter to
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> ()</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Send same value to all actors in group. Essentially same as <code><a href=
  "DNA.html#v:sendParam">sendParam</a></code> but works for group of actors.
  <pre>

do ... a <- startGroup (Frac 0.5) (NNodes 1) (return $(mkStaticClosure 'someActor)) broadcast 100 ...

distributeWork

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; a</td>

      <td class="doc">
        Parameter we want to send
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; (Int -&gt; a -&gt; [b])</td>

      <td class="doc">
        Function which distribute work between actors. First parameter is length of list to produce. It must
        generate list of required length.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Shell">Shell</a> (<a href="DNA.html#t:Scatter">Scatter</a> b)
      c</td>

      <td class="doc">
        Group of actors to send parameter to
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> ()</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Distribute work between group of actors. <code>distributeWork a f</code> will send values produced by
  function <code>f</code> to each actor in group. Computation is performed locally.
</div>

connect

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: (Serializable b, Typeable tag)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Shell">Shell</a> a (tag b)</td>

      <td class="doc">
        Actor which produce message(s)
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Shell">Shell</a> (tag b) c</td>

      <td class="doc">
        Actor which receives message(s)
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> ()</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Connect output of one actor to input of another actor. In example we connect output of group of actors to
  collect actor.
  <pre>

do ... a <- startGroupN (N 10) (NNodes 1) (return $(mkStaticClosure 'worker)) c &lt;- startCollector (N 1) (return $(mkStaticClosure 'collector)) connect a c ...

File channels.

data FileChan a

<div class="doc">
  File channel for communication between actors. It uses file system to store data and it's assumed that
  different actors have access to same file. It could be either placed on network FS or all actors are running
  on same computer.
</div>

<div class="subs instances">
  <p id="control.i:FileChan" class="caption collapser" onclick="toggleSection('i:FileChan')">Instances

  <div id="section.i:FileChan" class="show">
    <table>
      <tr>
        <td class="src">Show (<a href="DNA.html#t:FileChan">FileChan</a> a)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Generic (<a href="DNA.html#t:FileChan">FileChan</a> a)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Binary (<a href="DNA.html#t:FileChan">FileChan</a> a)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">Typeable (* -&gt; *) <a href="DNA.html#t:FileChan">FileChan</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><span class="keyword">type</span> Rep (<a href="DNA.html#t:FileChan">FileChan</a>
        a)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

createFileChan

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: <a href="DNA.html#t:Location">Location</a></td>

      <td class="doc">
        If <code><a href="DNA.html#v:Local">Local</a></code> will try to create channel in
        <code>/ramdisks</code> or <code>/tmp</code> if possible.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; String</td>

      <td class="doc">
        Channel name
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:FileChan">FileChan</a>
      a)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Allocates a new file channel for sharing data between actors.
</div>

Promises

data Promise a

<div class="doc">
  Result of an actor's computation. It could be generated by <code><a href=
  "DNA.html#v:delay">delay</a></code> and actual value extracted by <code><a href=
  "DNA.html#v:await">await</a></code>
  <pre>

do ... p <- delay someActor ... a <- await p

delay

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Location">Location</a></td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:Shell">Shell</a> a (<a href="DNA.html#t:Val">Val</a> b)</td>

      <td class="doc">
        Actor to obtain promise from.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Promise">Promise</a> b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Obtains a promise from a shell. This amounts to connecting the actor.
</div>

await

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Promise">Promise</a> a</td>

      <td class="doc">
        Promise to extract value from
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Extract value from <code><a href="DNA.html#t:Promise">Promise</a></code>, will block until value
  arrives
</div>

data Group a

<div class="doc">
  Like <code><a href="DNA.html#t:Promise">Promise</a></code>, but stands for the a group of results, as
  generated by an actor group. It could be used in likewise manner. In example below values produced by group
  of actors <code>grp</code> are summed in call to <code><a href="DNA.html#v:gather">gather</a></code>.
  <pre>

do ... p <- delayGroup grp ... a <- gather p (+) 0

delayGroup

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Shell">Shell</a> a (<a href="DNA.html#t:Grp">Grp</a> b)</td>

      <td class="doc">
        Actor to obtain promise from
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> (<a href="DNA.html#t:Group">Group</a> b)</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Like <code><a href="DNA.html#v:delay">delay</a></code>, but for a <code><a href=
  "DNA.html#t:Grp">Grp</a></code> of actors. Consequently, we produce a promise <code><a href=
  "DNA.html#t:Group">Group</a></code>.
</div>

gather

<div class="subs arguments">
  <p class="caption">Arguments

  <table>
    <tr>
      <td class="src">:: Serializable a</td>

      <td class="doc empty">&nbsp;</td>
    </tr>

    <tr>
      <td class="src">=&gt; <a href="DNA.html#t:Group">Group</a> a</td>

      <td class="doc">
        Promise to use.
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; (b -&gt; a -&gt; b)</td>

      <td class="doc">
        Stepper function (called for each message)
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; b</td>

      <td class="doc">
        Initial value
      </td>
    </tr>

    <tr>
      <td class="src">-&gt; <a href="DNA.html#t:DNA">DNA</a> b</td>

      <td class="doc empty">&nbsp;</td>
    </tr>
  </table>
</div>

<div class="doc">
  Obtains results from a group of actors by folding over the results. It behaves like <code><a href=
  "DNA.html#t:CollectActor">CollectActor</a></code> but all functions are evaluated locally. It will block
  until all messages are collected.
</div>

Reexports

class Monad m => MonadIO m where

<div class="subs methods">
  <p class="caption">Methods

  <p class="src"><a name="v:liftIO" class="def" id="v:liftIO">liftIO</a> :: IO a -&gt; m a
</div>

<div class="subs instances">
  <p id="control.i:MonadIO" class="caption collapser" onclick="toggleSection('i:MonadIO')">Instances

  <div id="section.i:MonadIO" class="show">
    <table>
      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> IO</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> Process</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> NC</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> <a href="DNA.html#t:Kern">Kern</a></td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (MaybeT m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (ListT m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (IdentityT m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> (MxAgent s)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (StateT s m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">(Error e, <a href="DNA.html#t:MonadIO">MonadIO</a> m) =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (ErrorT e m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">(Monoid w, <a href="DNA.html#t:MonadIO">MonadIO</a> m) =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (WriterT w m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">(Monoid w, <a href="DNA.html#t:MonadIO">MonadIO</a> m) =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (WriterT w m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (StateT s m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (ReaderT r m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (ExceptT e m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (ContT r m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src"><a href="DNA.html#t:MonadIO">MonadIO</a> m =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (ProgramT instr m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">(Monoid w, <a href="DNA.html#t:MonadIO">MonadIO</a> m) =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (RWST r w s m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>

      <tr>
        <td class="src">(Monoid w, <a href="DNA.html#t:MonadIO">MonadIO</a> m) =&gt; <a href=
        "DNA.html#t:MonadIO">MonadIO</a> (RWST r w s m)</td>

        <td class="doc empty">&nbsp;</td>
      </tr>
    </table>
  </div>
</div>

remotable :: [Name] -> Q [Dec]

mkStaticClosure :: Name -> Q Exp

Clone this wiki locally