source: codes/icosagcm/devel/Python/src/xios.pyx @ 630

Last change on this file since 630 was 630, checked in by dubos, 7 years ago

devel/Python : more cythonic interface to XIOS

File size: 4.8 KB
Line 
1import numpy as np
2import dynamico.wrap as wrap
3from ctypes import c_int, c_double, c_bool, c_void_p, c_char_p, byref, POINTER, Structure
4c_void_pp=POINTER(c_void_p) # used in prototype
5c_void_p_byref=type(byref(c_void_p())) # used in py2c because byref creates an object of this type, not c_void_pp
6
7# ------------- Direct cython interfaces ----------------- #
8
9cdef extern from "functions.h":
10     cdef void cxios_context_close_definition()
11     cdef void cxios_context_finalize()
12     cdef void cxios_finalize()
13     cdef void cxios_write_data_k81(char*, int, double*, int)
14     cdef void cxios_write_data_k82(char*, int, double*, int,int)
15     cdef void cxios_write_data_k83(char*, int, double*, int,int,int)
16
17def context_close_definition(): cxios_context_close_definition()
18def context_finalize(): cxios_context_finalize()
19def finalize(): cxios_finalize()
20
21cdef send_field1(char* id, int idlen, double[:] data):     cxios_write_data_k81(id, idlen, &data[0],     data.shape[0])
22cdef send_field2(char* id, int idlen, double[:,:] data):   cxios_write_data_k82(id, idlen, &data[0,0],   data.shape[0],data.shape[1])
23cdef send_field3(char* id, int idlen, double[:,:,:] data): cxios_write_data_k83(id, idlen, &data[0,0,0], data.shape[0],data.shape[1],data.shape[2])
24
25def send_field(bytes id, data):
26    cdef char* idptr = id
27    cdef int idlen = len(id)
28    print 'cxios.write_data', id, data.shape
29    ndim=data.ndim
30    if ndim==1: send_field1(idptr,idlen,data)
31    if ndim==2: send_field2(idptr,idlen,data)
32    if ndim==3: send_field3(idptr,idlen,data)
33
34# -------------------------------------------------------- #
35
36lib=wrap.Struct()
37cxios = wrap.SharedLib(vars(lib), "libxios.so", prefix_so='cxios_')
38
39class Duration(Structure):
40    _fields_ = [(name, c_double) for name in ('year', 'month', 'day', 'hour', 'minute', 'second', 'timestep') ]
41class Date(Structure):
42    _fields_ = [(name, c_int) for name in ('year', 'month', 'day', 'hour', 'minute', 'second') ]
43
44print Duration.from_param
45
46for x in c_void_p_byref, Duration, Date : wrap.py2c[x]=wrap.noop # accept arguments of type (void*)&, Duration, ...
47
48def SHAPE(data): return np.asarray(list(reversed(data.shape)),c_int) # reverse shape to follow Fortran convention
49
50class Handle:
51    def __init__(self, cat, id=None):
52        self.handle = c_void_p()
53        if id is None:
54            id='default'
55            create_fun = cxios.vardict['get_current_'+cat]
56            create_fun(byref(self.handle))
57        else:
58            create_fun = cxios.vardict[cat+'_handle_create']
59            create_fun(byref(self.handle), id, c_int(len(id)))
60        self.cat, self.prefix_set, self.id = cat, 'set_'+cat+'_', id
61        print 'Handle', cat, self.id, self.handle
62    def set_attr(self, **kwargs):
63        prefix, handle = self.prefix_set, self.handle
64        for key, value in kwargs.iteritems():
65            fun = cxios.vardict[prefix+key]
66            extra=value
67            if type(value) in (int,c_int):
68                fun(handle,c_int(value))
69            elif type(value) is np.ndarray:
70                extra=SHAPE(value)
71                fun(handle,value,extra)
72            elif type(value) is str:
73                fun(handle,value,c_int(len(value)))
74            elif type(value) in (Duration, Date):
75                fun(handle,value)
76            else:
77                raise(TypeError)
78            print self.id+'.'+prefix+key, type(value), extra
79    def update_timestep(self):
80        lib.update_calendar_timestep(self.handle)
81
82def import_set_attr(cats, *args): #attr_int, attr_array, attr_str):
83    for arg in args:
84        argtype = arg.pop(0)
85        if argtype is str:
86            argtype = [c_void_p, c_char_p, c_int] #char *str, int strlen
87        elif argtype is np.ndarray:
88            argtype = [c_void_p, c_void_p, c_void_p] # void *handle, double *data, int* SHAPE(data)
89        else:
90            argtype = [c_void_p, argtype] #void *handle, argtype data
91        for cat in cats:
92            cxios.import_funs( [arg + argtype], prefix='set_'+cat+'_')
93
94def import_cxios_functions():
95    cats=['axis','domain','domaingroup','field','fieldgroup'] # XIOS categories
96    cxios.import_funs([
97                       [cat+'_handle_create' for cat in cats]+[c_void_pp,c_char_p,c_int],
98                       ['get_current_'+'calendar_wrapper',c_void_pp],
99                       ['update_calendar_timestep',c_void_p],
100                       ['update_calendar',c_int] ])
101
102    import_set_attr(['domain','domaingroup'], [c_int,'ni_glo','ibegin','ni','nvertex','data_dim'], [str,'type'],
103                        [np.ndarray, 'i_index','lonvalue_1d','latvalue_1d','bounds_lat_1d','bounds_lon_1d'])
104    import_set_attr(['field','fieldgroup'], [Duration,'freq_op','freq_offset'])
105    import_set_attr(['axis'], [c_int,'n_glo'], [np.ndarray,'value'])
106    import_set_attr(['calendar_wrapper'], [Duration,'timestep'])
107
108import_cxios_functions()
Note: See TracBrowser for help on using the repository browser.