[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": |
---|
[630] | 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) |
---|
[615] | 16 | |
---|
[630] | 17 | def context_close_definition(): cxios_context_close_definition() |
---|
| 18 | def context_finalize(): cxios_context_finalize() |
---|
| 19 | def finalize(): cxios_finalize() |
---|
| 20 | |
---|
| 21 | cdef send_field1(char* id, int idlen, double[:] data): cxios_write_data_k81(id, idlen, &data[0], data.shape[0]) |
---|
| 22 | cdef send_field2(char* id, int idlen, double[:,:] data): cxios_write_data_k82(id, idlen, &data[0,0], data.shape[0],data.shape[1]) |
---|
| 23 | cdef 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 | |
---|
| 25 | def 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 | |
---|
[615] | 34 | # -------------------------------------------------------- # |
---|
| 35 | |
---|
| 36 | lib=wrap.Struct() |
---|
| 37 | cxios = wrap.SharedLib(vars(lib), "libxios.so", prefix_so='cxios_') |
---|
| 38 | |
---|
| 39 | class Duration(Structure): |
---|
| 40 | _fields_ = [(name, c_double) for name in ('year', 'month', 'day', 'hour', 'minute', 'second', 'timestep') ] |
---|
| 41 | class Date(Structure): |
---|
| 42 | _fields_ = [(name, c_int) for name in ('year', 'month', 'day', 'hour', 'minute', 'second') ] |
---|
| 43 | |
---|
| 44 | print Duration.from_param |
---|
| 45 | |
---|
| 46 | for x in c_void_p_byref, Duration, Date : wrap.py2c[x]=wrap.noop # accept arguments of type (void*)&, Duration, ... |
---|
| 47 | |
---|
| 48 | def SHAPE(data): return np.asarray(list(reversed(data.shape)),c_int) # reverse shape to follow Fortran convention |
---|
| 49 | |
---|
| 50 | class 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 | |
---|
| 82 | def 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 | |
---|
| 94 | def 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 | |
---|
| 108 | import_cxios_functions() |
---|