B
    #g\E8                 @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ ddlm	Z	 ddl
mZmZmZmZmZmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZ G d	d
 d
ZG dd deZdS )    N)colored   )	Empirical)utilstate	TraceModePriorInflationInferenceEngineInferenceNetwork	OptimizerAddressDictionary)r
   )OnlineDatasetOfflineDatasetInferenceNetworkFeedForwardInferenceNetworkLSTM)ModelServerc                   s  e Zd Zd' fdd	Zdd Zejeje	j
dddfddZd	ejeje	j
ddd
ddf	ddZd	ejddfddZd	ejdd dfddZd	e	j
dddddfddZd	e	j
ddd dddfddZejejddi dddejdddddddddfdd Zd!d" Zd#d$ Zejfd%d&Z  ZS )(ModelUnnamed pyprob modelNc                s4   t    || _d | _|d kr&d | _n
t|| _d S )N)super__init__name_inference_network_address_dictionaryr   )selfr   address_dict_file_name)	__class__ J/global/project/projectdirs/dasrepo/etalumis/pyprob_master/pyprob/model.pyr      s    
zModel.__init__c             C   s
   t  d S )N)NotImplementedError)r   r   r   r   forward   s    zModel.forwardc          
   o   sJ   t | j||||||| j x(t   | j||}	t |	}
|
V  qW d S )N)r   _init_tracesr   r   _begin_trace
_end_trace)r   
trace_modeprior_inflationinference_engineinference_networkobservemetropolis_hastings_traceargskwargsresulttracer   r   r   _trace_generator   s    
zModel._trace_generator
   Fc
          
   O   s|  | j |
|||||d|}t|	d}|d kr6dd }t }tjdkrx|sxtt|}tdd	|d d  d	}xt
|D ]}tjdkr$|s$t | }|| tjks||d kr$|}|d | }td
t|t|| | t|d |t|d |||dd tj  t|}|tjkr>d}n|j}|||| qW tjdkrp|spt  |  |S )N)r#   r$   r%   r&   r'   )	file_namec             S   s   | S )Nr   )r,   r   r   r   <lambda>)   s    zModel._traces.<locals>.<lambda>r   zBTime spent  | Time remain.| Progress             | {} | Traces/secTrace   r   z%{} | {} | {} | {}/{} | {:,.2f}       )endg      ?)r-   r   timer   
_verbositylenstrprintformatljustrange_print_refresh_ratedays_hours_mins_secs_strprogress_barrjustsysstdoutflushnextr   PRIORlog_importance_weightaddfinalize)r   
num_tracesr#   r$   r%   r&   map_funcsilentr'   r/   r)   r*   	generatorZtraces
time_startlen_str_num_tracesprev_durationidurationtraces_per_secondr,   
log_weightr   r   r   _traces%   s4    
J
zModel._tracesc             O   s4   | j ||tj|||d|}|d|j |S )N)rI   r#   r$   rJ   r/   zPrior, traces: {:,})rT   r   rE   renamer:   length)r   rI   r$   rJ   r/   r)   r*   priorr   r   r   prior_tracesB   s    zModel.prior_tracesc             C   s   | j S )N)r+   )r,   r   r   r   r0   G   s    zModel.<lambda>c             O   s   | j |||||d|S )N)rI   r$   rJ   r/   )rX   )r   rI   r$   rJ   r/   r)   r*   r   r   r   prior_distributionG   s    zModel.prior_distributionc             O   s  |t jkrF| j||tj|d |||d|	}
|
d|
j|
j nz|t j	kr| j
d krbtd| j
  t * | j||tj|| j
|||d|	}
W d Q R X |
d|
j| j
j|
j nt|d}
|d krdd }|d krt| j|tj||d|	}n|}t }d	}d	}d	}|d kr.d
}tjd
krftt|}tdd|d d
  d	}xt|D ]}tjd
krHt | }|| tjks||d
 krH|}|d
 | }tdt|t|| | t|d
 |t|d
 ||dd||d
   ddd| td
| d|dd t j!"  t| j|tj|||d|	}t#$|j%t#$|j% |j& |j& }xH|j'D ]>}|j(r|t)|j*7 }|t)|j+|j, j*8 }|d
7 }qW ||j%7 }t-j.d krtt/dddgd n|t)t-j.7 }t#$t00 t1|k r6|d
7 }|}|| d	krr|
2|| qrW tjd
krjt  |
3  |
d|t j4krdnd|
j|d
krdnd|d||  d| |  |
S )N)rI   r#   r%   r&   rJ   r'   r/   z)Posterior, IS, traces: {:,}, ESS: {:,.2f}zCannot run inference engine IMPORTANCE_SAMPLING_WITH_INFERENCE_NETWORK because no inference network for this model is available. Use learn_inference_network or load_inference_network first.z>Posterior, IC, traces: {:,}, train. traces: {:,}, ESS: {:,.2f})r/   c             S   s   | S )Nr   )r,   r   r   r   r0   X   s    z(Model.posterior_traces.<locals>.<lambda>)r#   r%   r'   r   r   zVTime spent  | Time remain.| Progress             | {} | Accepted|Smp reuse| Traces/secr1   r2   z/{} | {} | {} | {}/{} | {} | {} | {:,.2f}       z{:,.2f}%d      r3   )r4   )r#   r%   r(   r'   zzWarning: trace did not hit the Metropolis Hastings site, ensure that the model is deterministic except pyprob.sample callsredbold)attrszIPosterior, {}, traces: {:,}{}, accepted: {:,.2f}%, sample reuse: {:,.2f}%ZLMHRMH z(thinning_steps={:,}))5r	   IMPORTANCE_SAMPLINGrT   r   	POSTERIORrU   r:   rV   effective_sample_size*IMPORTANCE_SAMPLING_WITH_INFERENCE_NETWORKr   RuntimeErrorevaltorchno_gradZ_total_train_tracesr   rD   r-   r5   r   r6   r7   r8   r9   r;   r<   r=   r>   r?   r@   maxrA   rB   rC   mathloglength_controlledlog_prob_observedvariables_controlledreusedsumlog_probvariables_dict_addressaddressr   -_metropolis_hastings_site_transition_log_probr   randomfloatrG   rH   LIGHTWEIGHT_METROPOLIS_HASTINGS)r   rI   r%   initial_tracerJ   r'   r/   thinning_stepsr)   r*   	posteriorZcurrent_tracerM   Ztraces_acceptedZsamples_reusedZsamples_allrN   rO   rP   rQ   rR   Zcandidate_traceZlog_acceptance_ratiovariabler   r   r   posterior_tracesJ   sn    
"



. 

 

 $
NzModel.posterior_tracesc             C   s   | j S )N)r+   )r,   r   r   r   r0      s    c       
   
   O   s    | j ||||||||d|	S )N)rI   r%   rx   rJ   r'   r/   ry   )r|   )
r   rI   r%   rx   rJ   r'   r/   ry   r)   r*   r   r   r   posterior_distribution   s    zModel.posterior_distribution@   gMbP?g?g        iX  Tr   c             C   s2  |d krt | |d}n
t|d}d }|d krD|d k	rNt | ||d}n
t|d}| jd krtd |tjkrzt| |d| _n(|tjkrt| |d| _nt	d
||r|d k	r| jj||d |d k	r| jj||d ntd td	
| jjd
  | jjtjd | jj|||||	|
||||||||d d S )N)modelr$   )dataset_dir)r   rV   r$   z!Creating new inference network...)r   observe_embeddingszUnknown inference_network: {})save_file_name_prefixz1Continuing to train existing inference network...z Total number of parameters: {:,})device)rI   datasetdataset_valid
batch_sizevalid_everyoptimizer_typelearning_ratemomentumweight_decayr   save_every_secdistributed_backenddataloader_offline_num_workersstop_with_bad_loss)r   r   r   r9   r
   FEEDFORWARDr   LSTMr   
ValueErrorr:   Z_pre_generate_layersZ_history_num_paramstor   _deviceoptimize)r   rI   r&   r$   r   dataset_valid_dirr   r   
valid_sizer   r   r   r   r   r   r   Zpre_generate_layersr   r   r   r   r   r   r   r   learn_inference_network   s0    




zModel.learn_inference_networkc             C   s"   | j d krtd| j | d S )Nz+The model has no trained inference network.)r   re   _save)r   r/   r   r   r   save_inference_network   s    
zModel.save_inference_networkc             C   s   t || _| | j_d S )N)InferenceNetworkBase_loadr   Z_model)r   r/   r   r   r   load_inference_network   s    zModel.load_inference_networkc             O   sN   t j|s$td| t | t| d |d}|j||||d| d S )Nz&Directory does not exist, creating: {})r$   )r   rI   num_traces_per_file)ospathexistsr9   r:   makedirsr   save_dataset)r   r   rI   r   r$   r)   r*   r   r   r   r   r      s
    
zModel.save_dataset)r   N)__name__
__module____qualname__r   r   r   rE   r   DISABLEDr	   ra   r-   rT   rX   rY   r|   r}   r
   r   r   ADAMr   r   r   r   __classcell__r   r   )r   r   r      s   	"E4!r   c                   s2   e Zd Zd fdd	Z fddZdd Z  ZS )	RemoteModeltcp://127.0.0.1:5555c                s   || _ d | _t j|| d S )N)_server_address_model_serverr   r   )r   Zserver_addressr)   r*   )r   r   r   r      s    zRemoteModel.__init__c                s"   | j d k	r| j   t   d S )N)r   closer   )r   )r   r   r   r      s    

zRemoteModel.closec             C   s6   | j d kr,t| j| _ d| j j| j j| _| j  S )Nz{} running on {})r   r   r   r:   Z
model_nameZsystem_namer   r   )r   r   r   r   r      s    
zRemoteModel.forward)r   )r   r   r   r   r   r   r   r   r   )r   r   r      s   r   )rg   r5   rA   r   rj   ru   	termcolorr   distributionsr   r`   r   r   r   r   r	   r
   r   r   nnr   r   r   r   r   Zremoter   r   r   r   r   r   r   <module>   s   ( 6