B
    ]B                 @   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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LearningRateSchedulerAddressDictionary)r
   )OnlineDatasetOfflineDatasetInferenceNetworkFeedForwardInferenceNetworkLSTM)ModelServerc                   sH  e Zd Zd1 fdd	Zdd Zejeje	j
ddddfdd	Zd
ejeje	j
ddddddf
ddZ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dfddZd
e	j
ddd dddfddZdd Zdejejddi dddejdd ejd!d"dd#d$dd%dd&d$dd'd(d
fd)d*Zd+d, Zd-d. Zejfd/d0Z  ZS )2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__ Q/global/project/projectdirs/dasrepo/etalumis/pyprob_bucket_switch/pyprob/model.pyr      s    
zModel.__init__c             C   s
   t  d S )N)NotImplementedError)r   r   r   r   forward   s    zModel.forwardg      ?c             o   sN   t j| j||||||| j|d	 x(t   | j||	}
t |
}|V  q"W d S )N)	func
trace_modeprior_inflationinference_engineinference_networkobservemetropolis_hastings_traceaddress_dictionarylikelihood_importance)r   _init_tracesr    r   _begin_trace
_end_trace)r   r"   r#   r$   r%   r&   r'   r)   argskwargsresulttracer   r   r   _trace_generator   s     
zModel._trace_generator
   Fc          
   O   s~  | j |||||||
d|}t|	d}|d kr8dd }t }tjdkrz|szt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rr|srt  |  |S )N)r"   r#   r$   r%   r&   r)   )	file_namec             S   s   | S )Nr   )r0   r   r   r   <lambda>)   s    zModel._traces.<locals>.<lambda>r   zBTime spent  | Time remain.| Progress             | {} | Traces/secTrace   r   z%{} | {} | {} | {}/{} | {:,.2f}       )endg      ?)r1   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&   r3   r)   r-   r.   	generatorZtraces
time_startlen_str_num_tracesprev_durationidurationtraces_per_secondr0   
log_weightr   r   r   _traces%   s4    
J
zModel._tracesc             O   s   t | j||S )N)rH   r1   )r   r-   r.   r   r   r   	get_traceB   s    zModel.get_tracec       	   	   O   sL   | j ||tj||||d|}|d|j |jd|t||d |S )N)rM   r"   r#   rN   r3   r)   zPrior, traces: {:,}prior)oprM   r#   r)   )rX   r   rI   renamer>   lengthadd_metadatar<   )	r   rM   r#   rN   r3   r)   r-   r.   rZ   r   r   r   prior_tracesE   s     zModel.prior_tracesc             C   s   | j S )N)r/   )r0   r   r   r   r4   K   s    zModel.<lambda>c             O   s   | j ||||||d|S )N)rM   r#   rN   r3   r)   )r_   )r   rM   r#   rN   r3   r)   r-   r.   r   r   r   prior_distributionK   s    zModel.prior_distributionc	             O   s  |t jkrb| j|	|tj|d ||||d|
}|d|j|j |j	d|t
||j|d n|t jkr| jd kr~tdt , | j|	|tj|| j||||d|
}W d Q R X |d|j| jj|j |j	d|t
||j|| jjd nt|d}|d krd	d
 }|d kr>t| j|	tj||d|
}n|}t }d}d}d}|d krdd}tjdkrt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(r|t)|j*7 }|t)|j+|j, j*8 }|d7 }qW ||j%7 }t-j.d kr8tt/dddgd n|t)t-j.7 }t#$t00 t1|k rl|d7 }|}|| dkr|2|| qW tjdkrt  |3  |d|t j4krdnd|j|dkrdnd |d||  d| |  |j	d|t
||||||d! |S )"N)rM   r"   r$   r%   rN   r&   r3   r)   z)Posterior, IS, traces: {:,}, ESS: {:,.2f}	posterior)r[   rM   r$   effective_sample_sizer)   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[   rM   r$   rb   r)   Ztrain_traces)r3   c             S   s   | S )Nr   )r0   r   r   r   r4   ]   s    z(Model.posterior_traces.<locals>.<lambda>)r"   r$   r&   r   r   zVTime spent  | Time remain.| Progress             | {} | Accepted|Smp reuse| Traces/secr5   r6   z/{} | {} | {} | {}/{} | {} | {} | {:,.2f}       z{:,.2f}%d      r7   )r8   )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: {:,}))r[   rM   r$   r)   thinning_stepsZnum_traces_acceptedZnum_samples_reuisednum_samples)5r	   IMPORTANCE_SAMPLINGrX   r   	POSTERIORr\   r>   r]   rb   r^   r<   *IMPORTANCE_SAMPLING_WITH_INFERENCE_NETWORKr   RuntimeErrortorchno_gradZ_total_train_tracesr   rH   r1   r9   r   r:   r;   r=   r?   r@   rA   rB   rC   rD   maxrE   rF   rG   mathloglength_controlledlog_prob_observedvariables_controlledreusedsumlog_probvariables_dict_addressaddressr   -_metropolis_hastings_site_transition_log_probr   randomfloatrK   rL   LIGHTWEIGHT_METROPOLIS_HASTINGS)r   rM   r$   initial_tracerN   r&   r3   rj   r)   r-   r.   ra   Zcurrent_tracerQ   Ztraces_acceptedZsamples_reusedZsamples_allrR   rS   rT   rU   rV   Zcandidate_traceZlog_acceptance_ratiovariabler   r   r   posterior_tracesN   sr    
$


0$


 

 $
NzModel.posterior_tracesc             C   s   | j S )N)r/   )r0   r   r   r   r4      s    c       
   
   O   s    | j ||||||||d|	S )N)rM   r$   r   rN   r&   r3   rj   )r   )
r   rM   r$   r   rN   r&   r3   rj   r-   r.   r   r   r   posterior_distribution   s    zModel.posterior_distributionc             C   s
   d | _ d S )N)r   )r   r   r   r   reset_inference_network   s    zModel.reset_inference_networkg    eA@   gMbP?gư>g?g        iX  Ti'  r   i   r   c             C   s0  |d krt | |d}n
t|d}|d kr.d }n
t|d}| jd krtd |tjkrft| ||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_dirz!Creating new inference network...)r   observe_embeddingsproposal_mixture_components)r   r   lstm_dim
lstm_depthr   zUnknown inference_network: {})save_file_name_prefixz1Continuing to train existing inference network...z Total number of parameters: {:,})device)rM   datasetdataset_validnum_traces_end
batch_sizevalid_everyoptimizer_typelearning_rate_initlearning_rate_endlearning_rate_scheduler_typemomentumweight_decayr   save_every_secdistributed_backend"distributed_params_sync_every_iterdistributed_num_bucketsdataloader_offline_num_workersstop_with_bad_losslog_file_name)r   r   r   r=   r
   FEEDFORWARDr   LSTMr   
ValueErrorr>   Z_pre_generate_layersZ_history_num_paramstor   _deviceoptimize)r   rM   r   r%   r#   r   dataset_valid_dirr   r   
valid_sizer   r   r   r   r   r   r   r   r   Zpre_generate_layersr   r   r   r   r   r   r   r   r   r   r   r   r   r   learn_inference_network   s,    




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   ro   _save)r   r3   r   r   r   save_inference_network   s    
zModel.save_inference_networkc             C   s   t || _| | j_d S )N)InferenceNetworkBase_loadr   Z_model)r   r3   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   rM   num_traces_per_file)ospathexistsr=   r>   makedirsr   save_dataset)r   r   rM   r   r#   r-   r.   r   r   r   r   r      s
    
zModel.save_dataset)r   N)__name__
__module____qualname__r   r    r   rI   r   DISABLEDr	   rl   r1   rX   rY   r_   r`   r   r   r   r
   r   r   ADAMr   NONEr   r   r   r   __classcell__r   r   )r   r   r      s   	$FH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:5555Nc                s*   || _ d | _|| _|| _t j|| d S )N)_server_address_model_server_before_forward_func_after_forward_funcr   r   )r   Zserver_addressZbefore_forward_funcZafter_forward_funcr-   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   s^   | j d kr,t| j| _ d| j j| j j| _| jd k	r>|   | j  }| j	d k	rZ| 	  |S )Nz{} running on {})
r   r   r   r>   Z
model_nameZsystem_namer   r   r    r   )r   retr   r   r   r       s    



zRemoteModel.forward)r   NN)r   r   r   r   r   r    r   r   r   )r   r   r      s   r   )rp   r9   rE   r   rs   r~   	termcolorr   distributionsr   ri   r   r   r   r   r	   r
   r   r   r   nnr   r   r   r   r   Zremoter   r   r   r   r   r   r   <module>   s   , <