B
    dW                 @   s  d dl Z d dlm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 ddlmZ ee drje jZnejZd	ZdZd ZdZdZd
ZdZdZdZdZdZe
ddgedZe
ddgedZ edkse dkre!dda"da#da$da%da&d a'dd Z(ddddddddddZ)dd Z*dPdd Z+d!d" Z,d a-d#d$ Z.d%d& Z/eeeeB eeB eB d'Z0d(d) Z1d*d+ Z2d,d- Z3d.d/ Z4d0d1 Z5d2d3 Z6d4d5 Z7d6e j8id7ej9ie j:e j;d8ej<ej=d9d:Z>d6e j?id7ej@ie jAe jBd8ejCejDd9d:ZEd;d< ZFd=d> ZGd?d@ ZHdAdB ZIe jJZKejLejMejLejMejMejLejLejMejMejLejLejLejNgeK_OejMeK_PejQZRejLejMejLejMejMejLejLejMejMejLejLejLejNgeR_OejMeR_Pe jSZTejLejMejLejMejMejLejLejMejMejLejLejNgeT_OejMeT_PejUZVejLejMejLejMejMejLejLejMejMejLejLejNgeV_OejMeV_Pe jWZXejLejMejLejMejMejLejLejMejMejLejLejNgeX_OejMeX_PejYZZejLejMejLejMejMejLejLejMejMejLejLejNgeZ_OejMeZ_PeKeXeTeReZeVdCZ[dDdE Z\G dFdG dGeZ]G dHdI dIeZ^dJdK Z_dLdM Z`dNdO ZadS )Q    N)zeros)get_ctypes_library   )_BaseFFT	_BaseIFFT   )check_alignedRTLD_DEEPBIND             @   i    fftw3)modefftw3fzUnable to find FFTW librariesFc             C   sR   t s"| dkrtd| qN| }n,tj}tj}d |_d |_||  ||  | ad S )Nr   z7Threading is NOT enabled, but {0} > 1 threads specified)	HAVE_FFTW_THREADED
ValueErrorformat_double_threaded_libZfftw_plan_with_nthreads_float_threaded_libZfftwf_plan_with_nthreadsrestype_fftw_current_nthreads)nthreadsZ_pycbc_current_threadsZ	dplanwthrZ	fplanwthr r   [/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/fft/fftw.py_fftw_plan_with_nthreadsB   s    r   )doublefloatZ	fftw3_ompZ
fftw3f_ompZfftw3_threadsZfftw3f_threads)
unthreadedopenmppthreadsc             C   s  t rtdtyt|  d }t|  d }W n" tk
rP   td| Y nX |d k	ryt|dgtda	t|dgtda
t	d kst
d krd}|| d	7 }|| 7 }t|t	 }t
 }|d
ks|d
krdS dada | ad
S    dS ndada | ad
S d S )Nz@Threading backend for FFTW already set to {0}; cannot be changedr   r   z.Backend {0} for FFTW threading does not exist!r   )r   r   z!Unable to load threaded librariesz or r   r   TF)_fftw_threaded_setRuntimeErrorr   _fftw_threaded_lib_fftw_threading_libnamesKeyErrorr   r   FFTW_RTLD_MODEr   r   Zfftw_init_threadsZfftwf_init_threadsr   )backendZdouble_threaded_libnameZfloat_threaded_libnameZerr_strZdretZfretr   r   r   _init_threadsY   sJ    

r*   c             C   sP   | d k	r(t | }|dkrLtd| n$dddg}xtsJ| }t |}q4W d S )Nr   z/Could not initialize FFTW threading backend {0}r    r"   r!   )r*   r$   r   r#   pop)r)   retvalZ_backend_listZ_next_backendr   r   r   set_threads_backend   s    
r-   c               C   s   t s
t  t  t  d S )N)r#   r-   
double_libfftw_import_system_wisdom	float_libZfftwf_import_system_wisdomr   r   r   r   import_sys_wisdom   s    r1   c               C   s   t S )z
    Get the current 'measure level' used in deciding how much effort to put into
    creating FFTW plans.  From least effort (and shortest planning time) to most
    they are 0 to 3.  No arguments.
    )_default_measurelvlr   r   r   r   get_measure_level   s    r3   c             C   s   | dkrt d| adS )z
    Set the current 'measure level' used in deciding how much effort to expend
    creating FFTW plans.  Must be an integer from 0 (least effort, shortest time)
    to 3 (most effort and time).
    )r   r   r      z.Measure level can only be one of 0, 1, 2, or 3N)r   r2   )mlvlr   r   r   set_measure_level   s    r6   )r   r   r   r4   c             C   s   |rt |  S t |  tB S d S )N)
_flag_dictFFTW_UNALIGNED)r5   alignedr   r   r   get_flag   s    r:   c             C   s^   t s
t  tjtjtjtjd}|||f }tj	g|_
||  }|dkrZtd|| dS )zBImport or export an FFTW plan for single or double precision.
    ))r   import)r   export)r   r;   )r   r<   r   z"Could not {0} wisdom from file {1}N)r#   r-   r0   Z!fftwf_import_wisdom_from_filenameZfftwf_export_wisdom_to_filenamer.   Z fftw_import_wisdom_from_filenameZfftw_export_wisdom_to_filenamectypesc_char_pargtypesencoder$   r   )filename	precisionactionZfmapfr,   r   r   r   	wisdom_io   s    

rE   c             C   s   t | dd d S )Nr   r;   )rE   )rA   r   r   r   "import_single_wisdom_from_filename   s    rF   c             C   s   t | dd d S )Nr   r;   )rE   )rA   r   r   r   "import_double_wisdom_from_filename   s    rG   c             C   s   t | dd d S )Nr   r<   )rE   )rA   r   r   r    export_single_wisdom_to_filename   s    rH   c             C   s   t | dd d S )Nr   r<   )rE   )rA   r   r   r    export_double_wisdom_to_filename   s    rI   c             C   s>   t s
t  tj}tjg|_||  tj}tjg|_||  d S )N)	r#   r-   r.   Zfftw_set_timelimitr=   Zc_doubler?   r0   Zfftwf_set_timelimit)timerD   r   r   r   set_planning_limit   s    

rK   	complex64
complex128)float32rL   )float64rM   )rN   rO   rL   rM   c             C   s  t s
t  |tkrt| t||}||krPt| |d}	|rB|	}
qt| |d}
n|jdkr|jdkrt| d d |d}	|r|	j|dd|  }
qt| |d}
n:t| d d |d}
|r|
j|dd|  }	nt| |d}	t	|}t	|}t
t| t| }tj|_|j|jkrHtjtjtjtjtjg|_|| |	j|
j||}n(tjtjtjtjg|_|| |	j|
j|}~	~
|jdkrtj}ntj}tjg|_||fS )N)dtypecrD   r   r   r   )rD   F)r#   r-   r   r   r:   r   kindview_nprP   plan_functionstrr=   c_void_pr   c_intr?   ptrcharr0   Zfftwf_destroy_planr.   Zfftw_destroy_plan)sizeZidtypeZodtype	directionr5   r9   r   ZinplaceflagsipoprD   theplandestroyr   r   r   plan  sH    




rc   c             C   s>   t t|j t|j }tjtjtjg|_|| |j|j d S )N)execute_functionrW   rP   r=   rX   r?   rZ   )rc   invecoutvecrD   r   r   r   executeN  s    rg   c          
   C   sZ   t t| | j|jtt t| jo(t|jtjj	j
| j|jk\}}t|| | || d S )N)rc   lenrP   FFTW_FORWARDr3   r   data_schememgrstatenum_threadsrZ   rg   )re   rf   precitypeotypera   rb   r   r   r   fftS  s
    rr   c          
   C   sZ   t t|| j|jtt t| jo(t|jtjj	j
| j|jk\}}t|| | || d S )N)rc   rh   rP   FFTW_BACKWARDr3   r   rj   rk   rl   rm   rn   rZ   rg   )re   rf   ro   rp   rq   ra   rb   r   r   r   ifftZ  s
    rt   ))rL   rL   )rN   rL   )rL   rN   )rM   rM   )rO   rM   )rM   rO   c             C   sz  t j| jgt jd}t jt| jgt jd}t jt| jgt jd}tjj	j
}tsXt  |tkrht| t }t| jjot| jj}t||}tt| jjt| jjf }tt| j| jjd}	tt| j| jjd}
| jjdkr>| jjdkr>| jrt}nt}|d|jj| j|	j|jjd| j|
j|jjd| j||}n4|d|jj| j|	j|jjd| j|
j|jjd| j|}~	~
|S )N)rP   complexr   ) rU   Zasarrayr\   Zint32rh   re   rf   rk   rl   rm   rn   r#   r-   r   r   r3   r   rj   r:   _plan_funcs_dictrW   rP   r   rS   forwardri   rs   r=   nbatchrZ   ZidistZodist)ZfftobjnZinembedZonembedr   r5   r9   r^   Z	plan_funcZtmpinZtmpoutZffdrc   r   r   r   _fftw_setup  s:    


rz   c                   s&   e Zd Zd fdd	Zdd Z  ZS )FFTr   Nc                sj   t t| |||| | jj| _| jj| _tt	| jj
 t	| jj
 | _tjtjtjg| j_t| | _d S )N)superr{   __init__re   rZ   iptrrf   optrrd   rW   rP   _efuncr=   rX   r?   rz   rc   )selfre   rf   rx   r\   )	__class__r   r   r}     s    

zFFT.__init__c             C   s   |  | j| j| j d S )N)r   rc   r~   r   )r   r   r   r   rg     s    zFFT.execute)r   N)__name__
__module____qualname__r}   rg   __classcell__r   r   )r   r   r{     s   r{   c                   s&   e Zd Zd fdd	Zdd Z  ZS )IFFTr   Nc                sj   t t| |||| | jj| _| jj| _tt	| jj
 t	| jj
 | _tjtjtjg| j_t| | _d S )N)r|   r   r}   re   rZ   r~   rf   r   rd   rW   rP   r   r=   rX   r?   rz   rc   )r   re   rf   rx   r\   )r   r   r   r}     s    

zIFFT.__init__c             C   s   |  | j| j| j d S )N)r   rc   r~   r   )r   r   r   r   rg     s    zIFFT.execute)r   N)r   r   r   r}   rg   r   r   r   )r   r   r     s   r   c             C   s   | j ddtddddg ttd | j dd	d
d | j ddd
d | j ddd
d | j ddd
d | j ddd
d | j dddd d
S )z
    Inserts the options that affect the behavior of this backend

    Parameters
    ----------
    optgroup: fft_option
       OptionParser argument group whose options are extended
    z--fftw-measure-levelzMDetermines the measure level used in planning FFTW FFTs; allowed values are: r   r   r   r4   )helptypedefaultz--fftw-threads-backendzOGive 'openmp', 'pthreads' or 'unthreaded' to specify which threaded FFTW to useN)r   r   z--fftw-input-float-wisdom-filez3Filename from which to read single-precision wisdomz--fftw-input-double-wisdom-filez3Filename from which to read double-precision wisdomz--fftw-output-float-wisdom-filez2Filename to which to write single-precision wisdomz --fftw-output-double-wisdom-filez2Filename to which to write double-precision wisdomz--fftw-import-system-wisdomz-If given, call fftw[f]_import_system_wisdom()
store_true)r   rC   )add_argumentrW   intr2   )Zoptgroupr   r   r   insert_fft_options  s,    	
r   c             C   sb   | j dkr|d| j  | jr@| jdk	s6| jdk	r@|d | jdk	r^| jdkr^|d dS )a  Parses the FFT options and verifies that they are
       reasonable.

    Parameters
    ----------
    opt : object
        Result of parsing the CLI with OptionParser, or any object with the
        required attributes.
    parser : object
        OptionParser instance.
    )r   r   r   r4   z&{0} is not a valid FFTW measure level.NzIf --fftw-import-system-wisdom is given, then you cannot give either of --fftw-input-float-wisdom-file or --fftw-input-double-wisdom-file)r!   r"   r    zEInvalid threads backend; must be 'openmp', 'pthreads' or 'unthreaded')fftw_measure_levelerrorr   r/   Zfftw_input_float_wisdom_fileZfftw_input_double_wisdom_filefftw_threads_backend)optparserr   r   r   verify_fft_options  s    




r   c             C   s   t | j t| j d S )N)r-   r   r6   r   )r   r   r   r   from_cli  s    
r   )N)bosZpycbc.typesr   numpyrU   r=   Zpycbc.schemeschemerk   Zpycbc.libutilsr   corer   r   typesr   hasattrr	   r(   ZDEFAULT_MODEri   rs   ZFFTW_MEASUREZFFTW_DESTROY_INPUTr8   ZFFTW_CONSERVE_MEMORYZFFTW_EXHAUSTIVEZFFTW_PRESERVE_INPUTZFFTW_PATIENTZFFTW_ESTIMATEZFFTW_WISDOM_ONLYr.   r0   ImportErrorr%   r#   r   r   r   r   r   r&   r*   r-   r1   r2   r3   r6   r7   r:   rE   rF   rG   rH   rI   rK   Zfftwf_plan_dft_r2c_1dZfftw_plan_dft_r2c_1dZfftwf_plan_dft_c2r_1dZfftwf_plan_dft_1dZfftw_plan_dft_c2r_1dZfftw_plan_dft_1drV   Zfftwf_execute_dft_r2cZfftw_execute_dft_r2cZfftwf_execute_dft_c2rZfftwf_execute_dftZfftw_execute_dft_c2rZfftw_execute_dftrd   rc   rg   rr   rt   Zfftwf_plan_many_dftZplan_many_c2c_frY   rX   Zc_uintr?   r   Zfftw_plan_many_dftZplan_many_c2c_dZfftwf_plan_many_dft_c2rZplan_many_c2r_fZfftw_plan_many_dft_c2rZplan_many_c2r_dZfftwf_plan_many_dft_r2cZplan_many_r2c_fZfftw_plan_many_dft_r2cZplan_many_r2c_drv   rz   r{   r   r   r   r   r   r   r   r   <module>   s   
8

H



# 