def raw_receive(x, source, tag=0, vanilla=0): """Wrapper for raw MPI receive. Receive something of same size as x from source with tag. Automatically determine appropriate protocol and call corresponding receive function. The variable x can be any (picklable) type, but Numeric variables and text strings will most efficient. Setting vanilla = 1 forces vanilla mode for any type. """ protocol = get_control_info(x, vanilla)[0] if protocol == 'array': err, stat = receive_array(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_array failed with error code %d' % err elif protocol == 'string': err, stat = receive_string(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_string failed with error code %d' % err else: x = receive_vanilla(x, source, tag) return x
def raw_receive(x, source, tag=0, vanilla=0): """Wrapper for raw MPI receive. Receive something of same size as x from source with tag. Automatically determine appropriate protocol and call corresponding receive function. The variable x can be any (picklable) type, but Numeric variables and text strings will most efficient. Setting vanilla = 1 forces vanilla mode for any type. """ protocol = get_control_info(x, vanilla)[0] if protocol == 'array': err, stat = receive_array(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_array failed with error code %d' %err elif protocol == 'string': err, stat = receive_string(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_string failed with error code %d' %err else: x = receive_vanilla(x, source, tag) return x
def receive_control_info(source, return_source=False): """Receive control info from source The optional argument (due to Jim Bosch) also returns the actual source node which can be used to require that the data message come from the same node. """ # FIXME (Ole): Perhaps we should include actual source in the control info? import string msg = ' ' * control_data_max_size stat = receive_string(msg, source, control_tag) # No need to create status object here - it is reserved # for payload communications only msg = msg[:stat[3]] # Trim buffer to actual received length (needed?) control_info = msg.split(control_sep) assert len(control_info) == 4, 'len(control_info) = %d' % len(control_info) control_info[2] = eval(control_info[2]) # Convert back to int control_info[3] = eval(control_info[3]) # Convert back to tuple if return_source: return control_info, int(stat[0]) else: return control_info
def receive_control_info(source, return_source=False): """Receive control info from source The optional argument (due to Jim Bosch) also returns the actual source node which can be used to require that the data message come from the same node. """ # FIXME (Ole): Perhaps we should include actual source in the control info? import string msg = ' '*control_data_max_size stat = receive_string(msg, source, control_tag) # No need to create status object here - it is reserved # for payload communications only msg = msg[:stat[3]] # Trim buffer to actual received length (needed?) control_info = msg.split(control_sep) assert len(control_info) == 4, 'len(control_info) = %d' %len(control_info) control_info[2] = eval(control_info[2]) # Convert back to int control_info[3] = eval(control_info[3]) # Convert back to tuple if return_source: return control_info, int(stat[0]) else: return control_info
def receive(source, tag=0): """Wrapper for easy MPI receive. Receive data from source with tag. Assumes preceding message containing protocol, type, size. Create appropriate buffer and receive data. """ control_info = receive_control_info(source) protocol = control_info[0] typecode = control_info[1] size = control_info[2] if protocol == 'array': import Numeric x = Numeric.zeros(size, typecode) err, stat = receive_array(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_array failed with error code %d' % err elif protocol == 'string': x = ' ' * size err, stat = receive_string(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_string failed with error code %d' % err elif protocol == 'vanilla': from cPickle import loads s = ' ' * size err, stat = receive_string(s, source, tag) if not err: status.set_values(stat) else: raise 'receive_string failed with error code %d' % err x = loads(s) else: raise "Unknown values for protocol: %s" % protocol return x
def receive(source, tag=0): """Wrapper for easy MPI receive. Receive data from source with tag. Assumes preceding message containing protocol, type, size. Create appropriate buffer and receive data. """ control_info = receive_control_info(source) protocol = control_info[0] typecode = control_info[1] size = control_info[2] if protocol == 'array': import Numeric x = Numeric.zeros(size,typecode) err, stat = receive_array(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_array failed with error code %d' %err elif protocol == 'string': x = ' '*size err, stat = receive_string(x, source, tag) if not err: status.set_values(stat) else: raise 'receive_string failed with error code %d' %err elif protocol == 'vanilla': from cPickle import loads s = ' '*size err, stat = receive_string(s, source, tag) if not err: status.set_values(stat) else: raise 'receive_string failed with error code %d' %err x = loads(s) else: raise "Unknown values for protocol: %s" %protocol return x
def receive_control_info(source): """Receive control info from source """ import string msg = ' ' * control_data_max_size err, stat = receive_string(msg, source, control_tag) if err: raise Exception #NB: Do not set status block here control_info = msg.split(',') assert len(control_info) == 3 control_info[2] = int(control_info[2]) return control_info
def receive_control_info(source): """Receive control info from source """ import string msg = ' '*control_data_max_size err, stat = receive_string(msg, source, control_tag) if err: raise Exception #NB: Do not set status block here control_info = msg.split(',') assert len(control_info) == 3 control_info[2] = int(control_info[2]) return control_info
def receive_control_info(source): """Receive control info from source """ import string msg = ' ' * control_data_max_size stat = receive_string(msg, source, control_tag) #No need to create status object here - it is reserved #for payload communications only msg = msg[:stat[3]] #Trim buffer to actual received length (needed?) control_info = msg.split(control_sep) assert len(control_info) == 4, 'len(control_info) = %d' % len(control_info) control_info[2] = eval(control_info[2]) #Convert back to int control_info[3] = eval(control_info[3]) #Convert back to tuple return control_info
def receive_control_info(source): """Receive control info from source """ import string msg = ' '*control_data_max_size stat = receive_string(msg, source, control_tag) #No need to create status object here - it is reserved #for payload communications only msg = msg[:stat[3]] #Trim buffer to actual received length (needed?) control_info = msg.split(control_sep) assert len(control_info) == 4, 'len(control_info) = %d' %len(control_info) control_info[2] = eval(control_info[2]) #Convert back to int control_info[3] = eval(control_info[3]) #Convert back to tuple return control_info
def receive(source, buffer=None, vanilla=False, tag=default_tag, return_status=False, bypass=False): """receive - blocking MPI receive Receive data from source. Optional parameters: buffer: Use specified buffer for received data (faster). Default None. vanilla: Specify to enforce vanilla protocol for any type. Default False tag: Only received messages tagged as specified. Default default_tag return_status: Return Status object along with result. Default False. If no buffer is specified, receive will try to receive a preceding message containing protocol, type, size and shape and then create a suitable buffer. If buffer is specified the corresponding send must specify use_buffer = True. The variable buffer can be any (picklable) type, but numpy variables and text strings will most efficient. Appropriate protocol will be automatically determined and corresponding receive function called. If bypass is True, all admin and error checks get bypassed to reduce the latency. Should only be used for receiving numpy arrays and should be matched with a bypass in the corresponding send command. Also buffer must be specified. """ if bypass: # errmsg = 'bypass mode must be used with specified buffer' # assert buffer is not None, msg stat = receive_array(buffer, source, tag) else: import types # Input check errmsg = 'Source id (%s) must be an integer.' % source assert type(source) == types.IntType, errmsg errmsg = 'Tag %d is reserved by pypar - please use another.'\ % control_tag assert tag != control_tag, errmsg # Either receive or create metadata about object to receive if buffer is None: control_info, source = receive_control_info(source, return_source=True) protocol, typecode, size, shape = control_info else: protocol, typecode, size, shape = create_control_info( buffer, vanilla) # Receive payload data if protocol == 'array': if buffer is None: buffer = zeros(size, typecode) buffer = reshape(buffer, shape) stat = receive_array(buffer, source, tag) elif protocol == 'string': if buffer is None: buffer = ' ' * size stat = receive_string(buffer, source, tag) elif protocol == 'vanilla': from cPickle import dumps, loads, UnpicklingError if buffer is None: s = ' ' * size else: s = dumps(buffer, protocol=2) s = s + ' ' * int(0.1 * len(s)) #safety stat = receive_string(s, source, tag) try: buffer = loads(s) #Replace buffer with received result except UnpicklingError, err: raise UnpicklingError(str(err) + " - '%s'" % s) else:
def receive(source, buffer=None, vanilla=False, tag=default_tag, return_status=False, bypass=False): """receive - blocking MPI receive Receive data from source. Optional parameters: buffer: Use specified buffer for received data (faster). Default None. vanilla: Specify to enforce vanilla protocol for any type. Default False tag: Only received messages tagged as specified. Default default_tag return_status: Return Status object along with result. Default False. If no buffer is specified, receive will try to receive a preceding message containing protocol, type, size and shape and then create a suitable buffer. If buffer is specified the corresponding send must specify use_buffer = True. The variable buffer can be any (picklable) type, but numpy variables and text strings will most efficient. Appropriate protocol will be automatically determined and corresponding receive function called. If bypass is True, all admin and error checks get bypassed to reduce the latency. Should only be used for receiving numpy arrays and should be matched with a bypass in the corresponding send command. Also buffer must be specified. """ if bypass: #errmsg = 'bypass mode must be used with specified buffer' #assert buffer is not None, msg stat = receive_array(buffer, source, tag) else: import types #Input check errmsg = 'Source id (%s) must be an integer.' %source assert type(source) == types.IntType, errmsg errmsg = 'Tag %d is reserved by pypar - please use another.' %control_tag assert tag != control_tag, errmsg #Either receive or create metadata about objetc to receive if buffer is None: protocol, typecode, size, shape = receive_control_info(source) else: protocol, typecode, size, shape = create_control_info(buffer, vanilla) #Receive payload data if protocol == 'array': if buffer is None: buffer = zeros(size,typecode) buffer = reshape(buffer, shape) stat = receive_array(buffer, source, tag) elif protocol == 'string': if buffer is None: buffer = ' '*size stat = receive_string(buffer, source, tag) elif protocol == 'vanilla': from cPickle import dumps, loads if buffer is None: s = ' '*size else: s = dumps(buffer, 1) s = s + ' '*int(0.1*len(s)) #safety stat = receive_string(s, source, tag) buffer = loads(s) #Replace buffer with received result else: raise 'Unknown protocol: %s' %protocol # Return received data and possibly the status object if return_status: return buffer, Status(stat) else: return buffer