def __init__(self):
        """
        Initializes the tables.
        
        The q-values are initialized to a value of 10 since 10 seemed like an
        average q-value after the first 100000 iterations of training.
        
        The visits are initialized to zero since no actions have been taken 
        yet.

        The same_locs table is initalized to all 0s except for the first 
        column which is all 1s. The first column corresponds to the actions 
        ['O', 'O', ..., 'O'] which will never change the locations of 
        robots/stacks.
        
        Many times these tables are overwritten by csvs that have been saved
        after many iterations of training.
    
        Returns
        -------
        None.

        """
        num_states = (nCr(N_ROWS*N_COLS+1, N_ROBOTS) 
                      * nCr(N_ROWS*N_COLS+1, N_STACKS)    
                      * (N_ITEMS+1)**N_STACKS)
        num_actions = len(Actions().valid_actions)**N_ROBOTS
        
        self.qvals = np.ones((num_states, num_actions)) * (N_ROWS + N_COLS - 1) * N_STACKS
        self.visits = np.zeros((num_states, num_actions))
        self.same_locs = np.concatenate((np.ones((1, num_states)), 
                                         np.zeros((num_actions-1, num_states)))).transpose()
        self.performance = pd.DataFrame([], columns=['iters', 'score'])
        return
Beispiel #2
0
    def enum(self):
        """
        Enumerates the state by assigning a unique number to each state.
        
        First, enumerate the locations of the robots and multiply this value 
        by the number of possible locations of stacks and possible orders 
        values. Second, enumerate the locations of the stacks and multiply
        this value by the number of possible orders values. Last, enumerate 
        the number of possible orders values. Add all these together to get 
        the final enumeration of the state.
        
        
        Returns
        -------
        int
            The enumeration of the state.

        """
        ## enumerate the location of robots
        enum_robots = 0
        locations = copy.deepcopy(self.valid_locations)
        for i in range(N_ROBOTS):
            idx = locations.index(self.robot_locs[i])
            if i == N_ROBOTS - 1:
                enum_robots += idx
            else:
                locations = locations[1:]
                for j in range(idx):
                    enum_robots += nCr(len(locations), N_ROBOTS - i - 1)
                    locations = locations[1:]
            
        possible_stacks_orders = (nCr(N_ROWS * N_COLS + 1, N_STACKS)
                                  * (N_ITEMS+1)**N_STACKS)
        
        
        ## enumerate the locations of stacks
        enum_stacks = 0
        locations = copy.deepcopy(self.valid_locations)
        for i in range(N_STACKS):
            idx = locations.index(self.stack_locs[i])
            if i == N_STACKS - 1:
                enum_stacks += idx
            else:
                locations = locations[1:]
                for j in range(idx):
                    enum_stacks += nCr(len(locations), N_STACKS - i - 1)
                    locations = locations[1:]
            
        possible_orders = (N_ITEMS+1)**N_STACKS
            
        ## enumerate the order state variable
        enum_orders = 0
        for i in range(N_STACKS):
            enum_orders += self.orders[i] * (N_ITEMS+1)**(N_STACKS-1-i)
            
        enum = (enum_robots * possible_stacks_orders
               + enum_stacks * possible_orders
               + enum_orders)
        return enum
def predict_cell(candidates, row, model, lef_data, std_cells):
    """
    Use the trained model to choose the most probable cell from via groups.
    :param candidates: 2-via and 3-via groups that could make a cell
    :return: a tuple (chosen via group, predicted cell name)
    """
    # possibly I can use the current method of testing the width of each cell
    # margin = 350
    # dataset = np.ndarray(shape=(len(candidates), FEATURE_LEN),
    #                      dtype=np.float32)
    scores = [-100 for i in range(len(candidates))]
    for i in range(len(candidates)):
        if candidates[i] != -1:
            features = []
            each_group = candidates[i]
            # width = std_cells[2]
            left_margin = std_cells[i][-1]
            # for left_margin in range(50, 800, 50):
            left_pt = [each_group[0][0][0] - left_margin, CELL_HEIGHT * row]
            # width = each_group[-1][0][0] - left_pt[0] + margin
            num_vias = len(each_group)
            features.append(num_vias)
            x_bound = left_pt[0]
            y_bound = left_pt[1]
            # NOTE: some cell has 4 vias
            # We suppose maximum vias in a cell is 4
            for each_via in each_group:
                x_loc = each_via[0][0] - x_bound
                y_loc = each_via[0][1] - y_bound
                # features.append(x_loc)
                features.append(y_loc)
                # add via type
                features.append(each_via[3])
            # if there are only two vias, then there are no via3
            if num_vias < 4:
                temp = [-1 for i in range((4 - num_vias) * 2)]
                features.extend(temp)
            # add the distance between vias
            for i in range(num_vias - 1):
                for j in range(i + 1, num_vias):
                    x_dist = each_group[j][0][0] - each_group[i][0][0]
                    y_dist = each_group[j][0][1] - each_group[i][0][1]
                    features.append(x_dist)
                    features.append(y_dist)
            # add extra features in case of having less vias
            if num_vias < 4:
                if num_vias == 1:
                    remain_dists = 2 * int(util.nCr(4, 2))
                else:
                    remain_dists = 2 * (
                        int(util.nCr(4, 2) - util.nCr(num_vias, 2)))
                temp = [0 for i in range(remain_dists)]
                features.extend(temp)
            # do predict
            dataset = np.array(features, dtype=np.int32)
            # print(dataset)
            X_test = dataset.reshape(1, FEATURE_LEN)
            result = model.decision_function(X_test)
            result = result[0]
            # print(each_group)
            # print(left_margin)
            print(labels[i])
            print(features)
            print(result)
            # print()
            features = []
            if result[i] == max(result):
                return candidates[i], i
Beispiel #4
0
def extract_comp(comp_name, lef_data, def_data, macro_via1_dict):
    """
    Extract the features and label of each cell
    :param comp_name: name of the component
    :param lef_data: data parsed from LEF file.
    :param def_data: data parsed from DEF file.
    :param macro_via_dict: dictionary contains macro and via1 data
    :return: void
    """
    # get info of the component and macro from DEF and LEF
    comp_info = def_data.components.comp_dict[comp_name]
    macro_name = comp_info.macro
    macro_info = lef_data.macro_dict[macro_name]
    macro_size = macro_info.info["SIZE"]
    scale = float(def_data.scale)
    # get the placement of the component from DEF file
    bottom_left_pt = comp_info.placed
    top_right_pt = [
        bottom_left_pt[0] + int(macro_size[0] * scale),
        bottom_left_pt[1] + int(macro_size[1] * scale)
    ]
    corners = [bottom_left_pt, top_right_pt]
    # find the vias inside the component's area
    vias_in_comp = macro_via1_dict[comp_name]
    vias_draw = []
    for pin in vias_in_comp:
        if pin != "MACRO":
            for each_via in vias_in_comp[pin]:
                each_via_loc = each_via[0]
                via_type = each_via[1]
                if inside_area(each_via_loc, corners):
                    vias_draw.append((each_via_loc, via_type))

    # sort the vias by x-coordinate
    vias_draw.sort(key=lambda x: x[0][0])
    # crop the cell by the vias location

    # margin = 350
    # left_pt = [vias_draw[0][0][0] - margin, bottom_left_pt[1]]
    # width = vias_draw[-1][0][0] - left_pt[0] + margin
    # height = macro_size[1] * scale
    # corners = [left_pt]
    # corners.append([left_pt[0] + width, left_pt[1] + height])

    # get the pins from LEF data
    pins = []
    for pin in macro_info.pin_dict.keys():
        pin_name = pin.lower()
        if pin_name != 'gnd' and pin_name != 'vdd':
            pins.append(pin)

    left_pt = bottom_left_pt
    # build the features
    features = []
    # number of vias
    num_vias = len(vias_draw)
    features.append(num_vias)
    x_bound = left_pt[0]
    y_bound = left_pt[1]
    # NOTE: some cell has 4 vias
    # We suppose maximum vias in a cell is 4
    for each_via in vias_draw:
        x_loc = each_via[0][0] - x_bound
        y_loc = each_via[0][1] - y_bound
        # features.append(x_loc)
        features.append(y_loc)
        # determine the type of each via
        via_loc = each_via[0]
        # print(via_loc)
        pin_found = False
        for pin in pins:
            pin_data = macro_info.pin_dict[pin]
            pin_direction = pin_data.info["DIRECTION"].lower()
            layers = pin_data.info["PORT"].info["LAYER"]
            for layer in layers:
                for shape in layer.shapes:
                    # scale the points
                    corners = util.scalePts(shape.points, scale)
                    corners = relocate_area(bottom_left_pt, corners)
                    # print(corners)
                    if inside_area(via_loc, corners):
                        # print(pin)
                        # print(pin_direction)
                        pin_found = True
                        if pin_direction == 'output':
                            features.append(1)
                        elif pin_direction == 'input':
                            features.append(0)
                        break
            if pin_found:
                break
        if not pin_found:
            features.append(-1)
    # if there are only two vias, then there are no via3
    if num_vias < 4:
        # temp = [-1 for i in range((4 - num_vias) * 3)]
        # trial: only use num_vias, no x-coordinate and y-coordinate
        temp = [-1 for i in range((4 - num_vias) * 2)]
        features.extend(temp)

    # add the distance between vias
    for i in range(len(vias_draw) - 1):
        for j in range(i + 1, len(vias_draw)):
            x_dist = vias_draw[j][0][0] - vias_draw[i][0][0]
            y_dist = vias_draw[j][0][1] - vias_draw[i][0][1]
            features.append(x_dist)
            features.append(y_dist)
    # add extra features in case of having less vias
    if num_vias < 4:
        if num_vias == 1:
            remain_dists = 2 * int(util.nCr(4, 2))
        else:
            remain_dists = 2 * (int(util.nCr(4, 2) - util.nCr(num_vias, 2)))
        temp = [0 for i in range(remain_dists)]
        features.extend(temp)
    # print(macro_name)
    # print(features)
    # print(len(features))
    # add more features here
    label = macro_name
    return features, label
Beispiel #5
0
def extract_comp(comp_name, lef_data, def_data, macro_via1_dict):
    """
    Extract the features and label of each cell
    :param comp_name: name of the component
    :param lef_data: data parsed from LEF file.
    :param def_data: data parsed from DEF file.
    :param macro_via_dict: dictionary contains macro and via1 data
    :return: void
    """
    # get info of the component and macro from DEF and LEF
    comp_info = def_data.components.comp_dict[comp_name]
    macro_name = comp_info.macro
    macro_info = lef_data.macro_dict[macro_name]
    macro_size = macro_info.info["SIZE"]
    scale = float(def_data.scale)
    # get the placement of the component from DEF file
    bottom_left_pt = comp_info.placed
    top_right_pt = [bottom_left_pt[0] + int(macro_size[0] * scale),
                    bottom_left_pt[1] + int(macro_size[1] * scale)]
    corners = [bottom_left_pt, top_right_pt]
    # find the vias inside the component's area
    vias_in_comp = macro_via1_dict[comp_name]
    vias_draw = []
    for pin in vias_in_comp:
        if pin != "MACRO":
            for each_via in vias_in_comp[pin]:
                each_via_loc = each_via[0]
                via_type = each_via[1]
                if inside_area(each_via_loc, corners):
                    vias_draw.append((each_via_loc, via_type))

    # sort the vias by x-coordinate
    vias_draw.sort(key=lambda x: x[0][0])
    # crop the cell by the vias location

    # margin = 350
    # left_pt = [vias_draw[0][0][0] - margin, bottom_left_pt[1]]
    # width = vias_draw[-1][0][0] - left_pt[0] + margin
    # height = macro_size[1] * scale
    # corners = [left_pt]
    # corners.append([left_pt[0] + width, left_pt[1] + height])

    # get the pins from LEF data
    pins = []
    for pin in macro_info.pin_dict.keys():
        pin_name = pin.lower()
        if pin_name != 'gnd' and pin_name != 'vdd':
            pins.append(pin)

    left_pt = bottom_left_pt
    # build the features
    features = []
    # number of vias
    num_vias = len(vias_draw)
    features.append(num_vias)
    x_bound = left_pt[0]
    y_bound = left_pt[1]
    # NOTE: some cell has 4 vias
    # We suppose maximum vias in a cell is 4
    for each_via in vias_draw:
        x_loc = each_via[0][0] - x_bound
        y_loc = each_via[0][1] - y_bound
        # features.append(x_loc)
        features.append(y_loc)
        # determine the type of each via
        via_loc = each_via[0]
        # print(via_loc)
        pin_found = False
        for pin in pins:
            pin_data = macro_info.pin_dict[pin]
            pin_direction = pin_data.info["DIRECTION"].lower()
            layers = pin_data.info["PORT"].info["LAYER"]
            for layer in layers:
                for shape in layer.shapes:
                    # scale the points
                    corners = util.scalePts(shape.points, scale)
                    corners = relocate_area(bottom_left_pt, corners)
                    # print(corners)
                    if inside_area(via_loc, corners):
                        # print(pin)
                        # print(pin_direction)
                        pin_found = True
                        if pin_direction == 'output':
                            features.append(1)
                        elif pin_direction == 'input':
                            features.append(0)
                        break
            if pin_found:
                break
        if not pin_found:
            features.append(-1)
    # if there are only two vias, then there are no via3
    if num_vias < 4:
        # temp = [-1 for i in range((4 - num_vias) * 3)]
        # trial: only use num_vias, no x-coordinate and y-coordinate
        temp = [-1 for i in range((4 - num_vias) * 2)]
        features.extend(temp)

    # add the distance between vias
    for i in range(len(vias_draw) - 1):
        for j in range(i + 1, len(vias_draw)):
            x_dist = vias_draw[j][0][0] - vias_draw[i][0][0]
            y_dist = vias_draw[j][0][1] - vias_draw[i][0][1]
            features.append(x_dist)
            features.append(y_dist)
    # add extra features in case of having less vias
    if num_vias < 4:
        if num_vias == 1:
            remain_dists = 2 * int(util.nCr(4, 2))
        else:
            remain_dists = 2 * (int(util.nCr(4, 2) - util.nCr(num_vias, 2)))
        temp = [0 for i in range(remain_dists)]
        features.extend(temp)
    # print(macro_name)
    # print(features)
    # print(len(features))
    # add more features here
    label = macro_name
    return features, label
Beispiel #6
0
def predict_cell(candidates, row, model, lef_data, std_cells):
    """
    Use the trained model to choose the most probable cell from via groups.
    :param candidates: 2-via and 3-via groups that could make a cell
    :return: a tuple (chosen via group, predicted cell name)
    """
    # possibly I can use the current method of testing the width of each cell
    # margin = 350
    # dataset = np.ndarray(shape=(len(candidates), FEATURE_LEN),
    #                      dtype=np.float32)
    scores = [-100 for i in range(len(candidates))]
    for i in range(len(candidates)):
        if candidates[i] != -1:
            features = []
            each_group = candidates[i]
            # width = std_cells[2]
            left_margin = std_cells[i][-1]
            # for left_margin in range(50, 800, 50):
            left_pt = [each_group[0][0][0] - left_margin, CELL_HEIGHT * row]
            # width = each_group[-1][0][0] - left_pt[0] + margin
            num_vias = len(each_group)
            features.append(num_vias)
            x_bound = left_pt[0]
            y_bound = left_pt[1]
            # NOTE: some cell has 4 vias
            # We suppose maximum vias in a cell is 4
            for each_via in each_group:
                x_loc = each_via[0][0] - x_bound
                y_loc = each_via[0][1] - y_bound
                # features.append(x_loc)
                features.append(y_loc)
                # add via type
                features.append(each_via[3])
            # if there are only two vias, then there are no via3
            if num_vias < 4:
                temp = [-1 for i in range((4 - num_vias) * 2)]
                features.extend(temp)
            # add the distance between vias
            for i in range(num_vias - 1):
                for j in range(i + 1, num_vias):
                    x_dist = each_group[j][0][0] - each_group[i][0][0]
                    y_dist = each_group[j][0][1] - each_group[i][0][1]
                    features.append(x_dist)
                    features.append(y_dist)
            # add extra features in case of having less vias
            if num_vias < 4:
                if num_vias == 1:
                    remain_dists = 2 * int(util.nCr(4, 2))
                else:
                    remain_dists = 2 * (int(util.nCr(4, 2) - util.nCr(num_vias, 2)))
                temp = [0 for i in range(remain_dists)]
                features.extend(temp)
            # do predict
            dataset = np.array(features, dtype=np.int32)
            # print(dataset)
            X_test = dataset.reshape(1, FEATURE_LEN)
            result = model.decision_function(X_test)
            result = result[0]
            # print(each_group)
            # print(left_margin)
            print(labels[i])
            print(features)
            print(result)
            # print()
            features = []
            if result[i] == max(result):
                return candidates[i], i