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                   s:  e Zd Zd- 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
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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__ P/global/project/projectdirs/dasrepo/etalumis/pyprob_master_mar20/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   s6   | j ||tj||||d|}|d|j |S )N)rM   r"   r#   rN   r3   r)   zPrior, traces: {:,})rX   r   rI   renamer>   length)	r   rM   r#   rN   r3   r)   r-   r.   priorr   r   r   prior_tracesB   s     zModel.prior_tracesc             C   s   | j S )N)r/   )r0   r   r   r   r4   G   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_distributionG   s    zModel.prior_distributionc	             O   s  |t jkrH| j|	|tj|d ||||d|
}|d|j|j nr|t j	kr| j
d krdtd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r`tt|}tdd|d d
  d	}xt|D ]}tjd
krBt | }|| tjks||d
 krB|}|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rtt.dddgd n|t(t,j-7 }t"#t// t0|k r0|d
7 }|}|| d	krl|1|| qlW tjd
krdt  |2  |d|t j3krdnd|j|d
krdnd|d||  d| |  |S )N)rM   r"   r$   r%   rN   r&   r3   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})r3   c             S   s   | S )Nr   )r0   r   r   r   r4   W   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: {:,}))4r	   IMPORTANCE_SAMPLINGrX   r   	POSTERIORrY   r>   rZ   effective_sample_size*IMPORTANCE_SAMPLING_WITH_INFERENCE_NETWORKr   RuntimeErrortorchno_gradZ_total_train_tracesr   rH   r1   r9   r   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   thinning_stepsr)   r-   r.   	posteriorZcurrent_tracerQ   Ztraces_acceptedZsamples_reusedZsamples_allrR   rS   rT   rU   rV   Zcandidate_traceZlog_acceptance_ratiovariabler   r   r   posterior_tracesJ   sl    
$


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   r|   )r   )
r   rM   r$   r{   rN   r&   r3   r|   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   c             C   s(  |d krt | |d}n
t|d}|d kr.d }n
t|d}| jd krtd |tjkrdt| |d| _n(|tjkr~t| |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_embeddingsz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   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   ri   _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	   re   r1   rX   r\   r]   r   r   r   r
   r   r   ADAMr   NONEr   r   r   r   __classcell__r   r   )r   r   r      s   	$DB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   )rj   r9   rE   r   rm   rx   	termcolorr   distributionsr   rd   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