source: codes/icosagcm/devel/Python/src/cxios.pyx @ 694

Last change on this file since 694 was 694, checked in by dubos, 6 years ago

devel/unstructured : higher-level interface to XIOS

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