U
    d                     @   s\   d dl mZmZ d dlmZmZmZmZ G dd deZ	G dd deZ
G dd de
Zd	S )
    )core	workspace)ClusterTask	TaskGroupWorkspaceTypec                   @   s   e Zd ZdZdd ZdS )CompiledRunnablez? Wrapper for compiled runnable returned from session.compile() c                 C   s   || _ || _d S N)objsession_class)selfr
   r    r   9/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/session.py__init__   s    zCompiledRunnable.__init__N)__name__
__module____qualname____doc__r   r   r   r   r   r      s   r   c                   @   sz   e Zd ZdZi Zdd Zdd ZedddZdd	d
Z	dd Z
dd Zdd ZedddZdd Zdd Zdd ZdS )SessionaD  
    Allows to run Nets, ExecutionSteps, Plans, Tasks and TaskGroups.
    A session can potentially run in multiple nodes concurrently.


    Example:
        from core import Net
        from caffe2.python.task import Task, TaskGroup, WorkspaceType

        net = Net('test1')
        net.Add([net.Const(1), net.Const(2)])

        net2 = net.Clone()
        step = core.execution_step('step1', [net2])

        with TaskGroup(WorkspaceType.GLOBAL) as init_tg:
            with Node('node1'):
                n1setup = net.Net('n1setup')
                n1msg = n1setup.Const('Hello from node 1.')
                Task(step=n1setup)

        with TaskGroup() as private_tg:
            with Node('node1'):
                n1 = net.Net('n1')
                n1.Print(n1msg, 0)
                Task(step=n1)
            with Node('node2'):
                n2 = net.Net('n2')
                n2.Print(n2.Const('Hello from node 2.'), 0)
                Task(step=n2)

        session = LocalSession()
        session.run(net)
        session.run(step)
        session.run(init_tg)
        session.run(private_tg)


    Global Workspace:
        At the beginning of the session, a global workspace is created and kept
        alive for the duration of the session.


    Private Workspace:
        Tasks can be run either directly on the global workspace, or they can
        instantiate a private child workspace that is released after each run.

    Blob visibility:
        Tasks running in different nodes in parallel will always run under
        different workspaces, so it must be assumed that they won't be able to
        access each other's blobs. Tasks running on the same node will follow
        Workspace hierarchy rules: tasks running on separate private workspaces
        will only be able to share blobs defined on a common parent Workspace.
    c                 C   s
   d| _ d S )NT_openr   r   r   r   r   N   s    zSession.__init__c                 C   s   | j S r	   r   r   r   r   r   is_openQ   s    zSession.is_openNc                 C   sx  t |tr2| |jks.tdd| j|jjf  |S || jkrF| j| S t |tr|r| r~| |kstd|| n||_	|}n|d krt
j}t|d}t |tr|| nt |tjr|t|d nt |tjr:t| dkstt| dkr$|t| d d n|t| d ntd|}|t|d t| ||| d	}|| j|< |S )
Nz2Runnable was compiled for different session type. zNeed: %s, got: %szRequire {} but already have {})workspace_type)stepr      runnable)r   )
isinstancer   r   AssertionErrorr   _compiled_cacher   r   formatZ_workspace_typer   GLOBALr   addr   ZExecutionStepPlanlenZStepsZexecution_step_compile_task_group)clsr   r   setup_net_listtgr   compiledr   r   r   compileT   sV    
 


 


 
zSession.compilec                 C   s:   |   std|dk	s td| | |||j dS )a  Run the given runnable.

        Args:
            runnable: Object recognized by the Session. Currently, we support
                TaskGroup, Task, Plan, ExecutionStep, and Net.
            workspace_type: A string defined in the WorkspaceType object.
            setup_net_list: A list of Net objects or a list of NetDef protos.
                So far this is only used by the DistributedSession, in which we
                need to pass a list of special nets to setup the master.
        zSession is closed.NzGot a none runnable.)r   r   _run_compiledr*   r
   )r   r   r   r'   r   r   r   run   s
    zSession.runc                 C   s   |   r|   d| _d S )NF)r   	_do_closer   r   r   r   r   close   s    zSession.closec                 C   s
   t  d S r	   NotImplementedErrorr   outputr   r   r   fetch_output   s    zSession.fetch_outputc                 C   s
   t  d S r	   r/   )r   
task_groupr   r   r   r+      s    zSession._run_compiledc                 C   s   |S r	   r   )r&   r4   r'   r   r   r   r%      s    zSession._compile_task_groupc                 C   s   d S r	   r   r   r   r   r   r-      s    zSession._do_closec                 C   s   | j std| S )NzSession already closed.)r   r   r   r   r   r   	__enter__   s    zSession.__enter__c                 C   s   |d kr|    d S r	   )r.   )r   Zex_typevalue	tracebackr   r   r   __exit__   s    zSession.__exit__)NN)NN)N)r   r   r   r   r   r   r   classmethodr*   r,   r.   r3   r+   r%   r-   r5   r8   r   r   r   r   r      s   70
r   c                   @   s8   e Zd ZdZdddZedddZdd Zd	d
 ZdS )LocalSessionaQ  
    Session that runs in a single node.
    Tasks are all remapped to run in parallel in the 'local' node.

    Currently, LocalSession runs all parallel tasks in the same workspace,
    but this behavior may change in the future. Only tasks pointing to the
    same logical node are guaranteed to always run in the same workspace.
    Nc                 C   s   t |  |ptjjj| _d S r	   )r   r   r   C	Workspacecurrent_ws)r   wsr   r   r   r      s    
zLocalSession.__init__c              	   C   sD   t   | }W 5 Q R X td}||  || | fS )NZtask_group_plan)r   Zto_taskr   r#   ZAddStepZget_stepoutput_listr   )r&   r4   r'   Ztaskplanr   r   r   r%      s
    
z LocalSession._compile_task_groupc              	   C   s   |\}}}g }|  D ](}| jt| |tt| q|j|| jd |t	j
krhtj| jn| j}t| || W 5 Q R X d S )N)Z_fetch_func)namesr>   Zcreate_blobstrappendr   ZBlobReferenceZ
set_values_fetch_outputr   ZPRIVATEr   r;   r<   ZWorkspaceGuardr,   )r   r)   rA   r@   r   outputsnameZtask_wsr   r   r   r+      s    
zLocalSession._run_compiledc                 C   s   | j jt|  S r	   )r>   ZblobsrC   fetchr1   r   r   r   rE      s    zLocalSession._fetch_output)N)N)	r   r   r   r   r   r9   r%   r+   rE   r   r   r   r   r:      s   
r:   N)Zcaffe2.pythonr   r   Zcaffe2.python.taskr   r   r   r   objectr   r   r:   r   r   r   r   <module>	   s
    