def getContributeInfo(self, ep, contribution, contributor): reducer_type, data, c_type = contribution if reducer_type == self.ReducerType.external_py: numElems = len(data) c_data = ffi.from_buffer(data) # this avoids a copy c_data_size = numElems * ffi.sizeof('char') elif reducer_type != self.ReducerType.nop: t = type(data) if t == numpy.ndarray or isinstance(data, numpy.number): c_data = ffi.from_buffer(data) # get pointer to data, no copy c_data_size = data.nbytes numElems = data.size elif t == array.array: c_data = ffi.from_buffer(data) # get pointer to data, no copy c_data_size = data.buffer_info()[1] * data.itemsize numElems = len(data) else: dataTypeTuple = c_type_table[c_type] numElems = len(data) # this copies and convert data to C array of C type c_data = ffi.new(dataTypeTuple[1], data) c_data_size = numElems * dataTypeTuple[3] else: c_data = ffi.NULL c_data_size = numElems = 0 c_info = contributor._contributeInfo c_struct = c_info.data c_struct.cbEpIdx = ep c_struct.data = c_info.c_data = c_data c_struct.numelems = numElems c_struct.dataSize = c_info.dataSize = c_data_size c_struct.redType = reducer_type return c_info
def __init__(self, args): # Need to save these cdata objects or they will be deleted. Simply putting them # in the 'struct ContributeInfo' is not enough self.c_data = args[1] self.dataSize = args[3] self.c_idx = args[6] self.data = ffi.new("struct ContributeInfo*", args)
def __init__(self, _charm, opts, libcharm_path): global charm, ReducerType, c_type_table, times self.direct_copy_supported = (sys.version_info[0] >= 3 ) # requires Python 3 charm = _charm self.name = 'cffi' self.chareNames = [] self.init() ReducerType = ffi.cast('struct CkReductionTypesExt*', lib.getReducersStruct()) self.ReducerType = ReducerType times = [ 0.0 ] * 3 # track time in [charm reduction callbacks, custom reduction, outgoing object migration] self.times = times self.send_bufs = ffi.new( "char*[]", 60) # supports up to 60 direct-copy entry method arguments self.send_buf_sizes = ffi.new("int[]", [0] * 60) c_type_table = [None] * 10 c_type_table[red.C_CHAR] = ('char', 'char[]', 'char*', ffi.sizeof('char')) c_type_table[red.C_SHORT] = ('short', 'short[]', 'short*', ffi.sizeof('short')) c_type_table[red.C_INT] = ('int', 'int[]', 'int*', ffi.sizeof('int')) c_type_table[red.C_LONG] = ('long', 'long[]', 'long*', ffi.sizeof('long')) c_type_table[red.C_UCHAR] = ('unsigned char', 'unsigned char[]', 'unsigned char*', ffi.sizeof('unsigned char')) c_type_table[red.C_USHORT] = ('unsigned short', 'unsigned short[]', 'unsigned short*', ffi.sizeof('unsigned short')) c_type_table[red.C_UINT] = ('unsigned int', 'unsigned int[]', 'unsigned int*', ffi.sizeof('unsigned int')) c_type_table[red.C_ULONG] = ('unsigned long', 'unsigned long[]', 'unsigned long*', ffi.sizeof('unsigned long')) c_type_table[red.C_FLOAT] = ('float', 'float[]', 'float*', ffi.sizeof('float')) c_type_table[red.C_DOUBLE] = ('double', 'double[]', 'double*', ffi.sizeof('double'))
def initContributeInfo(self, elemId, index, elemType): if type(index) == int: index = (index, ) c_elemIdx = ffi.new('int[]', index) return ContributeInfo( (-1, ffi.NULL, 0, 0, self.ReducerType.nop, elemId, c_elemIdx, len(index), elemType))
def start(self): argv_bufs = [ffi.new("char[]", arg.encode()) for arg in sys.argv] lib.StartCharmExt(len(sys.argv), argv_bufs)
def CkRegisterArray(self, name, numEntryMethods): self.chareNames.append(ffi.new("char[]", name.encode())) chareIdx, startEpIdx = ffi.new("int*"), ffi.new("int*") lib.CkRegisterArrayExt(self.chareNames[-1], numEntryMethods, chareIdx, startEpIdx) return chareIdx[0], startEpIdx[0]