def _get_key_ranges(key, mask): """ Get a generator of base_key, n_keys pairs that represent ranges allowed by the mask :param key: The base key :param mask: The mask """ unwrapped_mask = utility_calls.expand_to_bit_array(mask) first_zeros = list() remaining_zeros = list() pos = len(unwrapped_mask) - 1 # Keep the indices of the first set of zeros while pos >= 0 and unwrapped_mask[pos] == 0: first_zeros.append(pos) pos -= 1 # Find all the remaining zeros while pos >= 0: if unwrapped_mask[pos] == 0: remaining_zeros.append(pos) pos -= 1 # Loop over 2^len(remaining_zeros) to produce the base key, # with n_keys being 2^len(first_zeros) n_sets = 2 ** len(remaining_zeros) n_keys = 2 ** len(first_zeros) unwrapped_key = utility_calls.expand_to_bit_array(key) for value in xrange(n_sets): generated_key = numpy.copy(unwrapped_key) unwrapped_value = utility_calls.expand_to_bit_array(value)[ -len(remaining_zeros):] generated_key[remaining_zeros] = unwrapped_value yield utility_calls.compress_from_bit_array(generated_key), n_keys
def _get_key_ranges(key, mask): """ Get a generator of base_key, n_keys pairs that represent ranges allowed by the mask :param key: The base key :param mask: The mask """ unwrapped_mask = utility_calls.expand_to_bit_array(mask) first_zeros = list() remaining_zeros = list() pos = len(unwrapped_mask) - 1 # Keep the indices of the first set of zeros while pos >= 0 and unwrapped_mask[pos] == 0: first_zeros.append(pos) pos -= 1 # Find all the remaining zeros while pos >= 0: if unwrapped_mask[pos] == 0: remaining_zeros.append(pos) pos -= 1 # Loop over 2^len(remaining_zeros) to produce the base key, # with n_keys being 2^len(first_zeros) n_sets = 2**len(remaining_zeros) n_keys = 2**len(first_zeros) unwrapped_key = utility_calls.expand_to_bit_array(key) for value in xrange(n_sets): generated_key = numpy.copy(unwrapped_key) unwrapped_value = utility_calls.expand_to_bit_array( value)[-len(remaining_zeros):] generated_key[remaining_zeros] = unwrapped_value yield utility_calls.compress_from_bit_array(generated_key), n_keys
def __init__(self, fixed_mask, fields, free_space_list): self._fixed_mask = fixed_mask self._is_next_key = True self._free_space_list = free_space_list self._free_space_pos = 0 self._next_key_read = False expanded_mask = utility_calls.expand_to_bit_array(fixed_mask) zeros = numpy.where(expanded_mask == 0)[0] self._n_mask_keys = 2 ** len(zeros) # If there are no fields, add the mask as a field the_fields = fields if fields is None or len(fields) == 0: n_ones = 32 - len(zeros) field_max = (2 ** n_ones) - 1 the_fields = [Field(0, field_max, fixed_mask)] # Check that the fields don't cross each other for field in the_fields: for other_field in the_fields: if field != other_field and field.mask & other_field.mask != 0: raise PacmanRouteInfoAllocationException( "Field masks {} and {} overlap".format( field.mask, other_field.mask)) # Sort the fields by highest bit range first self._fields = sorted(the_fields, key=lambda field: field.mask, reverse=True) self._update_next_valid_fields() self._increment_space_until_valid_key()
def __init__(self, fixed_mask, fields, free_space_list): self._fixed_mask = fixed_mask self._is_next_key = True self._free_space_list = free_space_list self._free_space_pos = 0 self._next_key_read = False expanded_mask = utility_calls.expand_to_bit_array(fixed_mask) zeros = numpy.where(expanded_mask == 0)[0] self._n_mask_keys = 2 ** len(zeros) # If there are no fields, add the mask as a field the_fields = fields if fields is None or len(fields) == 0: n_ones = 32 - len(zeros) field_max = (2 ** n_ones) - 1 the_fields = [Field(0, field_max, fixed_mask)] # Check that the fields don't cross each other for field in the_fields: for other_field in the_fields: if field != other_field and field.mask & other_field.mask != 0: raise PacmanRouteInfoAllocationException( "Field masks {} and {} overlap".format( field.mask, other_field.mask)) # Sort the fields by highest bit range first self._fields = sorted(the_fields, key=lambda field: field.value, reverse=True) self._update_next_valid_fields() self._increment_space_until_valid_key()
def _update_next_valid_fields(self): # Find the next valid key for the general mask min_key = self._free_space_list[self._free_space_pos].start_address if min_key & self._fixed_mask != min_key: min_key = (min_key + self._n_mask_keys) & self._fixed_mask # Generate a set of indices of ones for each field, and then store # the current value of each field given the minimum key (even if the # value might be out of range for the key - see later for fix for this) self._field_ones = dict() self._field_value = dict() for field in self._fields: expanded_mask = utility_calls.expand_to_bit_array(field.mask) field_ones = numpy.where(expanded_mask == 1)[0] self._field_ones[field] = field_ones field_min_key = min_key & field.mask field_min_value = utility_calls.compress_bits_from_bit_array( utility_calls.expand_to_bit_array(field_min_key), field_ones) self._field_value[field] = field_min_value # Update the values (other than the top value) to be valid for field_no in reversed(range(1, len(self._fields))): field = self._fields[field_no] previous_field = self._fields[field_no - 1] # If this value is too small, set it to its minimum if self._field_value[field] < field.lo: self._field_value[field] = field.lo # If this value is too large, set it to its minimum # and up the value of the next field if self._field_value[field] > field.hi: self._field_value[field] = field.lo self._field_value[previous_field] += 1 # If the top value is above its valid range, there are no valid keys top_field = self._fields[0] if self._field_value[top_field] > top_field.hi: self._is_next_key = False # If the top value is below its valid range, set it to the first valid # value if self._field_value[top_field] < top_field.lo: self._field_value[top_field] = top_field.lo
def _update_next_valid_fields(self): # Find the next valid key for the general mask min_key = self._free_space_list[self._free_space_pos].start_address if min_key & self._fixed_mask != min_key: min_key = (min_key + self._n_mask_keys) & self._fixed_mask # Generate a set of indices of ones for each field, and then store # the current value of each field given the minimum key (even if the # value might be out of range for the key - see later for fix for this) self._field_ones = dict() self._field_value = dict() for field in self._fields: expanded_mask = utility_calls.expand_to_bit_array(field.value) field_ones = numpy.where(expanded_mask == 1)[0] self._field_ones[field] = field_ones field_min_key = min_key & field.value field_min_value = utility_calls.compress_bits_from_bit_array( utility_calls.expand_to_bit_array(field_min_key), field_ones) self._field_value[field] = field_min_value # Update the values (other than the top value) to be valid for field_no in reversed(range(1, len(self._fields))): field = self._fields[field_no] previous_field = self._fields[field_no - 1] # If this value is too small, set it to its minimum if self._field_value[field] < field.lo: self._field_value[field] = field.lo # If this value is too large, set it to its minimum # and up the value of the next field if self._field_value[field] > field.hi: self._field_value[field] = field.lo self._field_value[previous_field] += 1 # If the top value is above its valid range, there are no valid keys top_field = self._fields[0] if self._field_value[top_field] > top_field.hi: self._is_next_key = False # If the top value is below its valid range, set it to the first valid # value if self._field_value[top_field] < top_field.lo: self._field_value[top_field] = top_field.lo
def convert_mask_into_fields(entity): """ :param entity: :return: """ results = list() expanded_mask = utility_calls.expand_to_bit_array(entity) # set up for first location detected_change_position = NUM_BITS_IN_ROUTING detected_last_state = expanded_mask[NUM_BITS_IN_ROUTING] # iterate up the key looking for fields for position in range(NUM_BITS_IN_ROUTING - 1, START_OF_ROUTING_KEY_POSITION - 2, -1): # check for last bit iteration if position == -1: # if last bit has changed, create new field if detected_change_position != position: # create field with correct routing tag if detected_last_state == ROUTING_MASK_BIT: results.append( Field(NUM_BITS_IN_ROUTING - detected_change_position, NUM_BITS_IN_ROUTING, entity, SUPPORTED_TAGS.ROUTING.name)) else: results.append( Field(NUM_BITS_IN_ROUTING - detected_change_position, NUM_BITS_IN_ROUTING, entity, SUPPORTED_TAGS.APPLICATION.name)) else: # check for bit iteration if expanded_mask[position] != detected_last_state: # if changed state, a field needs to be created. check for # which type of field to support if detected_last_state == ROUTING_MASK_BIT: results.append( Field(NUM_BITS_IN_ROUTING - detected_change_position, NUM_BITS_IN_ROUTING - (position + 1), entity, SUPPORTED_TAGS.ROUTING.name)) else: results.append( Field(NUM_BITS_IN_ROUTING - detected_change_position, NUM_BITS_IN_ROUTING - (position + 1), entity, SUPPORTED_TAGS.APPLICATION.name)) # update positions detected_last_state = expanded_mask[position] detected_change_position = position return results
def _get_next_key(self): # Form the key from the value of the fields expanded_key = numpy.zeros(32, dtype="uint8") for field in self._fields: field_ones = self._field_ones[field] expanded_value = expand_to_bit_array(self._field_value[field]) expanded_key[field_ones] = expanded_value[-len(field_ones):] key = compress_from_bit_array(expanded_key) # Return the generated key return key
def _get_next_key(self): # Form the key from the value of the fields expanded_key = numpy.zeros(32, dtype="uint8") for field in self._fields: field_ones = self._field_ones[field] expanded_value = utility_calls.expand_to_bit_array( self._field_value[field]) expanded_key[field_ones] = expanded_value[-len(field_ones):] key = utility_calls.compress_from_bit_array(expanded_key) # Return the generated key return key
def __init__(self, fixed_mask, fields, free_space_list): """ :param int fixed_mask: :param fields: :type fields: list(Field) or None :param list(ElementFreeSpace) free_space_list: """ self._fixed_mask = fixed_mask self._is_next_key = True self._free_space_list = free_space_list self._free_space_pos = 0 self._next_key_read = False self._field_ones = dict() self._field_value = dict() expanded_mask = expand_to_bit_array(fixed_mask) zeros = numpy.where(expanded_mask == 0)[0] self._n_mask_keys = 2 ** len(zeros) # If there are no fields, add the mask as a field the_fields = fields if fields is None or not fields: n_ones = 32 - len(zeros) field_max = (2 ** n_ones) - 1 the_fields = [Field(0, field_max, fixed_mask)] # Check that the fields don't cross each other for idx, field in enumerate(the_fields): for other_field in the_fields[idx+1:]: if field != other_field and field.mask & other_field.mask != 0: raise PacmanRouteInfoAllocationException( "Field masks {} and {} overlap".format( field.mask, other_field.mask)) # Sort the fields by highest bit range first self._fields = sorted(the_fields, key=lambda field: field.value, reverse=True) self._update_next_valid_fields() self._increment_space_until_valid_key()