U C^N@sddlmZddlZddlmZddlmZz ddlZWnek rPdZYnXz0ddl Z ddl Z ddl Z ddl Z ddl mZWnek rdZ dZYnXddZd d ZGd d d eZGd ddeZdS))unicode_literalsN)BytesIO)Model)ModulecCs*t|drtjj|St|SdS)NtoDlpack)hasattrtorchutilsdlpackZ from_dlpackrZ from_numpy)Z xp_tensorr 7/tmp/pip-install-6_kvzl1k/thinc/thinc/extra/wrappers.pyxp2torchs rcCs*|jrttjj|S|SdSN) Zis_cudacupyZ fromDlpackr r r Z to_dlpackdetachZnumpy)Z torch_tensorr r r torch2xpsrc@seZdZdZddZd+ddZddZd d Zd d Zd dZ d,ddZ ddZ e j ddZddddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*S)-PyTorchWrapperzWrap a PyTorch model, so that it has the same API as Thinc models. To optimize the model, you'll need to create a PyTorch optimizer and call optimizer.step() after each batch --- see examples/wrap_pytorch.py cCst|||_d|_dSr)r__init___model _optimizer)selfmodelr r r r,s zPyTorchWrapper.__init__TcCstjjt||d}|fifSN)Z requires_grad)r autogradVariabler)rx_data is_updatex_varr r r prepare_input1szPyTorchWrapper.prepare_inputcCst|Srr)ry_varr r r prepare_output5szPyTorchWrapper.prepare_outputcCst|}|fd|fifSNZ grad_tensorsr)rdy_datar!dy_varr r r prepare_backward_input8sz%PyTorchWrapper.prepare_backward_inputcCs|d}t|jSNrrZgrad)rx_argsx_kwargsrr r r prepare_backward_output<sz&PyTorchWrapper.prepare_backward_outputc CsP|j|j|dd\}}t|j||}W5QRX|j||S)NFr)revalrr Zno_gradtrainr")rrr*r+r!r r r predict@s    zPyTorchWrapper.predictcsd|dkr|dfSjj|dd\j}dfdd }||fS)zReturn the output of the wrapped PyTorch model for the given input, along with a callback to handle the backward pass. NTr-cs\|\}}tjj|||dk rPjdkr<|_jjSr) r'r rZbackwardr_create_optimizerstepZ zero_gradr,)r%sgdZd_argsZd_kwargsZfwd_argsZ fwd_kwargsrr!r r backward_pytorchSs    z5PyTorchWrapper.begin_update..backward_pytorch)N)r0rr/rr")rrZdropyr6r r5r begin_updateHs    zPyTorchWrapper.begin_updatecCsf|j}|jdkr<|jdkrqsz-PyTorchWrapper.use_params..) iditemsrr@rreplacer state_dictload_state_dict)rr=Z key_prefixrJrDrEbackupr r r use_paramsis zPyTorchWrapper.use_params) init_stepscCst|dddkrdS|jD]t\}}d|jd|}|j|d7<t|}||jkr~|j |j|||j|q"| |j|<||j|<q"dS)Naveragesr>r?rN) getattrrrJrHrGZ nr_updaterrPopsZupdate_averagescopy)rr4rOnameparamkeyZxp_paramr r r _update_pytorch_averagesxs z'PyTorchWrapper._update_pytorch_averagescCst|jt|dSr)r saverrJstr)rpathr r r to_diskszPyTorchWrapper.to_diskcCsJ|jjdkrd}ntj}d|}|jtj||d|j|dS)Ncpucuda:%d map_location) rRdevicer cudacurrent_devicerrKloadto)rrZr_ device_idr r r from_disks   zPyTorchWrapper.from_diskcCs*t}t|j||d|Sr()rr rXrrJseekgetvalue)rfileliker r r to_bytess zPyTorchWrapper.to_bytescCs\t|}|d|jjdkr$d}ntj}d|}|jtj ||d|j |dS)Nrr\r]r^) rrgrRr`r rarbrrKrcrd)rdatarir_rer r r from_bytess   zPyTorchWrapper.from_bytescCs|j|dSr)rra)rZ device_numr r r to_gpuszPyTorchWrapper.to_gpucCs|jdSr)rr\rr r r to_cpuszPyTorchWrapper.to_cpucCstdSrr<)rZnew_dimr r r resize_outputszPyTorchWrapper.resize_outputcCstdSrrprnr r r resize_inputszPyTorchWrapper.resize_inputN)T)r1)__name__ __module__ __qualname____doc__rrr"r'r,r0r8r2 contextlibcontextmanagerrMrWr[rfrjrlrmrorqrrr r r r r&s(      rc@s2eZdZdZd ddZddZddZd d Zd S) PyTorchWrapperRNNzWrap a PyTorch RNN modelFcCs<t|tr|\}}n|}d}tjjt||d}||fifSr) isinstancetupler rrr)rinputsrrZh_0rr r r rs   zPyTorchWrapperRNN.prepare_inputcCs|\}}t||fSrr )rZ torch_outputsr!Zh_nr r r r"sz PyTorchWrapperRNN.prepare_outputcCs(|\}}t|}|\}}|fd|fifSr#r$)rr%r!Zdyr?r&r r r r'sz(PyTorchWrapperRNN.prepare_backward_inputcCs|\}}t|jSrr))rr*r+rr?r r r r,sz)PyTorchWrapperRNN.prepare_backward_outputN)F)rsrtrurvrr"r'r,r r r r rys  ry) __future__rrwcompatrZneural._classes.modelrr ImportErrorZtorch.autogradr Z torch.optimZtorch.utils.dlpackZtorch.nnrZ PyTorchModulerrrryr r r r s*