Skip to content
Snippets Groups Projects
cost_model.py 43.5 KiB
Newer Older
    for i in range(len(level_access)):
        buffer_access = list(map(mul, level_access[i], layer_size))
sgauthamr2001's avatar
sgauthamr2001 committed
        total_cost += sum(buffer_access) * level_cost[i]

    if verbose >= 3:
        print("Level ", level, " array level access: ", level_access)

    return total_cost


def get_array_and_curr_level_cost(resource, point, layer, level, verbose=False):
sgauthamr2001's avatar
sgauthamr2001 committed
    """
    Get the energy from current level of memory access + inter-PE access
sgauthamr2001's avatar
sgauthamr2001 committed
    """

    # LMEI to distinguish O (partial sum) in buffer_access from A and W

    layer_size = get_layer_size(layer)
    mac_capacity = resource.mac_capacity

sgauthamr2001's avatar
sgauthamr2001 committed
    level_access = [
        get_if_access(level, point, layer, mac_capacity),
        get_of_access(level, point, layer, mac_capacity),
        get_fl_access(level, point, layer, mac_capacity),
    ]

    [if_access, of_access, fl_access] = level_access

sgauthamr2001's avatar
sgauthamr2001 committed
    buffer_level_access = [if_access, 2 * of_access - 1, fl_access]
    total_buffer_access = list(map(mul, buffer_level_access, layer_size))
    # level_cost = sum(total_buffer_access) * resource.access_cost[level]
    level_cost = 0
    for i in range(len(total_buffer_access)):
        index = resource.memory_partitions[level][i]
        if index is not None:
            level_cost += total_buffer_access[i] * resource.access_cost[level][index]
    # operand_costs = [access_cost * num_accesses for access_cost,num_accesses in zip(total_buffer_access,resource.access_cost[level]) ]
    # level_cost = sum(operand_costs)

    if verbose >= 3:
        print("Level ", level, " access: ", buffer_level_access)

sgauthamr2001's avatar
sgauthamr2001 committed
    level_cost += get_array_level_cost(
        resource, point, layer_size, level - 1, level_access, verbose
    )

    return level_cost


def get_level_cost(resource, point, layer, level, verbose=False):
sgauthamr2001's avatar
sgauthamr2001 committed
    """
    Get the energy from current level of memory access

    #LMEI to distinguish O (partial sum) in buffer_access from A and W
sgauthamr2001's avatar
sgauthamr2001 committed
    """

    layer_size = get_layer_size(layer)
    mac_capacity = resource.mac_capacity

sgauthamr2001's avatar
sgauthamr2001 committed
    level_access = [
        get_if_access(level, point, layer, mac_capacity),
        2 * get_of_access(level, point, layer, mac_capacity) - 1,
        get_fl_access(level, point, layer, mac_capacity),
    ]

    buffer_access = list(map(mul, level_access, layer_size))
    # Inputs, weights, and outputs may have different costs
    # level_cost = sum(buffer_access) * resource.access_cost[level]
    level_cost = 0
    for i in range(len(buffer_access)):
        index = resource.memory_partitions[level][i]
        if index is not None:
            level_cost += buffer_access[i] * resource.access_cost[level][index]
    # resouce.memory_partitions
    # operand_costs = [access_cost * num_accesses for access_cost,num_accesses in zip(buffer_access,resource.access_cost[level]) ]
    # level_cost = sum(operand_costs)

    if verbose >= 3:
        print("Level", level, " access: ", level_access)
    return level_cost


def get_total_access(resource, point, layer, verbose=False):
    layer_size = get_layer_size(layer)

sgauthamr2001's avatar
sgauthamr2001 committed
    access_list, array_cost = get_access(point, layer, resource)

    if verbose >= 3:
        print("access breakdown: ", access_list)

    total_level_access = []
    for i in range(len(access_list)):
sgauthamr2001's avatar
sgauthamr2001 committed
        """List of total access of each buffer at level i"""
        if not isinstance(access_list[i][0], list):
            buffer_access = list(map(mul, access_list[i], layer_size))
            total_level_access.append(sum(buffer_access))
sgauthamr2001's avatar
sgauthamr2001 committed
        else:
            for j in range(len(access_list[i])):
                buffer_access = list(map(mul, access_list[i][j], layer_size))
                total_level_access.append(sum(buffer_access))

    return total_level_access


def get_level_costs(resource, point, layer, verbose=False):
    num_levels = resource.buffer_levels()

    level_energy = []
    for level in range(num_levels):
        level_energy.append(get_level_cost(resource, point, layer, level))

    para_index = [i for i, e in enumerate(resource.paras) if e.access_mode != 0]

    delta = 1
    for index in para_index:
sgauthamr2001's avatar
sgauthamr2001 committed
        array_energy = (
            get_array_and_curr_level_cost(resource, point, layer, index + 1)
            - level_energy[index + delta]
        )
        level_energy.insert(index + delta, array_energy)
        delta += 1

    return level_energy

sgauthamr2001's avatar
sgauthamr2001 committed

# FIXME
def get_block_cost(resource, point, layer, verbose=False):
sgauthamr2001's avatar
sgauthamr2001 committed
    """
    Get the cost of the given mapping point on given resource.

    If the point is not feasible on the resource, return inf.
sgauthamr2001's avatar
sgauthamr2001 committed
    """
    # TODO include static energy
    num_levels = resource.buffer_levels()

sgauthamr2001's avatar
sgauthamr2001 committed
    access_list, array_cost = get_access(point, layer, resource)
    layer_size = get_layer_size(layer)

    total_access_cost = get_total_access_cost(resource, array_cost)
    assert len(total_access_cost) == len(access_list)

    block_costs = [0.0, 0.0, 0.0]
    for i in range(len(total_access_cost)):
sgauthamr2001's avatar
sgauthamr2001 committed
        buffer_access = [a * b for a, b in list(zip(access_list[i], layer_size))]
        block_cost = [x * total_access_cost[i] for x in buffer_access]
        block_costs = list(map(add, block_cost, block_costs))

    if verbose:
sgauthamr2001's avatar
sgauthamr2001 committed
        print("access_list: ", access_list)
        bank_size_list, block_size_list = get_block_sizes(num_levels, point, layer)
sgauthamr2001's avatar
sgauthamr2001 committed
        print("bank_size_list: ", bank_size_list)
        print("block_size_list: ", block_size_list)
        print("layer_size: ", layer_size)
        print("block costs: ", block_costs)
sgauthamr2001's avatar
sgauthamr2001 committed

def get_cost(resource, point, layer, verbose=False):
sgauthamr2001's avatar
sgauthamr2001 committed
    """
    Get the cost of the given mapping point on given resource.

    If the point is not feasible on the resource, return inf.
sgauthamr2001's avatar
sgauthamr2001 committed
    """
    # TODO include static energy
    # TODO support other access_mode
    num_levels = resource.buffer_levels()
sgauthamr2001's avatar
sgauthamr2001 committed
    assert len(point.loop_blockings[0]) == num_levels, (
        "number of blockings does not match with number of memory "
        "levels: %d" % num_levels
    )
sgauthamr2001's avatar
sgauthamr2001 committed
    access_list, array_cost = get_access(point, layer, resource)
    layer_size = get_layer_size(layer)

    total_access_cost = get_total_access_cost(resource, array_cost)
    assert len(total_access_cost) == len(access_list)

    total_cost = 0.0
    for i in range(len(total_access_cost)):
sgauthamr2001's avatar
sgauthamr2001 committed
        """List of total access of each buffer at level i"""
        if not isinstance(access_list[i][0], list):
            buffer_access = list(map(mul, access_list[i], layer_size))
sgauthamr2001's avatar
sgauthamr2001 committed
            total_cost += sum(buffer_access) * total_access_cost[i][0]
        else:
            for j in range(len(access_list[i])):
                buffer_access = list(map(mul, access_list[i][j], layer_size))
sgauthamr2001's avatar
sgauthamr2001 committed
                total_cost += sum(buffer_access) * total_access_cost[i][j]
sgauthamr2001's avatar
sgauthamr2001 committed
        # print("total_access_cost", total_access_cost)
        # print("access_list", access_list)
sgauthamr2001's avatar
sgauthamr2001 committed
        # print("layer_size",layer_size)

        idx_adjust = 0
        if len(total_access_cost) > 4:
            idx_adjust = 1
sgauthamr2001's avatar
sgauthamr2001 committed

        layer_access_cost = (
            total_access_cost[: 1 + idx_adjust] + total_access_cost[2 + idx_adjust :]
        )
        print(
            "16b_Access_Energy_[RegisterFile(s),Buffer,DRAM]_(pJ): \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                [item[0] for item in layer_access_cost],
                [item[1] for item in layer_access_cost],
                [item[2] for item in layer_access_cost],
            )
        )
        print(
            "PE_Access_Cost_(pJ): \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                total_access_cost[1 + idx_adjust][0],
                total_access_cost[1 + idx_adjust][1],
                total_access_cost[1 + idx_adjust][2],
            )
        )

        layer_num_access = access_list[: 1 + idx_adjust] + access_list[2 + idx_adjust :]
        print(
            "Tiles_Accessed_from_[RegisterFile(s),Buffer,DRAM]_in_Layer: \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                [item[0] for item in layer_num_access],
                [item[1] for item in layer_num_access],
                [item[2] for item in layer_num_access],
            )
        )
        print(
            "Tiles_Accessed_from_[RegisterFile(s),Buffer,DRAM]_PEs_in_Layer: \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                access_list[1 + idx_adjust][0],
                access_list[1 + idx_adjust][1],
                access_list[1 + idx_adjust][2],
            )
        )

        bank_size_list, block_size_list = get_block_sizes(num_levels, point, layer)
sgauthamr2001's avatar
sgauthamr2001 committed

        # print("bank_size_list", bank_size_list)
        # print("block_size_list", block_size_list)

        print(
            "Memory_Bank_Size_List_When_Parallelized/Unrolled_[RegisterFile(s),Buffer,DRAM]_(bytes): \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                [item[0] for item in bank_size_list],
                [item[1] for item in bank_size_list],
                [item[2] for item in bank_size_list],
            )
        )
        print(
            "Memory_Block_Size_List_When_NOT_Parallelized/Unrolled_[RegisterFile(s),Buffer,DRAM]_(bytes): \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                [item[0] for item in block_size_list],
                [item[1] for item in block_size_list],
                [item[2] for item in block_size_list],
            )
        )
        print(
            "Layer_Size_(number_of_pixels): \n\tifmap: {}\n\tofmap: {}\n\tfilter: {}".format(
                layer_size[0], layer_size[1], layer_size[2]
            )
        )
        # print('total cost: ', total_cost)

    # return total_cost
    return total_cost, total_access_cost, access_list, layer_size