vpr/src/base/SetupGrid.cpp
//Create a device grid which satisfies the minimum block counts
//  If a set of fixed grid layouts are specified, the smallest satisfying grid is picked
//  If an auto grid layouts are specified, the smallest dynamicly sized grid is picked
Create a device grid which satisfies the minimum block counts
If a set of fixed grid layouts are specified, the smallest satisfying grid is picked
If an auto grid layouts are specified, the smallest dynamicly sized grid is picked
Create a device grid which satisfies the minimum block counts If a set of fixed grid layouts are specified the smallest satisfying grid is picked If an auto grid layouts are specified the smallest dynamicly sized grid is picked
static DeviceGrid auto_size_device_grid(const std::vector<t_grid_def>& grid_layouts, const std::map<t_logical_block_type_ptr, size_t>& minimum_instance_counts, float maximum_device_utilization) {
    VTR_ASSERT(grid_layouts.size() > 0);
    DeviceGrid grid;
    auto is_auto_grid_def = [](const t_grid_def& grid_def) {
        return grid_def.grid_type == GridDefType::AUTO;
    };
    auto auto_layout_itr = std::find_if(grid_layouts.begin(), grid_layouts.end(), is_auto_grid_def);
    if (auto_layout_itr != grid_layouts.end()) {
        VTR_ASSERT_SAFE_MSG(std::find_if(auto_layout_itr + 1, grid_layouts.end(), is_auto_grid_def) == grid_layouts.end(), "Only one <auto_layout>");
        const auto& grid_def = *auto_layout_itr;
        VTR_ASSERT(grid_def.aspect_ratio >= 0.);
        size_t width = 3;
        size_t height = 3;
        std::vector<t_logical_block_type_ptr> limiting_resources;
        do {
            height = vtr::nint(width / grid_def.aspect_ratio);
#ifdef VERBOSE
            VTR_LOG("Grid size: %zu x %zu (AR: %.2f) \n", width, height, float(width) / height);
#endif
            grid = build_device_grid(grid_def, width, height, false, limiting_resources);
            if (grid_satisfies_instance_counts(grid, minimum_instance_counts, maximum_device_utilization)) {
                grid = build_device_grid(grid_def, width, height, true, limiting_resources);
                return grid;
            }
            limiting_resources = grid_overused_resources(grid, minimum_instance_counts);
            width++;
        } while (true);
    } else {
        VTR_ASSERT(auto_layout_itr == grid_layouts.end());
        std::vector<const t_grid_def*> grid_layouts_view;
        grid_layouts_view.reserve(grid_layouts.size());
        for (const auto& layout : grid_layouts) {
            grid_layouts_view.push_back(&layout);
        }
        auto area_cmp = [](const t_grid_def* lhs, const t_grid_def* rhs) {
            VTR_ASSERT(lhs->grid_type == GridDefType::FIXED);
            VTR_ASSERT(rhs->grid_type == GridDefType::FIXED);
            int lhs_area = lhs->width * lhs->height;
            int rhs_area = rhs->width * rhs->height;
            return lhs_area < rhs_area;
        };
        std::stable_sort(grid_layouts_view.begin(), grid_layouts_view.end(), area_cmp);
        std::vector<t_logical_block_type_ptr> limiting_resources;
        for (const auto* grid_def : grid_layouts_view) {
            grid = build_device_grid(*grid_def, grid_def->width, grid_def->height, true, limiting_resources);
            if (grid_satisfies_instance_counts(grid, minimum_instance_counts, maximum_device_utilization)) {
                return grid;
            }
            limiting_resources = grid_overused_resources(grid, minimum_instance_counts);
        }
    }
    return grid; 
}
static DeviceGrid auto_size_device_grid ( const std :: vector < t_grid_def > & grid_layouts , const std :: map < t_logical_block_type_ptr , size_t > & minimum_instance_counts , float maximum_device_utilization ) { VTR_ASSERT ( grid_layouts . size ( ) > 0 ) ; DeviceGrid grid ; auto is_auto_grid_def = [ ] ( const t_grid_def & grid_def ) { return grid_def . grid_type == GridDefType :: AUTO ; } ; auto auto_layout_itr = std :: find_if ( grid_layouts . begin ( ) , grid_layouts . end ( ) , is_auto_grid_def ) ; if ( auto_layout_itr != grid_layouts . end ( ) ) { VTR_ASSERT_SAFE_MSG ( std :: find_if ( auto_layout_itr + 1 , grid_layouts . end ( ) , is_auto_grid_def ) == grid_layouts . end ( ) , " " ) ; const auto & grid_def = * auto_layout_itr ; VTR_ASSERT ( grid_def . aspect_ratio >= 0. ) ; size_t width = 3 ; size_t height = 3 ; std :: vector < t_logical_block_type_ptr > limiting_resources ; do { height = vtr :: nint ( width / grid_def . aspect_ratio ) ; #ifdef VERBOSE VTR_LOG ( " \n " , width , height , float ( width ) / height ) ; #endif grid = build_device_grid ( grid_def , width , height , false , limiting_resources ) ; if ( grid_satisfies_instance_counts ( grid , minimum_instance_counts , maximum_device_utilization ) ) { grid = build_device_grid ( grid_def , width , height , true , limiting_resources ) ; return grid ; } limiting_resources = grid_overused_resources ( grid , minimum_instance_counts ) ; width ++ ; } while ( true ) ; } else { VTR_ASSERT ( auto_layout_itr == grid_layouts . end ( ) ) ; std :: vector < const t_grid_def * > grid_layouts_view ; grid_layouts_view . reserve ( grid_layouts . size ( ) ) ; for ( const auto & layout : grid_layouts ) { grid_layouts_view . push_back ( & layout ) ; } auto area_cmp = [ ] ( const t_grid_def * lhs , const t_grid_def * rhs ) { VTR_ASSERT ( lhs -> grid_type == GridDefType :: FIXED ) ; VTR_ASSERT ( rhs -> grid_type == GridDefType :: FIXED ) ; int lhs_area = lhs -> width * lhs -> height ; int rhs_area = rhs -> width * rhs -> height ; return lhs_area < rhs_area ; } ; std :: stable_sort ( grid_layouts_view . begin ( ) , grid_layouts_view . end ( ) , area_cmp ) ; std :: vector < t_logical_block_type_ptr > limiting_resources ; for ( const auto * grid_def : grid_layouts_view ) { grid = build_device_grid ( * grid_def , grid_def -> width , grid_def -> height , true , limiting_resources ) ; if ( grid_satisfies_instance_counts ( grid , minimum_instance_counts , maximum_device_utilization ) ) { return grid ; } limiting_resources = grid_overused_resources ( grid , minimum_instance_counts ) ; } } return grid ; }
Create a device grid which satisfies the minimum block counts
If a set of fixed grid layouts are specified, the smallest satisfying grid is picked
If an auto grid layouts are specified, the smallest dynamicly sized grid is picked
Create a device grid which satisfies the minimum block counts If a set of fixed grid layouts are specified the smallest satisfying grid is picked If an auto grid layouts are specified the smallest dynamicly sized grid is picked
//Automatic grid layout, find the smallest height/width //Initial size is 3x3, the smallest possible while avoiding //start before end location issues with <perimeter> location //specifications //Scale opposite dimension to match aspect ratio //Build the device // Don't warn about out-of-range specifications since these can // occur (harmlessly) at small device dimensions //Check if it satisfies the block counts //Re-build the grid at the final size with out-of-range //warnings turned on (so users are aware of out-of-range issues //at the final device sizes) //Increase the grid size //Fixed grid layouts, find the smallest of the fixed layouts //Sort the grid layouts from smallest to largest //Try all the fixed devices in order from smallest to largest //Build the grid //Unreachable