In [67]:
"""Optimal prioritizing of your tasks, in the sense of minimizing redundant memory footprint.
Idea is to take the longest graph path with most dependancies so that you don't mentally backtrack so often.
From the optimal paradigm of cpu worker allotment.
Simply make a dictionary where each key is a task name and the value is a list of other task names.
You can also add a time expected for each task if you want time estimations.
See the ``createDask`` doc.

Also, see my extended example for my own usage of it. 
In ``getOrderOfExecution`` try fiddling with different numConcurrentTasks, i.e. maybe you can/should multitask ;)
See the effect on total time to complete.
"""

import dask.array as da
import numpy as np
from dask.dot import dot_graph
from dask import delayed
from dask.threaded import get
from functools import partial
from time import sleep, clock
import dask



def requires(*args,time=0):
    '''time is in time units to do task'''
    #print("Spend: approx. {} days".format(time))
    sleep(time/100.)
    #print(args)
    return time

def input(time=0):
    '''time is in time units to do task'''
    #print("Spend: approx. {} days".format(time))
    sleep(time/100.)
    #print(args)
    return time

def createDask(depDict,timeDict={}):
    '''Input a dictionary of dependancies:
    e.g. if task_A requires task_B and task_C then add 
    depDict["task_A"] = ["task_B","task_C"]
    
    e.g. if task_A requires nothing then add
    depDict["task_A"] = []
    
    Try not to include loops like "task_A":["task_A","task_B"].
    Doing so will allow the graph to be constructed but an optimal order can not be determined.
       
    If a certain task will take a certain number of days then put this in the timeDict.
    e.g. if task_A will take 4 days add
    timeDict["task_A"] = 4
    
    e.g. if task_A is unknown add nothing (0 time)
    
    e.g. if task_A is a question then typically add nothing (0 time) because typically time is taken for 
    requirements for the question.
    
    This returns a dask object for further processing.    
    '''
    dsk = {}
    for key in depDict.keys():
        if key in timeDict.keys():
            time = timeDict[key]
        else:
            time = 0
        if len(depDict[key]) == 0:
            dsk[key] = (partial(input, time=time),)
        else:
            dsk[key] = (partial(requires, time=time),depDict[key])
            for dep in depDict[key]:
                if dep not in depDict.keys():
                    dsk[dep] = (partial(input, time=0),)
            
    return dsk

def getOrderOfExecution(dsk,finalTask, numConcurrentTasks=1):
    '''Get the optimal order to minimizing backtracking and memory footprint.
    numConcurrentTasks can be more than 1 if you think you can do two things at once.
    
    Put the final task you want to achieve (one of the keys in depDict)'''
    from dask.callbacks import Callback
    #from multiprocessing.pool import ThreadPool
    from dask.threaded import get
    #dask.set_options(pool=ThreadPool(numConcurrentTasks))
    class PrintKeys(Callback):
        def __init__(self,numWorkers):
            self.equivTime = None
            self.numWorkers = numWorkers
        def _start(self,dsk):
            print("Working with {} concurrent tasks".format(self.numWorkers))
            self.startTime = clock()
        def _pretask(self, key, dask, state):
            """Print the key of every task as it's started"""
            pass
        def _posttask(self,key,result,dsk,state,id):
            print("Do {} <- {}, approx. {} time units".format(repr(key),dsk[key][1:],repr(result)))
        def _finish(self,dsk,state,errored):
            self.endTime = clock()
            dt = (self.endTime - self.startTime)*100.
            print("Approximate time to complete: {} time units".format(dt))
            print("Equivalent single thread time: {} time units".format(dt*self.numWorkers))
            self.equivTime = dt*self.numWorkers
    with PrintKeys(numConcurrentTasks):
        get(dsk,finalTask,num_workers=numConcurrentTasks)
    
def getOptimalNumThreads(dsk,finalTask):
    threads = np.arange(9)+1#physical limit?
    from dask.callbacks import Callback
    #from multiprocessing.pool import ThreadPool
    from dask.threaded import get
    #dask.set_options(pool=ThreadPool(numConcurrentTasks))
    equivTime = 0
    class PrintKeys(Callback):
        def __init__(self,numWorkers):
            self.equivTime = None
            self.numWorkers = numWorkers
        def _start(self,dsk):
            self.startTime = clock()
        def _finish(self,dsk,state,errored):
            self.endTime = clock()
            dt = (self.endTime - self.startTime)*100.
            self.equivTime = dt*self.numWorkers
            equivTime = self.equivTime
    eqT = []
    eff = []
    optnum = 1
    for i in threads:
        with PrintKeys(i) as pk:
            get(dsk,finalTask,num_workers=i)
            eqT.append(pk.equivTime)
            print("Efficiency [{}]: {}".format(i,1-pk.equivTime/eqT[0]/i))
            ef = 1-pk.equivTime/eqT[0]/i
            eff.append(ef)
            if len(eff) > 1:
                if ef/eff[-2] < 1.1:
                    optnum = i - 1
                    break
    print("Optimal number of concurrent tasks (if possible): {}".format(optnum))
    return optnum
                    
            
            
    
    
def printGraph(dsk,outfile):
    '''output file without extension. Will make a pdf.
    Make sure you have two packages install:
    python-graphviz (the python bindings to graphviz), and graphviz (the system library)
    Try `pip install graphviz` for the bindings and `conda install graphviz` for the library.
    If you don't use conda, or conda library install fails then install from `http://www.graphviz.org/`
    '''
    dot_graph(dsk,filename=outfile,format='pdf')
    print("output image in {}.pdf".format(outfile))
    
    
if __name__ == '__main__':
    #Full example
    depDict = {'URSI Present':['Make Presentation',"Arrange the trip"],
           "Arrange the trip": ["funding","flights","accomadations"],
           "funding":[],
           "flights":[],
           "accomadations":[],
          'Make Presentation':['Show Works on Real','Survey ionosphere literature'],
          'Show Works on Real':['Does inversions show time coherence?','How well does it improve image?'],
          'How well does it improve image?':['Get phase screens','Apply a-term projections'],
          'Apply a-term projections':['Find an imager that can do a-term'],
          'Find an imager that can do a-term': ['Talk to people'],
          'Talk to people':[],
          'Does inversions show time coherence?':[ 'Get well Behaved Data','Trusted on Sim Data'],
          'Get well Behaved Data':['Calm Ionosphere','Trusted dTEC'],
          'Calm Ionosphere':["Jit's script"],
          'Trusted dTEC':['Is Robust to dTEC measurement uncertainty?','Validity checks'],
          'Validity checks':['Refractive scale consistent','Compare with literature','Compare with a priori'],
          'Trusted on Sim Data':['Stress Test All Internals','Make Robust','Quantify Reconstruction Resolution',"Get working on Sim Data"],
          'Quantify Reconstruction Resolution':['Information Completeness in FOV','Measured ne RMS Error'],
          'Measured ne RMS Error':['Optimal Antenna/facet selection','Choose required resolution'],
          'Optimal Antenna/facet selection':[ 'Bayesian optimization'],
          'Information Completeness in FOV':['Optimal Antenna/facet selection'],
          'Stress Test All Internals':['Stress Test Interpolation'],
          'Stress Test Interpolation':['Test RMS Error',"Write interpolation"],
          'Handle with proper padding':[],#'Stress Test Interpolation',
          'What happens near boundary':['Handle with proper padding'],
          'What effects of cell size':['Handle with proper padding'],
          'Choose required resolution':['What effects of cell size','Choose coherence Scale hyper parameter'],
          'Test RMS Error':['What happens near boundary','What effects of cell size'],
          'Make Robust':['Is Robust to dTEC measurement uncertainty?'],
          'Refractive scale consistent':["Jit's script"],
          "Jit's script":[],
          'Compare with literature': ['Survey ionosphere literature'],
          'Survey ionosphere literature':[],
          'Derive a priori ionosphere':['Survey ionosphere literature','Choose coherence Scale hyper parameter'],
          'Choose coherence Scale hyper parameter': ['Survey ionosphere literature','Bayesian optimization'],
          'Bayesian optimization':['Loop requires Trusted on Sim Data'],
          'Loop requires Trusted on Sim Data':[],
          'Compare with a priori':['Derive a priori ionosphere'],
          'Get phase screens':['Trusted on Sim Data'],
          'Is Robust to dTEC measurement uncertainty?':["quasi-Newton method","try different starting points"],
          "quasi-Newton method":["speed","limited memory","Gradient"],
          "try different starting points":["sampling turbulent realizations"],
          "sampling turbulent realizations":['Survey ionosphere literature','speed'],
          "limited memory":["BFGS"],
          "speed":["Parallelization","Optimization","Approximations"],
           "Approximations":[],
          "Parallelization":["Use dask"],
          "Use dask":[],
          "Optimization": ['Bayesian optimization'],
          "BFGS": ["Gradient","Preconditioning"],
           "Preconditioning":['Information Completeness in FOV'],
          "Get working on Sim Data":["quasi-Newton method",'Derive a priori ionosphere',"Forward equation"],
          "Forward equation":["Calc Rays",'framework to handle data'],
          "Calc Rays":["Fermats Principle"],
          "Fermats Principle":["Write interpolation"],
          "Write interpolation":[],
          "framework to handle data":["UVW frame","DataPack"],
          "DataPack":[],
          "UVW frame":[],
          "Gradient":["Forward equation"]}

    timeDict = {'URSI Present':0.5,
           "Arrange the trip": 4,
           "funding":7,
           "flights":2,
           "accomadations":3,
          'Make Presentation':7,
          'Show Works on Real':4,
          'How well does it improve image?':5,
          'Apply a-term projections':3,
          'Find an imager that can do a-term': 15,
          'Talk to people':0,
          'Does inversions show time coherence?':3,
          'Get well Behaved Data':0.5,
          'Calm Ionosphere':1,
          'Trusted dTEC':4,
          'Validity checks':2,
          'Trusted on Sim Data':2,
          'Quantify Reconstruction Resolution':5,
          'Measured ne RMS Error':2,
          'Optimal Antenna/facet selection':2,
          'Information Completeness in FOV':2,
          'Stress Test All Internals':2,
          'Stress Test Interpolation':5,
          'Handle with proper padding':1,#'Stress Test Interpolation',
          'What happens near boundary':3,
          'What effects of cell size':3,
          'Choose required resolution':1,
          'Test RMS Error':1,
          'Make Robust':7,
          'Refractive scale consistent':4,
          "Jit's script":5,
          'Compare with literature': 6,
          'Survey ionosphere literature':15,
          'Derive a priori ionosphere':7,
          'Choose coherence Scale hyper parameter': 5,
          'Bayesian optimization':0,
          'Loop requires Trusted on Sim Data':0,
          'Compare with a priori':2,
          'Get phase screens':3,
          'Is Robust to dTEC measurement uncertainty?':14,
          "quasi-Newton method":14,
          "try different starting points":2,
          "sampling turbulent realizations":2,
          "limited memory":0,
          "speed":0,
           "Approximations":7,
          "Parallelization":0,
          "Use dask":14,
          "Optimization": 7,
          "BFGS": 5,
           "Preconditioning":2,
          "Get working on Sim Data":5,
          "Forward equation":2,
          "Calc Rays":0,
          "Fermats Principle":0,
          "Write interpolation":2,
          "framework to handle data":4,
          "DataPack":0,
          "UVW frame":0,
          "Gradient":1}

    dsk = createDask(depDict,timeDict=timeDict)
    numTasks = getOptimalNumThreads(dsk,"URSI Present")
    getOrderOfExecution(dsk,"URSI Present",numConcurrentTasks=numTasks)
    printGraph(dsk,"URSI Roadmap")


Efficiency [1]: 0.0
Efficiency [2]: 0.5391167853989516
C:\Users\josh\Anaconda3\envs\compute\lib\site-packages\ipykernel_launcher.py:135: RuntimeWarning: divide by zero encountered in double_scalars
Efficiency [3]: 0.6569411067219979
Efficiency [4]: 0.7120465249659316
Optimal number of concurrent tasks (if possible): 3
Working with 3 concurrent tasks
Do 'Loop requires Trusted on Sim Data' <- (), approx. 0 time units
Do 'DataPack' <- (), approx. 0 time units
Do 'Bayesian optimization' <- (['Loop requires Trusted on Sim Data'],), approx. 0 time units
Do 'UVW frame' <- (), approx. 0 time units
Do 'Write interpolation' <- (), approx. 2 time units
Do 'Fermats Principle' <- (['Write interpolation'],), approx. 0 time units
Do 'Calc Rays' <- (['Fermats Principle'],), approx. 0 time units
Do 'Optimal Antenna/facet selection' <- (['Bayesian optimization'],), approx. 2 time units
Do 'framework to handle data' <- (['UVW frame', 'DataPack'],), approx. 4 time units
Do 'Information Completeness in FOV' <- (['Optimal Antenna/facet selection'],), approx. 2 time units
Do 'Forward equation' <- (['Calc Rays', 'framework to handle data'],), approx. 2 time units
Do 'Preconditioning' <- (['Information Completeness in FOV'],), approx. 2 time units
Do 'Gradient' <- (['Forward equation'],), approx. 1 time units
Do 'Optimization' <- (['Bayesian optimization'],), approx. 7 time units
Do 'BFGS' <- (['Gradient', 'Preconditioning'],), approx. 5 time units
Do 'limited memory' <- (['BFGS'],), approx. 0 time units
Do 'Approximations' <- (), approx. 7 time units
Do 'Handle with proper padding' <- (), approx. 1 time units
Do 'What effects of cell size' <- (['Handle with proper padding'],), approx. 3 time units
Do 'Use dask' <- (), approx. 14 time units
Do 'Parallelization' <- (['Use dask'],), approx. 0 time units
Do 'speed' <- (['Parallelization', 'Optimization', 'Approximations'],), approx. 0 time units
Do 'What happens near boundary' <- (['Handle with proper padding'],), approx. 3 time units
Do 'Test RMS Error' <- (['What happens near boundary', 'What effects of cell size'],), approx. 1 time units
Do 'Survey ionosphere literature' <- (), approx. 15 time units
Do 'Stress Test Interpolation' <- (['Test RMS Error', 'Write interpolation'],), approx. 5 time units
Do 'sampling turbulent realizations' <- (['Survey ionosphere literature', 'speed'],), approx. 2 time units
Do 'Stress Test All Internals' <- (['Stress Test Interpolation'],), approx. 2 time units
Do 'try different starting points' <- (['sampling turbulent realizations'],), approx. 2 time units
Do 'quasi-Newton method' <- (['speed', 'limited memory', 'Gradient'],), approx. 14 time units
Do 'Choose coherence Scale hyper parameter' <- (['Survey ionosphere literature', 'Bayesian optimization'],), approx. 5 time units
Do 'Compare with literature' <- (['Survey ionosphere literature'],), approx. 6 time units
Do 'Choose required resolution' <- (['What effects of cell size', 'Choose coherence Scale hyper parameter'],), approx. 1 time units
Do 'Measured ne RMS Error' <- (['Optimal Antenna/facet selection', 'Choose required resolution'],), approx. 2 time units
Do 'Derive a priori ionosphere' <- (['Survey ionosphere literature', 'Choose coherence Scale hyper parameter'],), approx. 7 time units
Do 'Quantify Reconstruction Resolution' <- (['Information Completeness in FOV', 'Measured ne RMS Error'],), approx. 5 time units
Do 'Is Robust to dTEC measurement uncertainty?' <- (['quasi-Newton method', 'try different starting points'],), approx. 14 time units
Do 'Compare with a priori' <- (['Derive a priori ionosphere'],), approx. 2 time units
Do 'Talk to people' <- (), approx. 0 time units
Do 'Get working on Sim Data' <- (['quasi-Newton method', 'Derive a priori ionosphere', 'Forward equation'],), approx. 5 time units
Do "Jit's script" <- (), approx. 5 time units
Do 'Make Robust' <- (['Is Robust to dTEC measurement uncertainty?'],), approx. 7 time units
Do 'Trusted on Sim Data' <- (['Stress Test All Internals', 'Make Robust', 'Quantify Reconstruction Resolution', 'Get working on Sim Data'],), approx. 2 time units
Do 'Refractive scale consistent' <- (["Jit's script"],), approx. 4 time units
Do 'Get phase screens' <- (['Trusted on Sim Data'],), approx. 3 time units
Do 'Validity checks' <- (['Refractive scale consistent', 'Compare with literature', 'Compare with a priori'],), approx. 2 time units
Do 'Calm Ionosphere' <- (["Jit's script"],), approx. 1 time units
Do 'Find an imager that can do a-term' <- (['Talk to people'],), approx. 15 time units
Do 'accomadations' <- (), approx. 3 time units
Do 'Trusted dTEC' <- (['Is Robust to dTEC measurement uncertainty?', 'Validity checks'],), approx. 4 time units
Do 'Get well Behaved Data' <- (['Calm Ionosphere', 'Trusted dTEC'],), approx. 0.5 time units
Do 'flights' <- (), approx. 2 time units
Do 'Apply a-term projections' <- (['Find an imager that can do a-term'],), approx. 3 time units
Do 'Does inversions show time coherence?' <- (['Get well Behaved Data', 'Trusted on Sim Data'],), approx. 3 time units
Do 'How well does it improve image?' <- (['Get phase screens', 'Apply a-term projections'],), approx. 5 time units
Do 'funding' <- (), approx. 7 time units
Do 'Show Works on Real' <- (['Does inversions show time coherence?', 'How well does it improve image?'],), approx. 4 time units
Do 'Arrange the trip' <- (['funding', 'flights', 'accomadations'],), approx. 4 time units
Do 'Make Presentation' <- (['Show Works on Real', 'Survey ionosphere literature'],), approx. 7 time units
Do 'URSI Present' <- (['Make Presentation', 'Arrange the trip'],), approx. 0.5 time units
Approximate time to complete: 89.14045927522238 time units
Equivalent single thread time: 267.42137782566715 time units
output image in URSI Roadmap.pdf

In [74]:
def deepflatten(nlist):
    out = []
    for i in nlist:
        if isinstance(i,list):
            out += deepflatten(i)
        else:
            out += [i]
    return out

def Fdot(n,v):
    if n == 0:
        return ['pull_F0',v]
    d = deepflatten([Fdot(n-1,v), 'pull_beta{}'.format(n-1), v, 'dm{}'.format(n-1), 'dgamma{}'.format(n-1),'v{}'.format(n-1)])
    return d

N=5
depDict = {}
for n in range(N):
    depDict['g{}'.format(n)] = ['pull_m{}'.format(n),'rays']
    depDict['gamma{}'.format(n)] = ['g{}'.format(n),'dobs','mprior','rays','pull_m{}'.format(n),'CdCt','Cm']
    depDict['phi{}'.format(n)] = ['F{}(gamma{})'.format(n,n)]
    depDict['F{}(gamma{})'.format(n,n)] = Fdot(n,'pull_gamma{}'.format(n))
    depDict['beta{}'.format(n)] = ['dgamma{}'.format(n),'dm{}'.format(n),'pull_gamma{}'.format(n)]
    depDict['dgamma{}'.format(n)] = ['pull_gamma{}'.format(n+1),'pull_gamma{}'.format(n)]
    depDict['dm{}'.format(n)] = ['pull_m{}'.format(n+1),'pull_m{}'.format(n)]
    depDict['v{}'.format(n)] = ['pull_F{}(gamma{})'.format(n,n+1),'pull_F{}(gamma{})'.format(n,n)]
    depDict['F{}(gamma{})'.format(n,n+1)] = Fdot(n,'pull_gamma{}'.format(n+1))
    depDict['ep{}'.format(n)] = ['pull_phi{}'.format(n),'pull_m{}'.format(n),'rays']
    depDict['m{}'.format(n+1)] = ['pull_m{}'.format(n),'ep{}'.format(n),'pull_phi{}'.format(n)]
depDict['m0'] = ['mprior']
depDict_pull = {}
for key in depDict.keys():
    #depDict_pull['store_{}'.format(key)] = [key]
    #dep_pull = []
    for dep in depDict[key]:
        #dep_pull.append("pull_{}".format(dep))
        if "pull" in dep:
            depDict_pull[dep] = [dep.replace('pull','store')]
            depDict_pull[dep.replace('pull','store')] = [dep.replace('pull_','')]
    #depDict_pull[dep] = dep_pull

depDict.update(depDict_pull)

timeDict = {}
for key in depDict.keys():
    if "store" in key or "pull" in key:
        timeDict[key] = 0
    else:
        timeDict[key] = 10
        
print(depDict)
dsk = createDask(depDict,timeDict=timeDict)

#numTasks = getOptimalNumThreads(dsk,"m2")
getOrderOfExecution(dsk,"pull_m5",numConcurrentTasks=1)
printGraph(dsk,"BFGS map")


{'dgamma2': ['pull_gamma3', 'pull_gamma2'], 'beta0': ['dgamma0', 'dm0', 'pull_gamma0'], 'store_m2': ['m2'], 'pull_F4(gamma5)': ['store_F4(gamma5)'], 'store_gamma1': ['gamma1'], 'pull_F3(gamma3)': ['store_F3(gamma3)'], 'phi4': ['F4(gamma4)'], 'pull_gamma4': ['store_gamma4'], 'pull_m2': ['store_m2'], 'F3(gamma3)': ['pull_F0', 'pull_gamma3', 'pull_beta0', 'pull_gamma3', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma3', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma3', 'dm2', 'dgamma2', 'v2'], 'pull_F2(gamma2)': ['store_F2(gamma2)'], 'gamma0': ['g0', 'dobs', 'mprior', 'rays', 'pull_m0', 'CdCt', 'Cm'], 'store_phi1': ['phi1'], 'dm4': ['pull_m5', 'pull_m4'], 'phi1': ['F1(gamma1)'], 'store_phi4': ['phi4'], 'store_F1(gamma1)': ['F1(gamma1)'], 'm4': ['pull_m3', 'ep3', 'pull_phi3'], 'pull_gamma1': ['store_gamma1'], 'pull_beta2': ['store_beta2'], 'pull_beta0': ['store_beta0'], 'v3': ['pull_F3(gamma4)', 'pull_F3(gamma3)'], 'store_F0': ['F0'], 'store_beta1': ['beta1'], 'F4(gamma4)': ['pull_F0', 'pull_gamma4', 'pull_beta0', 'pull_gamma4', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma4', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma4', 'dm2', 'dgamma2', 'v2', 'pull_beta3', 'pull_gamma4', 'dm3', 'dgamma3', 'v3'], 'store_m0': ['m0'], 'store_phi2': ['phi2'], 'pull_gamma3': ['store_gamma3'], 'pull_gamma0': ['store_gamma0'], 'store_m1': ['m1'], 'm0': ['mprior'], 'm1': ['pull_m0', 'ep0', 'pull_phi0'], 'store_phi3': ['phi3'], 'pull_phi0': ['store_phi0'], 'g0': ['pull_m0', 'rays'], 'ep3': ['pull_phi3', 'pull_m3', 'rays'], 'store_beta3': ['beta3'], 'g2': ['pull_m2', 'rays'], 'pull_phi2': ['store_phi2'], 'store_gamma0': ['gamma0'], 'F1(gamma2)': ['pull_F0', 'pull_gamma2', 'pull_beta0', 'pull_gamma2', 'dm0', 'dgamma0', 'v0'], 'pull_F4(gamma4)': ['store_F4(gamma4)'], 'ep0': ['pull_phi0', 'pull_m0', 'rays'], 'dm0': ['pull_m1', 'pull_m0'], 'pull_gamma5': ['store_gamma5'], 'store_F4(gamma4)': ['F4(gamma4)'], 'dm3': ['pull_m4', 'pull_m3'], 'store_m3': ['m3'], 'phi2': ['F2(gamma2)'], 'm5': ['pull_m4', 'ep4', 'pull_phi4'], 'g3': ['pull_m3', 'rays'], 'store_gamma4': ['gamma4'], 'F1(gamma1)': ['pull_F0', 'pull_gamma1', 'pull_beta0', 'pull_gamma1', 'dm0', 'dgamma0', 'v0'], 'store_F2(gamma2)': ['F2(gamma2)'], 'store_beta0': ['beta0'], 'pull_phi4': ['store_phi4'], 'F2(gamma2)': ['pull_F0', 'pull_gamma2', 'pull_beta0', 'pull_gamma2', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma2', 'dm1', 'dgamma1', 'v1'], 'store_gamma2': ['gamma2'], 'pull_F0(gamma0)': ['store_F0(gamma0)'], 'm3': ['pull_m2', 'ep2', 'pull_phi2'], 'v1': ['pull_F1(gamma2)', 'pull_F1(gamma1)'], 'store_F1(gamma2)': ['F1(gamma2)'], 'store_m4': ['m4'], 'pull_gamma2': ['store_gamma2'], 'gamma2': ['g2', 'dobs', 'mprior', 'rays', 'pull_m2', 'CdCt', 'Cm'], 'v0': ['pull_F0(gamma1)', 'pull_F0(gamma0)'], 'pull_m3': ['store_m3'], 'F3(gamma4)': ['pull_F0', 'pull_gamma4', 'pull_beta0', 'pull_gamma4', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma4', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma4', 'dm2', 'dgamma2', 'v2'], 'g1': ['pull_m1', 'rays'], 'store_F3(gamma4)': ['F3(gamma4)'], 'pull_beta1': ['store_beta1'], 'store_F3(gamma3)': ['F3(gamma3)'], 'ep4': ['pull_phi4', 'pull_m4', 'rays'], 'store_F0(gamma0)': ['F0(gamma0)'], 'F2(gamma3)': ['pull_F0', 'pull_gamma3', 'pull_beta0', 'pull_gamma3', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma3', 'dm1', 'dgamma1', 'v1'], 'store_F4(gamma5)': ['F4(gamma5)'], 'gamma1': ['g1', 'dobs', 'mprior', 'rays', 'pull_m1', 'CdCt', 'Cm'], 'dgamma1': ['pull_gamma2', 'pull_gamma1'], 'store_gamma3': ['gamma3'], 'ep2': ['pull_phi2', 'pull_m2', 'rays'], 'v4': ['pull_F4(gamma5)', 'pull_F4(gamma4)'], 'F0(gamma0)': ['pull_F0', 'pull_gamma0'], 'pull_beta3': ['store_beta3'], 'beta3': ['dgamma3', 'dm3', 'pull_gamma3'], 'store_F2(gamma3)': ['F2(gamma3)'], 'pull_F0(gamma1)': ['store_F0(gamma1)'], 'phi3': ['F3(gamma3)'], 'beta2': ['dgamma2', 'dm2', 'pull_gamma2'], 'dm1': ['pull_m2', 'pull_m1'], 'store_m5': ['m5'], 'beta4': ['dgamma4', 'dm4', 'pull_gamma4'], 'dm2': ['pull_m3', 'pull_m2'], 'pull_F3(gamma4)': ['store_F3(gamma4)'], 'store_phi0': ['phi0'], 'm2': ['pull_m1', 'ep1', 'pull_phi1'], 'pull_F1(gamma2)': ['store_F1(gamma2)'], 'pull_m1': ['store_m1'], 'pull_F0': ['store_F0'], 'dgamma4': ['pull_gamma5', 'pull_gamma4'], 'gamma4': ['g4', 'dobs', 'mprior', 'rays', 'pull_m4', 'CdCt', 'Cm'], 'pull_phi3': ['store_phi3'], 'pull_F1(gamma1)': ['store_F1(gamma1)'], 'F0(gamma1)': ['pull_F0', 'pull_gamma1'], 'phi0': ['F0(gamma0)'], 'gamma3': ['g3', 'dobs', 'mprior', 'rays', 'pull_m3', 'CdCt', 'Cm'], 'pull_m5': ['store_m5'], 'F4(gamma5)': ['pull_F0', 'pull_gamma5', 'pull_beta0', 'pull_gamma5', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma5', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma5', 'dm2', 'dgamma2', 'v2', 'pull_beta3', 'pull_gamma5', 'dm3', 'dgamma3', 'v3'], 'pull_m0': ['store_m0'], 'beta1': ['dgamma1', 'dm1', 'pull_gamma1'], 'pull_phi1': ['store_phi1'], 'pull_m4': ['store_m4'], 'store_beta2': ['beta2'], 'g4': ['pull_m4', 'rays'], 'dgamma0': ['pull_gamma1', 'pull_gamma0'], 'store_gamma5': ['gamma5'], 'dgamma3': ['pull_gamma4', 'pull_gamma3'], 'store_F0(gamma1)': ['F0(gamma1)'], 'v2': ['pull_F2(gamma3)', 'pull_F2(gamma2)'], 'ep1': ['pull_phi1', 'pull_m1', 'rays'], 'pull_F2(gamma3)': ['store_F2(gamma3)']}
Working with 1 concurrent tasks
Do 'mprior' <- (), approx. 0 time units
Do 'm0' <- (['mprior'],), approx. 10 time units
Do 'store_m0' <- (['m0'],), approx. 0 time units
Do 'pull_m0' <- (['store_m0'],), approx. 0 time units
Do 'rays' <- (), approx. 0 time units
Do 'g0' <- (['pull_m0', 'rays'],), approx. 10 time units
Do 'CdCt' <- (), approx. 0 time units
Do 'Cm' <- (), approx. 0 time units
Do 'dobs' <- (), approx. 0 time units
Do 'gamma0' <- (['g0', 'dobs', 'mprior', 'rays', 'pull_m0', 'CdCt', 'Cm'],), approx. 10 time units
Do 'store_gamma0' <- (['gamma0'],), approx. 0 time units
Do 'pull_gamma0' <- (['store_gamma0'],), approx. 0 time units
Do 'F0' <- (), approx. 0 time units
Do 'store_F0' <- (['F0'],), approx. 0 time units
Do 'pull_F0' <- (['store_F0'],), approx. 0 time units
Do 'F0(gamma0)' <- (['pull_F0', 'pull_gamma0'],), approx. 10 time units
Do 'phi0' <- (['F0(gamma0)'],), approx. 10 time units
Do 'store_phi0' <- (['phi0'],), approx. 0 time units
Do 'pull_phi0' <- (['store_phi0'],), approx. 0 time units
Do 'ep0' <- (['pull_phi0', 'pull_m0', 'rays'],), approx. 10 time units
Do 'm1' <- (['pull_m0', 'ep0', 'pull_phi0'],), approx. 10 time units
Do 'store_m1' <- (['m1'],), approx. 0 time units
Do 'pull_m1' <- (['store_m1'],), approx. 0 time units
Do 'g1' <- (['pull_m1', 'rays'],), approx. 10 time units
Do 'gamma1' <- (['g1', 'dobs', 'mprior', 'rays', 'pull_m1', 'CdCt', 'Cm'],), approx. 10 time units
Do 'store_gamma1' <- (['gamma1'],), approx. 0 time units
Do 'pull_gamma1' <- (['store_gamma1'],), approx. 0 time units
Do 'dgamma0' <- (['pull_gamma1', 'pull_gamma0'],), approx. 10 time units
Do 'F0(gamma1)' <- (['pull_F0', 'pull_gamma1'],), approx. 10 time units
Do 'store_F0(gamma1)' <- (['F0(gamma1)'],), approx. 0 time units
Do 'pull_F0(gamma1)' <- (['store_F0(gamma1)'],), approx. 0 time units
Do 'dm0' <- (['pull_m1', 'pull_m0'],), approx. 10 time units
Do 'beta0' <- (['dgamma0', 'dm0', 'pull_gamma0'],), approx. 10 time units
Do 'store_beta0' <- (['beta0'],), approx. 0 time units
Do 'pull_beta0' <- (['store_beta0'],), approx. 0 time units
Do 'store_F0(gamma0)' <- (['F0(gamma0)'],), approx. 0 time units
Do 'pull_F0(gamma0)' <- (['store_F0(gamma0)'],), approx. 0 time units
Do 'v0' <- (['pull_F0(gamma1)', 'pull_F0(gamma0)'],), approx. 10 time units
Do 'F1(gamma1)' <- (['pull_F0', 'pull_gamma1', 'pull_beta0', 'pull_gamma1', 'dm0', 'dgamma0', 'v0'],), approx. 10 time units
Do 'phi1' <- (['F1(gamma1)'],), approx. 10 time units
Do 'store_phi1' <- (['phi1'],), approx. 0 time units
Do 'pull_phi1' <- (['store_phi1'],), approx. 0 time units
Do 'ep1' <- (['pull_phi1', 'pull_m1', 'rays'],), approx. 10 time units
Do 'm2' <- (['pull_m1', 'ep1', 'pull_phi1'],), approx. 10 time units
Do 'store_m2' <- (['m2'],), approx. 0 time units
Do 'pull_m2' <- (['store_m2'],), approx. 0 time units
Do 'g2' <- (['pull_m2', 'rays'],), approx. 10 time units
Do 'gamma2' <- (['g2', 'dobs', 'mprior', 'rays', 'pull_m2', 'CdCt', 'Cm'],), approx. 10 time units
Do 'store_gamma2' <- (['gamma2'],), approx. 0 time units
Do 'pull_gamma2' <- (['store_gamma2'],), approx. 0 time units
Do 'dgamma1' <- (['pull_gamma2', 'pull_gamma1'],), approx. 10 time units
Do 'F1(gamma2)' <- (['pull_F0', 'pull_gamma2', 'pull_beta0', 'pull_gamma2', 'dm0', 'dgamma0', 'v0'],), approx. 10 time units
Do 'store_F1(gamma2)' <- (['F1(gamma2)'],), approx. 0 time units
Do 'pull_F1(gamma2)' <- (['store_F1(gamma2)'],), approx. 0 time units
Do 'dm1' <- (['pull_m2', 'pull_m1'],), approx. 10 time units
Do 'beta1' <- (['dgamma1', 'dm1', 'pull_gamma1'],), approx. 10 time units
Do 'store_beta1' <- (['beta1'],), approx. 0 time units
Do 'pull_beta1' <- (['store_beta1'],), approx. 0 time units
Do 'store_F1(gamma1)' <- (['F1(gamma1)'],), approx. 0 time units
Do 'pull_F1(gamma1)' <- (['store_F1(gamma1)'],), approx. 0 time units
Do 'v1' <- (['pull_F1(gamma2)', 'pull_F1(gamma1)'],), approx. 10 time units
Do 'F2(gamma2)' <- (['pull_F0', 'pull_gamma2', 'pull_beta0', 'pull_gamma2', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma2', 'dm1', 'dgamma1', 'v1'],), approx. 10 time units
Do 'phi2' <- (['F2(gamma2)'],), approx. 10 time units
Do 'store_phi2' <- (['phi2'],), approx. 0 time units
Do 'pull_phi2' <- (['store_phi2'],), approx. 0 time units
Do 'ep2' <- (['pull_phi2', 'pull_m2', 'rays'],), approx. 10 time units
Do 'm3' <- (['pull_m2', 'ep2', 'pull_phi2'],), approx. 10 time units
Do 'store_m3' <- (['m3'],), approx. 0 time units
Do 'pull_m3' <- (['store_m3'],), approx. 0 time units
Do 'g3' <- (['pull_m3', 'rays'],), approx. 10 time units
Do 'gamma3' <- (['g3', 'dobs', 'mprior', 'rays', 'pull_m3', 'CdCt', 'Cm'],), approx. 10 time units
Do 'store_gamma3' <- (['gamma3'],), approx. 0 time units
Do 'pull_gamma3' <- (['store_gamma3'],), approx. 0 time units
Do 'dgamma2' <- (['pull_gamma3', 'pull_gamma2'],), approx. 10 time units
Do 'F2(gamma3)' <- (['pull_F0', 'pull_gamma3', 'pull_beta0', 'pull_gamma3', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma3', 'dm1', 'dgamma1', 'v1'],), approx. 10 time units
Do 'store_F2(gamma3)' <- (['F2(gamma3)'],), approx. 0 time units
Do 'pull_F2(gamma3)' <- (['store_F2(gamma3)'],), approx. 0 time units
Do 'dm2' <- (['pull_m3', 'pull_m2'],), approx. 10 time units
Do 'beta2' <- (['dgamma2', 'dm2', 'pull_gamma2'],), approx. 10 time units
Do 'store_beta2' <- (['beta2'],), approx. 0 time units
Do 'pull_beta2' <- (['store_beta2'],), approx. 0 time units
Do 'store_F2(gamma2)' <- (['F2(gamma2)'],), approx. 0 time units
Do 'pull_F2(gamma2)' <- (['store_F2(gamma2)'],), approx. 0 time units
Do 'v2' <- (['pull_F2(gamma3)', 'pull_F2(gamma2)'],), approx. 10 time units
Do 'F3(gamma3)' <- (['pull_F0', 'pull_gamma3', 'pull_beta0', 'pull_gamma3', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma3', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma3', 'dm2', 'dgamma2', 'v2'],), approx. 10 time units
Do 'phi3' <- (['F3(gamma3)'],), approx. 10 time units
Do 'store_phi3' <- (['phi3'],), approx. 0 time units
Do 'pull_phi3' <- (['store_phi3'],), approx. 0 time units
Do 'ep3' <- (['pull_phi3', 'pull_m3', 'rays'],), approx. 10 time units
Do 'm4' <- (['pull_m3', 'ep3', 'pull_phi3'],), approx. 10 time units
Do 'store_m4' <- (['m4'],), approx. 0 time units
Do 'pull_m4' <- (['store_m4'],), approx. 0 time units
Do 'g4' <- (['pull_m4', 'rays'],), approx. 10 time units
Do 'gamma4' <- (['g4', 'dobs', 'mprior', 'rays', 'pull_m4', 'CdCt', 'Cm'],), approx. 10 time units
Do 'store_gamma4' <- (['gamma4'],), approx. 0 time units
Do 'pull_gamma4' <- (['store_gamma4'],), approx. 0 time units
Do 'dgamma3' <- (['pull_gamma4', 'pull_gamma3'],), approx. 10 time units
Do 'F3(gamma4)' <- (['pull_F0', 'pull_gamma4', 'pull_beta0', 'pull_gamma4', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma4', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma4', 'dm2', 'dgamma2', 'v2'],), approx. 10 time units
Do 'store_F3(gamma4)' <- (['F3(gamma4)'],), approx. 0 time units
Do 'pull_F3(gamma4)' <- (['store_F3(gamma4)'],), approx. 0 time units
Do 'dm3' <- (['pull_m4', 'pull_m3'],), approx. 10 time units
Do 'beta3' <- (['dgamma3', 'dm3', 'pull_gamma3'],), approx. 10 time units
Do 'store_beta3' <- (['beta3'],), approx. 0 time units
Do 'pull_beta3' <- (['store_beta3'],), approx. 0 time units
Do 'store_F3(gamma3)' <- (['F3(gamma3)'],), approx. 0 time units
Do 'pull_F3(gamma3)' <- (['store_F3(gamma3)'],), approx. 0 time units
Do 'v3' <- (['pull_F3(gamma4)', 'pull_F3(gamma3)'],), approx. 10 time units
Do 'F4(gamma4)' <- (['pull_F0', 'pull_gamma4', 'pull_beta0', 'pull_gamma4', 'dm0', 'dgamma0', 'v0', 'pull_beta1', 'pull_gamma4', 'dm1', 'dgamma1', 'v1', 'pull_beta2', 'pull_gamma4', 'dm2', 'dgamma2', 'v2', 'pull_beta3', 'pull_gamma4', 'dm3', 'dgamma3', 'v3'],), approx. 10 time units
Do 'phi4' <- (['F4(gamma4)'],), approx. 10 time units
Do 'store_phi4' <- (['phi4'],), approx. 0 time units
Do 'pull_phi4' <- (['store_phi4'],), approx. 0 time units
Do 'ep4' <- (['pull_phi4', 'pull_m4', 'rays'],), approx. 10 time units
Do 'm5' <- (['pull_m4', 'ep4', 'pull_phi4'],), approx. 10 time units
Do 'store_m5' <- (['m5'],), approx. 0 time units
Do 'pull_m5' <- (['store_m5'],), approx. 0 time units
Approximate time to complete: 538.8372534886003 time units
Equivalent single thread time: 538.8372534886003 time units
output image in BFGS map.pdf