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