runActorManyRanks :: Actor a b -> Process ()
runActorManyRanks (Actor action) = do
    -- Obtain parameters
    (acp,ParamActor parent _ grp) <- expect
    -- Create channels for communication
    (chSendParam,chRecvParam) <- newChan
    (chSendDst,  chRecvDst  ) <- newChan
    (chSendRnk,  chRecvRnk  ) <- newChan
    -- Send shell process back
    let shell = Shell (SingleActor acp)
                      (RecvVal chSendParam)
                      (SendVal chSendDst  )
    -- Communicate back to ACP
    send parent (acp, chSendRnk, wrapMessage shell)
    a   <- receiveChan chRecvParam
    -- Now we can start execution and send back data
    dst <- receiveChan chRecvDst
    let loop = do
            send parent (acp,chSendRnk)
            mrnk <- receiveChan chRecvRnk
            case mrnk of
                Nothing  -> return ()
                Just rnk -> do !b  <- runDNA acp rnk grp (action a)
                               sendToDest dst b
                               send parent (acp,DoneTask)
                               loop
    loop

-- | Start execution of collector actor
runActorManyRanks :: Actor a b -> Process ()
runActorManyRanks (Actor action) = do
    -- Obtain parameters
    (acp,ParamActor parent _ grp) <- expect
    -- Create channels for communication
    (chSendParam,chRecvParam) <- newChan
    (chSendDst,  chRecvDst  ) <- newChan
    (chSendRnk,  chRecvRnk  ) <- newChan
    -- Send shell process back
    let shell = Shell (SingleActor acp)
                      (RecvVal chSendParam)
                      (SendVal chSendDst  )
    -- Communicate back to ACP
    send parent (acp, chSendRnk, wrapMessage shell)
    a   <- receiveChan chRecvParam
    -- Now we can start execution and send back data
    dst <- receiveChan chRecvDst
    let loop = do
            send parent (acp,chSendRnk)
            mrnk <- receiveChan chRecvRnk
            case mrnk of
                Nothing  -> return ()
                Just rnk -> do !b  <- runDNA acp rnk grp (action a)
                               sendToDest dst b
                               send parent (acp,DoneTask)
                               loop
    loop

-- | Start execution of collector actor
runActorManyRanks (Actor action) = do
    -- Obtain parameters
    (acp,ParamActor parent _ grp) <- expect
    -- Create channels for communication
    (chSendParam,chRecvParam) <- newChan
    (chSendDst,  chRecvDst  ) <- newChan
    (chSendRnk,  chRecvRnk  ) <- newChan
    -- Send shell process back
    let shell = Shell (SingleActor acp)
                      (RecvVal chSendParam)
                      (SendVal chSendDst  )
    -- Communicate back to ACP
    send parent (acp, chSendRnk, wrapMessage shell)
    a   <- receiveChan chRecvParam
    -- Now we can start execution and send back data
    dst <- receiveChan chRecvDst
    let loop = do
            send parent (acp,chSendRnk)
            mrnk <- receiveChan chRecvRnk
            case mrnk of
                Nothing  -> return ()
                Just rnk -> do !b  <- runDNA acp rnk grp (action a)
                               sendToDest dst b
                               send parent (acp,DoneTask)
                               loop
    loop

-- | Start execution of collector actor