B
    8\07                 @   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fddZd	e	j
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__ N/global/project/projectdirs/dasrepo/etalumis/conda_envs/pyprob/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   sz  | j |
|||||d|}t|	d}t }tjdkrh|sht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}|d k	rF||}||| qrW tjdkrn|snt  |  |S )N)r#   r$   r%   r&   r'   )	file_namer   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)rH   r#   r$   rI   r/   zPrior, traces: {:,})rS   r   rD   renamer9   length)r   rH   r$   rI   r/   r)   r*   priorr   r   r   prior_tracesB   s    zModel.prior_tracesc             C   s   | j S )N)r+   )r,   r   r   r   <lambda>G   s    zModel.<lambda>c             O   s   | j |||||d|S )N)rH   r$   rI   r/   )rW   )r   rH   r$   rI   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 nL|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rt| j|tj||d|}
n|}
t }d}d}d}tjdkrFtt|}td	d
|d d  d}xt|D ]}tjdkr(t | }|| tjks||d kr(|}|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(rt|t)|j*7 }|t)|
j+|j, j*8 }|d7 }qtW ||j%7 }t-j.d krtt/dddgd n|t)t-j.7 }t#$t00 t1|k r|d7 }|}
|d k	r0|	2||
 n
|	2|
 qRW tjdkrRt  |	3  |	d|t j4krrdnd|	jd||  d| |  |	S )N)rH   r#   r%   r&   rI   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/   )r#   r%   r'   r   r   zVTime spent  | Time remain.| Progress             | {} | Accepted|Smp reuse| Traces/secr0   r1   z/{} | {} | {} | {}/{} | {} | {} | {:,.2f}       z{:,.2f}%d      r2   )r3   )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)attrszGPosterior, {}, traces: {:,}, accepted: {:,.2f}%, sample reuse: {:,.2f}%ZLMHRMH)5r	   IMPORTANCE_SAMPLINGrS   r   	POSTERIORrT   r9   rU   effective_sample_size*IMPORTANCE_SAMPLING_WITH_INFERENCE_NETWORKr   RuntimeErrorevaltorchno_gradZ_total_train_tracesr   rC   r-   r4   r   r5   r6   r7   r8   r:   r;   r<   r=   r>   r?   maxr@   rA   rB   mathloglength_controlledlog_prob_observedvariables_controlledreusedsumlog_probvariables_dict_addressaddressr   -_metropolis_hastings_site_transition_log_probr   randomfloatrF   rG   LIGHTWEIGHT_METROPOLIS_HASTINGS)r   rH   r%   initial_tracerI   r'   r/   r)   r*   	posteriorZcurrent_tracerL   Ztraces_acceptedZsamples_reusedZsamples_allrM   rN   rO   rP   rQ   Zcandidate_traceZlog_acceptance_ratiovariabler   r   r   posterior_tracesJ   sh    
"



. 
 
 $

8zModel.posterior_tracesc             C   s   | j S )N)r+   )r,   r   r   r   rX      s    c       	   	   O   s   | j |||||||d|S )N)rH   r%   rw   rI   r'   r/   )rz   )	r   rH   r%   rw   rI   r'   r/   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}   rU   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)rH   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   r8   r
   FEEDFORWARDr   LSTMr   
ValueErrorr9   Z_pre_generate_layersZ_history_num_paramstor   _deviceoptimize)r   rH   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   rd   _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~   rH   num_traces_per_file)ospathexistsr8   r9   makedirsr   save_dataset)r   r~   rH   r   r$   r)   r*   r   r   r   r   r      s
    
zModel.save_dataset)r   N)__name__
__module____qualname__r   r   r   rD   r   DISABLEDr	   r`   r-   rS   rW   rY   rz   r{   r
   r   r   ADAMr   r   r   r   __classcell__r   r   )r   r   r      s   	"@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   r9   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   )rf   r4   r@   r   ri   rt   	termcolorr   distributionsr    r   r   r   r   r	   r
   r   r   nnr   r   r   r   r   Zremoter   r   r   r   r   r   r   <module>   s   ( 1