Class Workflow

java.lang.Object
jline.lang.Model
jline.lang.workflow.Workflow
All Implemented Interfaces:
Serializable, Copyable

public class Workflow extends Model
A computational workflow that can be converted to a phase-type distribution.

A workflow whose precedence graph is series-parallel is reduced exactly, by recursive composition of the series-parallel tree, which handles arbitrary nesting (a fork inside a loop, a branch that is itself a fork-join). Graphs that are not series-parallel fall back to the block-based composition, which is a heuristic.

A loop repeats its body a geometric number of times of mean COUNT, the semantics of the POST_LOOP precedence of an activity graph, rather than COUNT times deterministically.

See Also:
  • Constructor Details

    • Workflow

      public Workflow(String name)
  • Method Details

    • addActivity

      public WorkflowActivity addActivity(String name, double meanServiceTime)
    • addActivity

      public WorkflowActivity addActivity(String name, Distribution hostDemand)
    • addPrecedence

      public void addPrecedence(ActivityPrecedence prec)
    • addPrecedence

      public void addPrecedence(ActivityPrecedence[] precs)
    • getActivity

      public WorkflowActivity getActivity(String name)
    • getActivities

      public List<WorkflowActivity> getActivities()
    • getPrecedences

      public List<ActivityPrecedence> getPrecedences()
    • validate

      public Pair<Boolean,String> validate()
    • toPH

      public Markovian toPH()
      Composed law of the workflow execution time.
      Returns:
      an APH, or a PH when the composed generator is cyclic, which a geometric loop over a multi-phase body makes it
    • refreshPH

      public Markovian refreshPH()
      Recompose the workflow law after a demand change, reusing every cached series-parallel node whose subtree is unchanged.
      Returns:
      the composed law
    • setActivityDemand

      public void setActivityDemand(String name, Distribution hostDemand)
      Change the host demand of one activity, marking only that leaf dirty.
      Parameters:
      name - activity name
      hostDemand - new host demand law
    • setActivityDemandMean

      public void setActivityDemandMean(String name, double meanValue)
      Change only the mean of one activity, preserving its shape and order.
      Parameters:
      name - activity name
      meanValue - new mean
    • invalidateTopology

      public void invalidateTopology()
      Discard the cached law and decomposition, after a change that can alter the shape of the series-parallel tree.
    • invalidateActivity

      public void invalidateActivity(int actIdx)
      Mark the law of one activity dirty, keeping the topology and every other cached block.
      Parameters:
      actIdx - activity index
    • rescaleActivityLeaf

      public void rescaleActivityLeaf(int actIdx, double factor)
      Time-scale a cached leaf in place, as T -> T*factor with alpha fixed.
      Parameters:
      actIdx - activity index
      factor - rate scaling factor
    • getSPTree

      public Workflow.SPTree getSPTree()
      Cached series-parallel decomposition, or null when the precedence graph is not series-parallel. Field execs carries the expected number of executions of each node per workflow execution.
      Returns:
      the decomposition
    • composeSerial

      public static Pair<Matrix,Matrix> composeSerial(Matrix alpha1, Matrix T1, Matrix alpha2, Matrix T2)
    • composeMixture

      public static Pair<Matrix,Matrix> composeMixture(List<Matrix> alphas, List<Matrix> Ts, double[] probs)
      Probabilistic mixture of several PH laws, which is aph_simplify pattern 3 generalised to any number of branches.
      Parameters:
      alphas - branch initial vectors
      Ts - branch subgenerators
      probs - branch probabilities
      Returns:
      the mixture law
    • composeLoopGeometric

      public static Pair<Matrix,Matrix> composeLoopGeometric(Matrix alpha, Matrix T, double count)
      Geometric repetition of a PH law, the POST_LOOP semantics of an activity graph: the number of executions of the body is geometric of mean COUNT.

      For COUNT>=1 the body runs at least once and repeats on absorption with probability P = 1-1/COUNT, so T_OUT = T + P/D*(-T*e)*ALPHA and ALPHA_OUT = ALPHA/D with D = 1-P*(1-ALPHA*e) the correction for an atom at zero in ALPHA. The order is that of the body, unlike the COUNT-fold convolution of composeRepeat, and the mean is COUNT times the mean of the body in both cases. For COUNT<1 the body is executed at most once, with probability COUNT.

      Parameters:
      alpha - body initial vector
      T - body subgenerator
      count - mean number of executions
      Returns:
      the repeated law
    • isAcyclicGenerator

      public static boolean isAcyclicGenerator(Matrix T)
      True when the phase graph of T has no cycle. A geometric loop over a body of two or more phases closes a cycle, so the composed law is a PH and not an APH.
      Parameters:
      T - subgenerator
      Returns:
      true when acyclic
    • composeParallel

      public static Pair<Matrix,Matrix> composeParallel(Matrix alpha1, Matrix T1, Matrix alpha2, Matrix T2)
    • composeRepeat

      public static Pair<Matrix,Matrix> composeRepeat(Matrix alpha, Matrix T, int count)
      Deterministic COUNT-fold convolution of a PH law. The POST_LOOP precedence of an activity graph is instead geometric; use composeLoopGeometric for it.
      Parameters:
      alpha - initial vector
      T - subgenerator
      count - number of executions
      Returns:
      the convolved law
    • Serial

      public static ActivityPrecedence[] Serial(WorkflowActivity... activities)
    • AndFork

      public static ActivityPrecedence AndFork(WorkflowActivity preAct, List<WorkflowActivity> postActs)
    • AndJoin

      public static ActivityPrecedence AndJoin(List<WorkflowActivity> preActs, WorkflowActivity postAct)
    • AndJoin

      public static ActivityPrecedence AndJoin(List<WorkflowActivity> preActs, WorkflowActivity postAct, int quorum)
      AND-join waiting for QUORUM of the branches. Workflow refuses a partial join, since it is not the maximum of the branches; the overload exists so that such a graph is rejected by name rather than mis-composed.
      Parameters:
      preActs - branch tail activities
      postAct - activity after the join
      quorum - number of branches to wait for
      Returns:
      the precedence
    • OrFork

      public static ActivityPrecedence OrFork(WorkflowActivity preAct, List<WorkflowActivity> postActs, double[] probs)
    • OrJoin

      public static ActivityPrecedence OrJoin(List<WorkflowActivity> preActs, WorkflowActivity postAct)
    • Loop

      public static ActivityPrecedence Loop(WorkflowActivity preAct, List<WorkflowActivity> postActs, double count)
    • fromWfCommons

      public static Workflow fromWfCommons(String jsonFile) throws IOException
      Load a workflow from a WfCommons JSON file.

      WfCommons (https://github.com/wfcommons/workflow-schema) is a standard format for representing scientific workflow traces.

      Parameters:
      jsonFile - Path to the WfCommons JSON file
      Returns:
      Workflow object
      Throws:
      IOException - If the file cannot be read
    • fromWfCommons

      public static Workflow fromWfCommons(String jsonFile, WfCommonsOptions options) throws IOException
      Load a workflow from a WfCommons JSON file with options.
      Parameters:
      jsonFile - Path to the WfCommons JSON file
      options - Loader options
      Returns:
      Workflow object
      Throws:
      IOException - If the file cannot be read