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
Esempio n. 2
0
    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
Esempio n. 3
0
    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()
Esempio n. 5
0
    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
Esempio n. 8
0
    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
Esempio n. 9
0
    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
Esempio n. 10
0
    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()