a
    a1                     @   s   d Z ddlZddlZddlmZ dZdZdZdZdefd	efd
efdefgZ	ddgZ
g dZdZdZdZdd Zdd Zdd Zdd Zedkre  dS )a  
python generate_sparsetools.py

Generate manual wrappers for C++ sparsetools code.

Type codes used:

    'i':  integer scalar
    'I':  integer array
    'T':  data array
    'B':  boolean array
    'V':  std::vector<integer>*
    'W':  std::vector<data>*
    '*':  indicates that the next argument is an output argument
    'v':  void
    'l':  64-bit integer scalar

See sparsetools.cxx for more details.

    N)newera  
bsr_diagonal        v iiiiiIIT*T
bsr_tocsr           v iiiiIIT*I*I*T
bsr_scale_rows      v iiiiII*TT
bsr_scale_columns   v iiiiII*TT
bsr_sort_indices    v iiii*I*I*T
bsr_transpose       v iiiiIIT*I*I*T
bsr_matmat          v iiiiiiIITIIT*I*I*T
bsr_matvec          v iiiiIITT*T
bsr_matvecs         v iiiiiIITT*T
bsr_elmul_bsr       v iiiiIITIIT*I*I*T
bsr_eldiv_bsr       v iiiiIITIIT*I*I*T
bsr_plus_bsr        v iiiiIITIIT*I*I*T
bsr_minus_bsr       v iiiiIITIIT*I*I*T
bsr_maximum_bsr     v iiiiIITIIT*I*I*T
bsr_minimum_bsr     v iiiiIITIIT*I*I*T
bsr_ne_bsr          v iiiiIITIIT*I*I*B
bsr_lt_bsr          v iiiiIITIIT*I*I*B
bsr_gt_bsr          v iiiiIITIIT*I*I*B
bsr_le_bsr          v iiiiIITIIT*I*I*B
bsr_ge_bsr          v iiiiIITIIT*I*I*B
aZ  
csc_diagonal        v iiiIIT*T
csc_tocsr           v iiIIT*I*I*T
csc_matmat_maxnnz   l iiIIII
csc_matmat          v iiIITIIT*I*I*T
csc_matvec          v iiIITT*T
csc_matvecs         v iiiIITT*T
csc_elmul_csc       v iiIITIIT*I*I*T
csc_eldiv_csc       v iiIITIIT*I*I*T
csc_plus_csc        v iiIITIIT*I*I*T
csc_minus_csc       v iiIITIIT*I*I*T
csc_maximum_csc     v iiIITIIT*I*I*T
csc_minimum_csc     v iiIITIIT*I*I*T
csc_ne_csc          v iiIITIIT*I*I*B
csc_lt_csc          v iiIITIIT*I*I*B
csc_gt_csc          v iiIITIIT*I*I*B
csc_le_csc          v iiIITIIT*I*I*B
csc_ge_csc          v iiIITIIT*I*I*B
a  
csr_matmat_maxnnz   l iiIIII
csr_matmat          v iiIITIIT*I*I*T
csr_diagonal        v iiiIIT*T
csr_tocsc           v iiIIT*I*I*T
csr_tobsr           v iiiiIIT*I*I*T
csr_todense         v iiIIT*T
csr_matvec          v iiIITT*T
csr_matvecs         v iiiIITT*T
csr_elmul_csr       v iiIITIIT*I*I*T
csr_eldiv_csr       v iiIITIIT*I*I*T
csr_plus_csr        v iiIITIIT*I*I*T
csr_minus_csr       v iiIITIIT*I*I*T
csr_maximum_csr     v iiIITIIT*I*I*T
csr_minimum_csr     v iiIITIIT*I*I*T
csr_ne_csr          v iiIITIIT*I*I*B
csr_lt_csr          v iiIITIIT*I*I*B
csr_gt_csr          v iiIITIIT*I*I*B
csr_le_csr          v iiIITIIT*I*I*B
csr_ge_csr          v iiIITIIT*I*I*B
csr_scale_rows      v iiII*TT
csr_scale_columns   v iiII*TT
csr_sort_indices    v iI*I*T
csr_eliminate_zeros v ii*I*I*T
csr_sum_duplicates  v ii*I*I*T
get_csr_submatrix   v iiIITiiii*V*V*W
csr_row_index       v iIIIT*I*T
csr_row_slice       v iiiIIT*I*T
csr_column_index1   v iIiiII*I*I
csr_column_index2   v IIiIT*I*T
csr_sample_values   v iiIITiII*T
csr_count_blocks    i iiiiII
csr_sample_offsets  i iiIIiII*I
expandptr           v iI*I
test_throw_error    i
csr_has_sorted_indices    i iII
csr_has_canonical_format  i iII
z
coo_tocsr           v iiiIIT*I*I*T
coo_todense         v iilIIT*Ti
coo_matvec          v lIITT*T
dia_matvec          v iiiiITT*T
cs_graph_components i iII*I
ZbsrZcsrZcscother)Z	NPY_INT32Z	npy_int32)Z	NPY_INT64Z	npy_int64))ZNPY_BOOLZnpy_bool_wrapper)ZNPY_BYTEZnpy_byte)Z	NPY_UBYTEZ	npy_ubyte)Z	NPY_SHORTZ	npy_short)Z
NPY_USHORTZ
npy_ushort)ZNPY_INTZnpy_int)ZNPY_UINTZnpy_uint)ZNPY_LONGZnpy_long)Z	NPY_ULONGZ	npy_ulong)ZNPY_LONGLONGZnpy_longlong)ZNPY_ULONGLONGZnpy_ulonglong)Z	NPY_FLOATZ	npy_float)Z
NPY_DOUBLEZ
npy_double)ZNPY_LONGDOUBLEZnpy_longdouble)Z
NPY_CFLOATZnpy_cfloat_wrapper)ZNPY_CDOUBLEZnpy_cdouble_wrapper)ZNPY_CLONGDOUBLEZnpy_clongdouble_wrapperzf
static PY_LONG_LONG %(name)s_thunk(int I_typenum, int T_typenum, void **a)
{
    %(thunk_content)s
}
z
NPY_VISIBILITY_HIDDEN PyObject *
%(name)s_method(PyObject *self, PyObject *args)
{
    return call_thunk('%(ret_spec)s', "%(arg_spec)s", %(name)s_thunk, args);
}
z]
static int get_thunk_case(int I_typenum, int T_typenum)
{
    %(content)s;
    return -1;
}
c            	   	   C   s   g } g }d}d}t D ]\}}d}||t||d 7 }|||d|df |d7 }tD ]<\}}d}||t||d 7 }| |||||f |d7 }qT|d	7 }q|| tt|d
 fS )a  
    Get a list containing cartesian product of data types, plus a getter routine.

    Returns
    -------
    i_types : list [(j, I_typenum, None, I_type, None), ...]
         Pairing of index type numbers and the corresponding C++ types,
         and an unique index `j`. This is for routines that are parameterized
         only by I but not by T.
    it_types : list [(j, I_typenum, T_typenum, I_type, T_type), ...]
         Same as `i_types`, but for routines parameterized both by T and I.
    getter_code : str
         C++ code for a function that takes I_typenum, T_typenum and returns
         the unique index corresponding to the lists, or -1 if no match was
         found.

    r   z    if (0) {}zb
        else if (I_typenum == %(I_typenum)s) {
            if (T_typenum == -1) { return %(j)s; })	I_typenumjN   zC
            else if (T_typenum == %(T_typenum)s) { return %(j)s; })	T_typenumr   z

        })content)I_TYPESdictappendT_TYPESGET_THUNK_CASE_TEMPLATE)	it_typesi_typesr   getter_coder   I_typepiecer   T_type r   q/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/scipy/sparse/generate_sparsetools.pyget_thunk_type_set   s     

r   c                    s   |d }|dd   fdd}d}|D ]T\}}}}	}
||	|
}d}|dkrV|d	7 }n|d
7 }||t ||	|
|||| d 7 }q(|d7 }tt | |d }tt | | d }||fS )a3  
    Generate thunk and method code for a given routine.

    Parameters
    ----------
    name : str
        Name of the C++ routine
    args : str
        Argument list specification (in format explained above)
    types : list
        List of types to instantiate, as returned `get_thunk_type_set`

    r   r   Nc                    sB  g }d}d} D ]$}|rdnd}d}|dkr6d}qn|dkrV| d||  |f  n|d	krv| d
||  |f  n|dkr| d
|| |f  n|dkr| d|f  n~|dkr|rtd| d| |f  nV|dkr|rtd| d||f  n,|dkr | d||f  ntd|f |d7 }qd|S )zE
        Generate argument list for calling the C++ function
        Fr    zconst *Tiz*(%s*)a[%d]Iz
(%s*)a[%d]TBz(npy_bool_wrapper*)a[%d]Vz"'V' argument must be an output argz(std::vector<%s>*)a[%d]Wz"'W' argument must be an output arglz*(%snpy_int64*)a[%d]zInvalid spec character %rr   z, )r   
ValueErrorjoin)r   r   argsZnext_is_writeabler   tconstarg_specr   r   get_arglist  s<    



z"parse_routine.<locals>.get_arglistz>int j = get_thunk_case(I_typenum, T_typenum);
    switch (j) {z
        case %(j)s:vz?
            (void)%(name)s(%(arglist)s);
            return 0;z*
            return %(name)s(%(arglist)s);)r   r   r   r   r   arglistnamezb
    default:
        throw std::runtime_error("internal error: invalid argument typenums");
    })r*   thunk_content)r*   ret_specr&   )r
   THUNK_TEMPLATEMETHOD_TEMPLATE)r*   r"   typesr,   r'   r+   r   r   r   r   r   r)   r   Z
thunk_codeZmethod_coder   r%   r   parse_routine   s.    &

r0   c                  C   s  t jtp
d d} | jddddd |  \}}g }t \}}}tD ]\}}g }	g }
| D ]}| }|r`|	dr|q`z|
d d	\}}W n4 ty } ztd
|f |W Y d }~n
d }~0 0 d|
 }d|v sd|v rt|||\}}nt|||\}}||v rtd|f || |	| |
| q`tjtjtd|d }tt|sn|jrtd|f  t|dN}t| || |	D ]}|| q|
D ]}|| qW d    n1 s0    Y  qFtd|f  qFd}|D ]}|d|f 7 }q d}|D ]}|dt|d 7 }q|d7 }tjtjtdd}tt|sl|jrtd|f  t|d,}t| || || W d    n1 s0    Y  ntd|f  d S )Nr   )usagez
--no-forcestore_falseforceT)actiondestdefault#r   zMalformed line: %rr#   r   zDuplicate routine %rZsparsetoolsz_impl.hz$[generate_sparsetools] generating %rwz,[generate_sparsetools] %r already up-to-datezCNPY_VISIBILITY_HIDDEN PyObject *%s_method(PyObject *, PyObject *);
z4
static struct PyMethodDef sparsetools_methods[] = {zH
        {"%(name)s", (PyCFunction)%(name)s_method, METH_VARARGS, NULL},)r*   z%
        {NULL, NULL, 0, NULL}
    };zsparsetools_impl.h)optparseOptionParser__doc__strip
add_option
parse_argsr   COMPILATION_UNITS
splitlines
startswithsplitr    r!   r0   r   ospathdirname__file__r   r3   printopenwrite_autogen_blurbwriter
   )poptionsr"   namesr   r   r   Z	unit_nameZroutinesZthunksmethodsliner*   eZthunkmethoddstfZmethod_defsZmethod_structr   r   r   mainN  sz    &



0

,rT   c                 C   s   |  d d S )Nzh/* This file is autogenerated by generate_sparsetools.py
 * Do not edit manually or check into VCS.
 */
)rJ   )streamr   r   r   rI     s    rI   __main__)r;   r9   rC   distutils.dep_utilr   ZBSR_ROUTINESZCSC_ROUTINESZCSR_ROUTINESZOTHER_ROUTINESr?   r	   r   r-   r.   r   r   r0   rT   rI   __name__r   r   r   r   <module>   s2   	(
0ZS