Safe Haskell | None |
---|
This adapter implements parallelism by via MPI; process 0 is the supervisor and the other processes are the workers. (This does mean that one process is used only for coordination, but this approach simplifies things and also ensures that worker requests and responses will be handled promptly.)
WARNING: Do *NOT* use the threaded runtime with this adapter as it has been designed with the assumption that the run-time is single-threaded. This was done because the MPI implementation might not support having multiple operating system threads (even if only one of them calls MPI functions), and anyway multiple operating system threads provide no benefit over lightweight Haskell threads in this case because the MPI scheduler will assign an MPI process to each CPU core so multiple threads will not result in better performance but rather in multiple processes fighting over the same CPU core, as well as the additional overhead of the threaded runtime compared to the non-threaded runtime.
- driver :: forall shared_configuration supervisor_configuration m n exploration_mode. (Serialize shared_configuration, Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => Driver IO shared_configuration supervisor_configuration m n exploration_mode
- driverMPI :: (Serialize shared_configuration, Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => Driver MPI shared_configuration supervisor_configuration m n exploration_mode
- data MPI α
- runMPI :: MPI α -> IO α
- getMPIInformation :: MPI (Bool, CInt)
- receiveBroadcastMessage :: Serialize α => MPI α
- sendBroadcastMessage :: Serialize α => α -> MPI ()
- sendMessage :: Serialize α => α -> CInt -> MPI ()
- tryReceiveMessage :: Serialize α => MPI (Maybe (CInt, α))
- data MPIControllerMonad exploration_mode α
- abort :: RequestQueueMonad m => m ()
- fork :: RequestQueueMonad m => m () -> m ThreadId
- getCurrentProgressAsync :: RequestQueueMonad m => (ProgressFor (ExplorationModeFor m) -> IO ()) -> m ()
- getCurrentProgress :: RequestQueueMonad m => m (ProgressFor (ExplorationModeFor m))
- getNumberOfWorkersAsync :: RequestQueueMonad m => (Int -> IO ()) -> m ()
- getNumberOfWorkers :: RequestQueueMonad m => m Int
- requestProgressUpdateAsync :: RequestQueueMonad m => (ProgressFor (ExplorationModeFor m) -> IO ()) -> m ()
- requestProgressUpdate :: RequestQueueMonad m => m (ProgressFor (ExplorationModeFor m))
- setWorkloadBufferSize :: RequestQueueMonad m => Int -> m ()
- data RunOutcome progress final_result = RunOutcome {
- runStatistics :: RunStatistics
- runTerminationReason :: TerminationReason progress final_result
- data RunStatistics = RunStatistics {
- runStartTime :: !UTCTime
- runEndTime :: !UTCTime
- runWallTime :: !NominalDiffTime
- runSupervisorOccupation :: !Float
- runSupervisorMonadOccupation :: !Float
- runNumberOfCalls :: !Int
- runAverageTimePerCall :: !Float
- runWorkerOccupation :: !Float
- runWorkerWaitTimes :: !(FunctionOfTimeStatistics NominalDiffTime)
- runStealWaitTimes :: !IndependentMeasurementsStatistics
- runWaitingWorkerStatistics :: !(FunctionOfTimeStatistics Int)
- runAvailableWorkloadStatistics :: !(FunctionOfTimeStatistics Int)
- runInstantaneousWorkloadRequestRateStatistics :: !(FunctionOfTimeStatistics Float)
- runInstantaneousWorkloadStealTimeStatistics :: !(FunctionOfTimeStatistics Float)
- data TerminationReason progress final_result
- runSupervisor :: forall exploration_mode. (Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => CInt -> ExplorationMode exploration_mode -> ProgressFor exploration_mode -> MPIControllerMonad exploration_mode () -> MPI (RunOutcomeFor exploration_mode)
- runWorker :: (Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => ExplorationMode exploration_mode -> Purity m n -> TreeT m (ResultFor exploration_mode) -> MPI ()
- runExplorer :: forall shared_configuration supervisor_configuration exploration_mode m n. (Serialize shared_configuration, Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => (shared_configuration -> ExplorationMode exploration_mode) -> Purity m n -> IO (shared_configuration, supervisor_configuration) -> (shared_configuration -> IO ()) -> (shared_configuration -> TreeT m (ResultFor exploration_mode)) -> (shared_configuration -> supervisor_configuration -> IO (ProgressFor exploration_mode)) -> (shared_configuration -> supervisor_configuration -> MPIControllerMonad exploration_mode ()) -> MPI (Maybe ((shared_configuration, supervisor_configuration), RunOutcomeFor exploration_mode))
Driver
driver :: forall shared_configuration supervisor_configuration m n exploration_mode. (Serialize shared_configuration, Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => Driver IO shared_configuration supervisor_configuration m n exploration_mode
This is the driver for the MPI adapter; process 0 acts as the supervisor and the other processes act as workers.
WARNING: Do *NOT* use the threaded runtime with this driver (or driverMPI
);
see the warning in the documentation for this module for more
details.
driverMPI :: (Serialize shared_configuration, Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) => Driver MPI shared_configuration supervisor_configuration m n exploration_mode
MPI
Monad and runner
data MPI α
This monad exists in order to ensure that the MPI system is initialized
before it is used and finalized when we are done; all MPI operations are
run within it, and it itself is run by using the runMPI
function.
Information and communication
getMPIInformation :: MPI (Bool, CInt)
Gets the total number of processes and whether this process is process 0.
receiveBroadcastMessage :: Serialize α => MPI α
Receves a message broadcast from process 0 (which must not be this process).
sendBroadcastMessage :: Serialize α => α -> MPI ()
Sends a message broadcast from this process, which must be process 0.
sendMessage :: Serialize α => α -> CInt -> MPI ()
Sends a message to another process.
tryReceiveMessage :: Serialize α => MPI (Maybe (CInt, α))
Receives a message (along with the sending process id) if one is waiting to be received; this function will not block if there are no messages available.
Controller
data MPIControllerMonad exploration_mode α
This is the monad in which the MPI controller will run.
Monad (MPIControllerMonad exploration_mode) | |
Functor (MPIControllerMonad exploration_mode) | |
Applicative (MPIControllerMonad exploration_mode) | |
MonadIO (MPIControllerMonad exploration_mode) | |
RequestQueueMonad (MPIControllerMonad exploration_mode) | |
HasExplorationMode (MPIControllerMonad exploration_mode) | |
MonadCatchIO (MPIControllerMonad exploration_mode) |
abort :: RequestQueueMonad m => m ()
Abort the supervisor.
fork :: RequestQueueMonad m => m () -> m ThreadId
Fork a new thread running in this monad; all controller threads are automnatically killed when the run is finished.
getCurrentProgressAsync :: RequestQueueMonad m => (ProgressFor (ExplorationModeFor m) -> IO ()) -> m ()
Request the current progress, invoking the given callback with the result; see getCurrentProgress
for the synchronous version.
getCurrentProgress :: RequestQueueMonad m => m (ProgressFor (ExplorationModeFor m))
Like getCurrentProgressAsync
, but blocks until the result is ready.
getNumberOfWorkersAsync :: RequestQueueMonad m => (Int -> IO ()) -> m ()
Request the number of workers, invoking the given callback with the result; see getNumberOfWorkers
for the synchronous version.
getNumberOfWorkers :: RequestQueueMonad m => m Int
Like getNumberOfWorkersAsync
, but blocks until the result is ready.
requestProgressUpdateAsync :: RequestQueueMonad m => (ProgressFor (ExplorationModeFor m) -> IO ()) -> m ()
Request that a global progress update be performed, invoking the given callback with the result; see requestProgressUpdate
for the synchronous version.
requestProgressUpdate :: RequestQueueMonad m => m (ProgressFor (ExplorationModeFor m))
Like requestProgressUpdateAsync
, but blocks until the progress update has completed.
setWorkloadBufferSize :: RequestQueueMonad m => Int -> m ()
Sets the size of the workload buffer; for more information, see setWorkloadBufferSize
(which links to the LogicGrowsOnTrees.Parallel.Common.Supervisor module).
Outcome types
data RunOutcome progress final_result
A type that represents the outcome of a run.
RunOutcome | |
|
(Eq progress, Eq final_result) => Eq (RunOutcome progress final_result) | |
(Show progress, Show final_result) => Show (RunOutcome progress final_result) |
data RunStatistics
Statistics gathered about the run.
RunStatistics | |
|
data TerminationReason progress final_result
A type that represents the reason why a run terminated.
Aborted progress | the run was aborted with the given progress |
Completed final_result | the run completed with the given final result |
Failure progress String | the run failed with the given progress for the given reason |
(Eq progress, Eq final_result) => Eq (TerminationReason progress final_result) | |
(Show progress, Show final_result) => Show (TerminationReason progress final_result) |
Generic runners
In this section the full functionality of this module is exposed in case one
does not want the restrictions of the driver interface. If you decide to go in
this direction, then you need to decide whether you want to manually handle
factors such as deciding whether a process is the supervisor or a worker and the
propagation of configuration information to the worker or whether you want this
to be done automatically; if you want full control then call runSupervisor
in the supervisor process --- which *must* be process 0! --- and call
runWorker
in the worker processes, otherwise call runExplorer
.
WARNING: Do *NOT* use the threaded runtime with this adapter; see the warning in the documentation for this module for more details.
:: forall exploration_mode . (Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) | |
=> CInt | the number of workers |
-> ExplorationMode exploration_mode | the exploration mode |
-> ProgressFor exploration_mode | the initial progress of the run |
-> MPIControllerMonad exploration_mode () | the controller of the supervisor |
-> MPI (RunOutcomeFor exploration_mode) | the outcome of the run |
This runs the supervisor; it must be called in process 0.
:: (Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) | |
=> ExplorationMode exploration_mode | the mode in to explore the tree |
-> Purity m n | the purity of the tree |
-> TreeT m (ResultFor exploration_mode) | the tree |
-> MPI () |
Runs a worker; it must be called in all processes other than process 0.
:: forall shared_configuration supervisor_configuration exploration_mode m n . (Serialize shared_configuration, Serialize (ProgressFor exploration_mode), Serialize (WorkerFinishedProgressFor exploration_mode)) | |
=> (shared_configuration -> ExplorationMode exploration_mode) | a function that constructs the exploration mode given the shared configuration |
-> Purity m n | the purity of the tree |
-> IO (shared_configuration, supervisor_configuration) | an action that gets the shared and supervisor-specific configuration information (run only on the supervisor) |
-> (shared_configuration -> IO ()) | an action that initializes the global state of the process given the shared configuration (run on both supervisor and worker processes) |
-> (shared_configuration -> TreeT m (ResultFor exploration_mode)) | a function that constructs the tree from the shared configuration (called only on the worker) |
-> (shared_configuration -> supervisor_configuration -> IO (ProgressFor exploration_mode)) | an action that gets the starting progress given the full configuration information (run only on the supervisor) |
-> (shared_configuration -> supervisor_configuration -> MPIControllerMonad exploration_mode ()) | a function that constructs the controller for the supervisor, which must at least set the number of workers to be non-zero (called only on the supervisor) |
-> MPI (Maybe ((shared_configuration, supervisor_configuration), RunOutcomeFor exploration_mode)) | if this process is the supervisor, then the outcome of the run as
well as the configuration information wrapped in |
Explores the given tree using MPI to achieve parallelism.
This function grants access to all of the functionality of this adapter, rather than having to go through the more restricted driver interface. The signature of this function is very complicated because it is meant to be used in all processes, supervisor and worker alike.