diff --git a/vpr/src/analytical_place/flat_placement_mass_calculator.cpp b/vpr/src/analytical_place/flat_placement_mass_calculator.cpp index 523586f7ec..93068fa4df 100644 --- a/vpr/src/analytical_place/flat_placement_mass_calculator.cpp +++ b/vpr/src/analytical_place/flat_placement_mass_calculator.cpp @@ -6,38 +6,184 @@ */ #include "flat_placement_mass_calculator.h" +#include +#include #include #include "ap_mass_report.h" #include "ap_netlist.h" #include "atom_netlist.h" +#include "atom_netlist_fwd.h" #include "logic_types.h" #include "physical_types.h" #include "prepack.h" #include "primitive_dim_manager.h" #include "primitive_vector.h" -#include "primitive_vector_fwd.h" #include "vtr_log.h" #include "vtr_vector.h" /** - * @brief Get the scalar mass of the given model (primitive type). - * - * A model with a higher mass will take up more space in its bin which may force - * more spreading of that type of primitive. - * - * TODO: This will be made more complicated later. Models may be weighted based - * on some factors. + * @brief Returns true if the given pb_type is a primitive and is a memory class. */ -static float get_model_mass(LogicalModelId model_id) { - // Currently, all models have a mass of one. - (void)model_id; - return 1.f; +static bool is_primitive_memory_pb_type(const t_pb_type* pb_type) { + VTR_ASSERT_SAFE(pb_type != nullptr); + + if (!pb_type->is_primitive()) + return false; + + if (pb_type->class_type != MEMORY_CLASS) + return false; + + return true; +} + +/** + * @brief Calculate the cost of the given pb_type. This cost is a value that + * represents how much mass in a specific dimension a physical block + * takes up. + */ +static float calc_pb_type_cost(const t_pb_type* pb_type) { + // If this primitive represents a memory, count the number of bits this memory + // can store and return that as the cost. + if (is_primitive_memory_pb_type(pb_type)) { + // Get the number of address and data pins to compute the number of bits + // this memory can store. + // number_bits = num_data_out_pins * 2^num_address_pins + int num_address_pins = 0; + int num_data_out_pins = 0; + int num_address1_pins = 0; + int num_data_out1_pins = 0; + int num_address2_pins = 0; + int num_data_out2_pins = 0; + for (int i = 0; i < pb_type->num_ports; i++) { + if (pb_type->ports[i].port_class == nullptr) + continue; + + std::string port_class = pb_type->ports[i].port_class; + if (port_class == "address") + num_address_pins += pb_type->ports[i].num_pins; + if (port_class == "data_out") + num_data_out_pins += pb_type->ports[i].num_pins; + if (port_class == "address1") + num_address1_pins += pb_type->ports[i].num_pins; + if (port_class == "data_out1") + num_data_out1_pins += pb_type->ports[i].num_pins; + if (port_class == "address2") + num_address2_pins += pb_type->ports[i].num_pins; + if (port_class == "data_out2") + num_data_out2_pins += pb_type->ports[i].num_pins; + } + + // Compute the number of bits this could store if it was a single port + // memory. + int single_port_num_bits = 0; + if (num_address_pins > 0) { + VTR_ASSERT_MSG(num_address1_pins == 0 && num_address2_pins == 0, + "Cannot be a single port and dual port memory"); + single_port_num_bits = (1 << num_address_pins) * num_data_out_pins; + } + + // Compute the number of bits this could store if it was a dual port memory. + // Need to compute the number of bits for each of the ports. + int dual_port1_num_bits = 0; + if (num_address1_pins > 0) { + // FIXME: Found that the Titan architecture fails this test! Raise + // an issue on this to maybe update the documentation or fix + // the architecture. + // See: prim_ram_1Kx9 + // Perhaps the architecture parsing file should check for this. + // VTR_ASSERT_MSG(num_address_pins == 0 && num_address2_pins > 0, + // "Ill-formed dual port memory"); + dual_port1_num_bits = (1 << num_address1_pins) * num_data_out1_pins; + } + int dual_port2_num_bits = 0; + if (num_address2_pins > 0) { + VTR_ASSERT_MSG(num_address_pins == 0 && num_address1_pins > 0, + "Ill-formed dual port memory"); + dual_port2_num_bits = (1 << num_address2_pins) * num_data_out2_pins; + } + // Note: We take the max of the two dual port num bits since dual ports + // access the same memory but with different address bits. + int total_dual_port_num_bits = std::max(dual_port1_num_bits, dual_port2_num_bits); + + // Get the total number of bits. We assume that this memory will be either + // a single port or dual port memory, therefore we can just sum these two + // terms. If it was a single port, the dual port num bits will be 0 and + // vice-versa. + int total_num_bits = single_port_num_bits + total_dual_port_num_bits; + VTR_ASSERT_MSG(total_num_bits != 0, + "Cannot deduce number of bits in memory primitive."); + return total_num_bits; + } + + // If this is not a memory, count the number of input and output pins. + // This makes physical blocks with more pins have more size than those with + // less. For example, a 4 lut would have a lower cost than a 5 lut. + float pb_cost = pb_type->num_input_pins + pb_type->num_output_pins + pb_type->num_clock_pins; + return pb_cost; +} + +/** + * @brief Returns the mass of the given atom block. + */ +static float get_atom_mass(AtomBlockId blk_id, const Prepacker& prepacker, const AtomNetlist& atom_netlist) { + + // Get the physical block that this block will most likely be packed into. + // This will give us a better estimate for how many resources this atom will + // use. For example, a LUT atom may only use 2 input pins; however, the + // architecture may only have 4-LUTs and 5-LUTs available. This method should + // return the smallest compatible resource for this atom (i.e. the 4-LUT). + const t_pb_graph_node* primitive = prepacker.get_expected_lowest_cost_pb_gnode(blk_id); + + // Get the physical cost of this atom. This is the cost of the atom when it + // is physically implemented on the device. For example, the 2-LUT above may + // be at best implemented by a 4-LUT which may give it a cost of 5 pins. + float physical_cost = calc_pb_type_cost(primitive->pb_type); + + // Get the mass of this atom (i.e. how much resources on the device this atom + // will likely use). + float mass = 0.0f; + if (!is_primitive_memory_pb_type(primitive->pb_type)) { + // If this is not a memory, we use a weighted sum of the physical cost + // (how much resources we expect it to use physically on the device) and + // the logical cost (how much resources is it actually using). + + // The logical cost is the sum of the used pins on the atom block. For + // the 2-LUT example, this would have a logical cost of 3 (2 inputs and + // 1 output). + size_t num_logical_input_pins = atom_netlist.block_input_pins(blk_id).size(); + size_t num_logical_clock_pins = atom_netlist.block_clock_pins(blk_id).size(); + size_t num_logical_output_pins = atom_netlist.block_output_pins(blk_id).size(); + float logical_cost = num_logical_input_pins + num_logical_clock_pins + num_logical_output_pins; + + // We take a weighted sum of the physical and logical cost. The physical + // cost is an over-estimation of how many resources the atom will use + // since, if less pins are used, the atom may be able to "share" its + // inputs. The logical cost is closer to an underestimate. We use a weighted + // sum to try and account for the unknowns about the eventual packing. + mass = (0.8f * physical_cost) + (0.2f * logical_cost); + } else { + // For memories, mass is just the physical cost. + // NOTE: It is important for the physical and logical costs to have + // "the same units". Since memories have a cost proportional to + // the number of bits within the memory, we cannot do a weighted + // sum with the number of pins. + // TODO: Should use the number of input and output pins to compute + // logical memory cost (i.e. how many bits the atom actually needs). + mass = physical_cost; + } + + // Currently, the code does not handle well with fractional masses. Rounding + // up to the nearest whole number. + mass = std::ceil(mass); + + return mass; } // This method is being forward-declared due to the double recursion below. // Eventually this should be made into a non-recursive algorithm for performance, // however this is not in a performance critical part of the code. static PrimitiveVector calc_pb_type_capacity(const t_pb_type* pb_type, + std::set& memory_model_dims, const PrimitiveDimManager& dim_manager); /** @@ -47,15 +193,13 @@ static PrimitiveVector calc_pb_type_capacity(const t_pb_type* pb_type, * themselves have modes. */ static PrimitiveVector calc_mode_capacity(const t_mode& mode, + std::set& memory_model_dims, const PrimitiveDimManager& dim_manager) { // Accumulate the capacities of all the pbs in this mode. PrimitiveVector capacity; for (int pb_child_idx = 0; pb_child_idx < mode.num_pb_type_children; pb_child_idx++) { const t_pb_type& pb_type = mode.pb_type_children[pb_child_idx]; - PrimitiveVector pb_capacity = calc_pb_type_capacity(&pb_type, dim_manager); - // A mode may contain multiple pbs of the same type, multiply the - // capacity. - pb_capacity *= pb_type.num_pb; + PrimitiveVector pb_capacity = calc_pb_type_capacity(&pb_type, memory_model_dims, dim_manager); capacity += pb_capacity; } return capacity; @@ -68,6 +212,7 @@ static PrimitiveVector calc_mode_capacity(const t_mode& mode, * Modes are made of pbs. */ static PrimitiveVector calc_pb_type_capacity(const t_pb_type* pb_type, + std::set& memory_model_dims, const PrimitiveDimManager& dim_manager) { // Since a pb cannot be multiple modes at the same time, we do not // accumulate the capacities of the mode. Instead we need to "mix" the two @@ -76,19 +221,45 @@ static PrimitiveVector calc_pb_type_capacity(const t_pb_type* pb_type, // If this is a leaf / primitive, create the base PrimitiveVector capacity. if (pb_type->is_primitive()) { LogicalModelId model_id = pb_type->model_id; - VTR_ASSERT(model_id.is_valid()); + VTR_ASSERT_SAFE(model_id.is_valid()); PrimitiveVectorDim dim = dim_manager.get_model_dim(model_id); VTR_ASSERT(dim.is_valid()); - capacity.add_val_to_dim(get_model_mass(model_id), dim); + if (pb_type->class_type == MEMORY_CLASS) + memory_model_dims.insert(dim); + float pb_type_cost = calc_pb_type_cost(pb_type); + capacity.add_val_to_dim(pb_type_cost * pb_type->num_pb, dim); return capacity; } // For now, we simply mix the capacities of modes by taking the max of each // dimension of the capcities. This provides an upper-bound on the amount of // primitives this pb can contain. for (int mode = 0; mode < pb_type->num_modes; mode++) { - PrimitiveVector mode_capacity = calc_mode_capacity(pb_type->modes[mode], dim_manager); + PrimitiveVector mode_capacity = calc_mode_capacity(pb_type->modes[mode], memory_model_dims, dim_manager); capacity = PrimitiveVector::max(capacity, mode_capacity); } + + // A pb_type represents a heirarchy of physical blocks that can be implemented, + // with leaves of primitives at the bottom of the heirarchy. A pb_type will have + // many children, each with their own physical cost; however, a parent pb_type + // should not have higher cost than its children. For example, here we use + // pin counts to represent cost. The children of the pb_type cannot use more + // pins than the parent has available. Therefore, each dimension of the + // pb_type cannot have a higher cost than the parent. + // Clamp the capacity by the physical cost of this pb_type. + float pb_type_physical_cost = calc_pb_type_cost(pb_type); + for (PrimitiveVectorDim dim : capacity.get_non_zero_dims()) { + // If this dimension corresponds to a memory, do not clamp the capacity. + // Memories count bits, so clamping by the number of pins of the parent + // does not really make sense. + if (memory_model_dims.count(dim) != 0) + continue; + capacity.set_dim_val(dim, std::min(capacity.get_dim_val(dim), pb_type_physical_cost)); + } + + // A pb_type may contain multiple copies of the same PB. Multiply the capacity + // by the number of pb. + capacity *= pb_type->num_pb; + return capacity; } @@ -100,9 +271,15 @@ static PrimitiveVector calc_logical_block_type_capacity(const t_logical_block_ty // If this logical block is empty, it cannot contain any primitives. if (logical_block_type.is_empty()) return PrimitiveVector(); + + std::set memory_model_dims; + PrimitiveVector capacity = calc_pb_type_capacity(logical_block_type.pb_type, + memory_model_dims, + dim_manager); + // The primitive capacity of a logical block is the primitive capacity of // its root pb. - return calc_pb_type_capacity(logical_block_type.pb_type, dim_manager); + return capacity; } /** @@ -176,28 +353,225 @@ static PrimitiveVector calc_block_mass(APBlockId blk_id, // safely be ignored. if (!atom_blk_id.is_valid()) continue; + + // Get the dimension in the vector to add value to. LogicalModelId model_id = atom_netlist.block_model(atom_blk_id); - VTR_ASSERT(model_id.is_valid()); + VTR_ASSERT_SAFE(model_id.is_valid()); PrimitiveVectorDim dim = dim_manager.get_model_dim(model_id); VTR_ASSERT(dim.is_valid()); - mass.add_val_to_dim(get_model_mass(model_id), dim); + + // Get the amount of mass in this dimension to add. + float atom_mass = get_atom_mass(atom_blk_id, prepacker, atom_netlist); + + // Add mass to the dimension. + mass.add_val_to_dim(atom_mass, dim); } return mass; } +namespace { + +/** + * @brief A struct to hold information on pb types which act like one-hot primitves. + */ +struct OneHotPbType { + /// @brief The root pb type which contains the modes which act in a one-hot + /// fashion. + t_pb_type* pb_type; + + /// @brief The models which will all share a dimension due to being a part + /// of this pb type. + std::set shared_models; +}; + +} // namespace + +/** + * @brief Search the architecture for pb types which implement models in a "one-hot" way. + * + * A one-hot pb type is a pb_type which effectively acts like a one-hot + * encoding for a set of models. A good example of this is IO pb types. An + * IO pb type can either be an input or an output but not both. These pb_types + * should be treated as a single dimension in the primitive vector since they + * are mutually exclusive (i.e. using the resource of one is the same as using + * the resource of another). + */ +static std::vector find_one_hot_pb_types(const std::vector& logical_block_types, + const LogicalModels& models, + int log_verbosity) { + // Populate a lookup between each model and the primitives that implement them. + // This is simply done by doing a BFS on the complex graph and accumulating + // any pb_types that implement each of the models. + VTR_LOGV(log_verbosity >= 10, "Creating lookup for the model primitives...\n"); + vtr::vector> model_primitives(models.all_models().size()); + + // Initialize a queue for the pb_types to check. + std::queue pb_type_queue; + for (const t_logical_block_type& block_type : logical_block_types) { + pb_type_queue.push(block_type.pb_type); + } + + // BFS over the pb_types. + while (!pb_type_queue.empty()) { + t_pb_type* pb_type = pb_type_queue.front(); + pb_type_queue.pop(); + if (pb_type == nullptr) + continue; + + // If this pb_type is a primitive, add it to the model primitives of the + // model that implements it. + if (pb_type->is_primitive()) { + model_primitives[pb_type->model_id].insert(pb_type); + continue; + } + + // Explore all of the children of this pb_type by adding them to the queue. + for (int mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) { + const t_mode& mode = pb_type->modes[mode_idx]; + for (int pb_child_idx = 0; pb_child_idx < mode.num_pb_type_children; pb_child_idx++) { + pb_type_queue.push(&mode.pb_type_children[pb_child_idx]); + } + } + } + + // Search for the one-hot pb types. + // Some properties of the one-hot pb types that this search is looking for: + // - it is a pb_type + // - it has more than one mode + // - each mode implements a single, unique primitive + // - single: num_pb == 1 (this makes the cost function easier) + // - unique: this primitive implements a model that is not used anywhere else. + // This search is done using a BFS similar to above. + VTR_LOGV(log_verbosity >= 10, "Searching for one-hot primitives...\n"); + std::vector one_hot_pb_types; + + // Initialize the queue with the pb type for each of the logical blocks. + VTR_ASSERT(pb_type_queue.empty()); + for (const t_logical_block_type& block_type : logical_block_types) { + pb_type_queue.push(block_type.pb_type); + } + + // Perform a BFS over the queue. + while (!pb_type_queue.empty()) { + t_pb_type* pb_type = pb_type_queue.front(); + pb_type_queue.pop(); + if (pb_type == nullptr) + continue; + + // If this is a primitive, there is nothing to do, skip it. + if (pb_type->is_primitive()) { + continue; + } + + // The one-hot pb type must have more than 1 mode. + if (pb_type->num_modes > 1) { + bool is_one_hot = true; + std::set contained_models; + // Check if every pb_type in each mode is single and unique. + for (int mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) { + const t_mode& mode = pb_type->modes[mode_idx]; + // Check if the mode contains only a single pb_type. + if (mode.num_pb_type_children != 1) { + is_one_hot = false; + break; + } + // Check if the mode contains a singular primitive. + t_pb_type* mode_child_pb = &mode.pb_type_children[0]; + if (mode_child_pb->num_pb > 1 || !mode_child_pb->is_primitive()) { + is_one_hot = false; + break; + } + // Check if the primitive is unique (i.e. there is no other model + // like it anywhere in the architecture). + VTR_ASSERT_SAFE(mode_child_pb->is_primitive()); + LogicalModelId child_model = mode_child_pb->model_id; + if (model_primitives[child_model].size() > 1) { + is_one_hot = false; + break; + } + // Keep track of the contained models. + contained_models.insert(mode_child_pb->model_id); + } + + // If this pb type is one-hot, store its info. + if (is_one_hot) { + OneHotPbType one_hot_pb_type_info; + one_hot_pb_type_info.pb_type = pb_type; + one_hot_pb_type_info.shared_models = std::move(contained_models); + one_hot_pb_types.push_back(std::move(one_hot_pb_type_info)); + + // Do not explore the children of this pb_type. + continue; + } + } + + // Add the pb_type children of this pb_type to the queue. + for (int mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) { + const t_mode& mode = pb_type->modes[mode_idx]; + for (int pb_child_idx = 0; pb_child_idx < mode.num_pb_type_children; pb_child_idx++) { + pb_type_queue.push(&mode.pb_type_children[pb_child_idx]); + } + } + } + + // Log the one-hot pb types for debugging. + if (log_verbosity >= 10) { + VTR_LOG("One-Hot PB Types:\n"); + for (const OneHotPbType& one_hot_pb_type_info : one_hot_pb_types) { + VTR_LOG("\t%s:\n", one_hot_pb_type_info.pb_type->name); + for (LogicalModelId model_id : one_hot_pb_type_info.shared_models) { + VTR_LOG("\t\t%s\n", models.model_name(model_id).c_str()); + } + } + } + + return one_hot_pb_types; +} + /** * @brief Initialize the dim manager such that every model in the architecture * has a valid dimension in the primitive vector. */ static void initialize_dim_manager(PrimitiveDimManager& dim_manager, const LogicalModels& models, - const AtomNetlist& atom_netlist) { + const std::vector& logical_block_types, + const AtomNetlist& atom_netlist, + int log_verbosity) { // Set the mapping between model IDs and Primitive Vector IDs + // Find all of the pb types that act like a one-hot primitive. + std::vector one_hot_pb_types = find_one_hot_pb_types(logical_block_types, + models, + log_verbosity); + + // For each model, label them with their shared model ID if they are part + // of a one-hot pb_type, -1 otherwise. + vtr::vector model_one_hot_id(models.all_models().size(), -1); + for (size_t one_hot_id = 0; one_hot_id < one_hot_pb_types.size(); one_hot_id++) { + for (LogicalModelId model_id : one_hot_pb_types[one_hot_id].shared_models) { + model_one_hot_id[model_id] = one_hot_id; + } + } + // Count the number of occurences of each model in the netlist. vtr::vector num_model_occurence(models.all_models().size(), 0); for (AtomBlockId blk_id : atom_netlist.blocks()) { - num_model_occurence[atom_netlist.block_model(blk_id)]++; + LogicalModelId model_id = atom_netlist.block_model(blk_id); + + // If this model is not part of a shared dimension, just accumulate its + // number of occurences. + int one_hot_id = model_one_hot_id[model_id]; + if (one_hot_id == -1) { + num_model_occurence[model_id]++; + continue; + } + + // If this model is part of a shared dimension, only accumulate into the + // first shared model. This creates an accurate count of the number of + // occurences of the overall shared dimension in this first model id. + const OneHotPbType& one_hot_pb_type = one_hot_pb_types[one_hot_id]; + LogicalModelId first_model_id = *one_hot_pb_type.shared_models.begin(); + num_model_occurence[first_model_id]++; } // Create a list of models, sorted by their frequency in the netlist. @@ -210,9 +584,47 @@ static void initialize_dim_manager(PrimitiveDimManager& dim_manager, return num_model_occurence[a] > num_model_occurence[b]; }); - // Create a primitive vector dim for each model. + // Create a primitive vector dim for each model that occurs in the netlist + // and is not part of a shared dimension. for (LogicalModelId model_id : logical_models) { - dim_manager.create_dim(model_id, models.model_name(model_id)); + // If this model is not part of a shared dimension, create a single + // dimension just for it. + int one_hot_id = model_one_hot_id[model_id]; + if (one_hot_id == -1) { + dim_manager.create_dim(model_id, models.model_name(model_id)); + continue; + } + + // If this model is part of a shared dimension, check if this is the first + // model ID in the list, if it isn't skip it. We only want to create one + // dimension for these models. + const OneHotPbType& one_hot_pb_type = one_hot_pb_types[one_hot_id]; + LogicalModelId first_model_id = *one_hot_pb_type.shared_models.begin(); + if (model_id != first_model_id) + continue; + + // Create the shared dimension. + + // Create a unique name for the dim. This is used for debugging. + std::string dim_name = one_hot_pb_type.pb_type->name; + dim_name += "_ap_shared["; + size_t index = 0; + for (LogicalModelId shared_model_id : one_hot_pb_type.shared_models) { + dim_name += models.model_name(shared_model_id); + dim_name += "]"; + if (index != one_hot_pb_type.shared_models.size() - 1) + dim_name += "["; + index++; + } + + // Create the new dimension. + PrimitiveVectorDim new_dim = dim_manager.create_empty_dim(dim_name); + + // Add all of the models that are part of the one-hot to the new dimension. + for (LogicalModelId shared_model_id : one_hot_pb_type.shared_models) { + VTR_ASSERT(!dim_manager.get_model_dim(shared_model_id).is_valid()); + dim_manager.add_model_to_dim(shared_model_id, new_dim); + } } } @@ -231,7 +643,9 @@ FlatPlacementMassCalculator::FlatPlacementMassCalculator(const APNetlist& ap_net // Initialize the mapping between model IDs and Primitive Vector dims initialize_dim_manager(primitive_dim_manager_, models, - atom_netlist); + logical_block_types, + atom_netlist, + log_verbosity_); // Precompute the capacity of each logical block type. for (const t_logical_block_type& logical_block_type : logical_block_types) { diff --git a/vpr/src/analytical_place/primitive_dim_manager.h b/vpr/src/analytical_place/primitive_dim_manager.h index 79c980081d..5be796312f 100644 --- a/vpr/src/analytical_place/primitive_dim_manager.h +++ b/vpr/src/analytical_place/primitive_dim_manager.h @@ -47,17 +47,37 @@ class PrimitiveDimManager { } /** - * @brief Create a mapping between the given logical model and a new dimension. - * - * The name is used only for printing debug information on this dimension. + * @brief Create an empty primitive vector dimension with the given name. */ - inline void create_dim(LogicalModelId model_id, const std::string& name) { - VTR_ASSERT_SAFE_MSG(model_id.is_valid(), - "Cannot create a dim for an invalid model"); + inline PrimitiveVectorDim create_empty_dim(const std::string& name) { PrimitiveVectorDim new_dim = static_cast(dims_.size()); dims_.push_back(new_dim); dim_name_.push_back(name); - model_dim_.insert(model_id, new_dim); + return new_dim; + } + + /** + * @brief Add the given model ID to the given primitive vector dim. + * + * It is assumed that the given model is not part of any other dimension. + */ + inline void add_model_to_dim(LogicalModelId model_id, PrimitiveVectorDim dim) { + VTR_ASSERT_SAFE_MSG(model_id.is_valid(), + "Cannot add an invalid model to a dim"); + VTR_ASSERT_SAFE_MSG(dim.is_valid(), + "Cannot add a model to an invalid dim"); + model_dim_.insert(model_id, dim); + } + + /** + * @brief Create a mapping between the given logical model and a new dimension. + * + * The name is used only for printing debug information on this dimension. + */ + inline PrimitiveVectorDim create_dim(LogicalModelId model_id, const std::string& name) { + PrimitiveVectorDim new_dim = create_empty_dim(name); + add_model_to_dim(model_id, new_dim); + return new_dim; } /** diff --git a/vpr/src/pack/greedy_candidate_selector.cpp b/vpr/src/pack/greedy_candidate_selector.cpp index 0ae3972140..60f169c049 100644 --- a/vpr/src/pack/greedy_candidate_selector.cpp +++ b/vpr/src/pack/greedy_candidate_selector.cpp @@ -962,21 +962,17 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id, // see if the molecule is too far away from the position of the cluster. // If so, do not add it to the list of candidates. if (appack_ctx.appack_options.use_appack) { - // If this cluster is a memory block, do not drop candidates based on - // distance. Was found to create too many RAM blocks. - if (!cluster_gain_stats.is_memory) { - // Get the max dist for this block type. - float max_dist = appack_ctx.max_distance_threshold_manager.get_max_dist_threshold(*cluster_type); - - // If the distance from the cluster to the candidate is too large, - // do not add this molecule to the list of candidates. - const t_flat_pl_loc mol_loc = get_molecule_pos(molecule_id, - prepacker, - appack_ctx); - float dist = get_manhattan_distance(mol_loc, cluster_gain_stats.flat_cluster_position); - if (dist > max_dist) - return; - } + // Get the max dist for this block type. + float max_dist = appack_ctx.max_distance_threshold_manager.get_max_dist_threshold(*cluster_type); + + // If the distance from the cluster to the candidate is too large, + // do not add this molecule to the list of candidates. + const t_flat_pl_loc mol_loc = get_molecule_pos(molecule_id, + prepacker, + appack_ctx); + float dist = get_manhattan_distance(mol_loc, cluster_gain_stats.flat_cluster_position); + if (dist > max_dist) + return; } int num_molecule_failures = 0; diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/config.txt index dbc8f9dcd3..4642cbc21d 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/config.txt @@ -18,27 +18,27 @@ arch_list_add=k6_frac_N10_40nm.xml # Add circuits to list to sweep circuit_list_add=apex4.pre-vpr.blif circuit_list_add=des.pre-vpr.blif -circuit_list_add=ex1010.pre-vpr.blif +# circuit_list_add=ex1010.pre-vpr.blif circuit_list_add=seq.pre-vpr.blif # Constrain the circuits to their devices circuit_constraint_list_add=(apex4.pre-vpr.blif, device=mcnc_medium) circuit_constraint_list_add=(seq.pre-vpr.blif, device=mcnc_medium) circuit_constraint_list_add=(des.pre-vpr.blif, device=mcnc_large) -circuit_constraint_list_add=(ex1010.pre-vpr.blif, device=mcnc_large) +# circuit_constraint_list_add=(ex1010.pre-vpr.blif, device=mcnc_large) # Constrain the IOs circuit_constraint_list_add=(apex4.pre-vpr.blif, constraints=../../../../../mcnc/constraints/apex4_io_constraint.xml) circuit_constraint_list_add=(seq.pre-vpr.blif, constraints=../../../../../mcnc/constraints/seq_io_constraint.xml) circuit_constraint_list_add=(des.pre-vpr.blif, constraints=../../../../../mcnc/constraints/des_io_constraint.xml) -circuit_constraint_list_add=(ex1010.pre-vpr.blif, constraints=../../../../../mcnc/constraints/ex1010_io_constraint.xml) +# circuit_constraint_list_add=(ex1010.pre-vpr.blif, constraints=../../../../../mcnc/constraints/ex1010_io_constraint.xml) # Constrain the circuits to their channel widths # 1.3 * minW circuit_constraint_list_add=(apex4.pre-vpr.blif, route_chan_width=78) circuit_constraint_list_add=(seq.pre-vpr.blif, route_chan_width=78) circuit_constraint_list_add=(des.pre-vpr.blif, route_chan_width=44) -circuit_constraint_list_add=(ex1010.pre-vpr.blif, route_chan_width=114) +# circuit_constraint_list_add=(ex1010.pre-vpr.blif, route_chan_width=114) # Parse info and how to parse parse_file=vpr_fixed_chan_width.txt diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/golden_results.txt index f73f554221..5ee50c475e 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/golden_results.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/naive_full_legalizer/config/golden_results.txt @@ -1,5 +1,4 @@ arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time initial_placed_wirelength_est placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time initial_placed_CPD_est placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time routed_wirelength avg_routed_wirelength routed_wiresegment avg_routed_wiresegment total_nets_routed total_connections_routed total_heap_pushes total_heap_pops logic_block_area_total logic_block_area_used routing_area_total routing_area_per_tile crit_path_route_success_iteration num_rr_graph_nodes num_rr_graph_edges collapsed_nodes critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS create_rr_graph_time create_intra_cluster_rr_graph_time adding_internal_edges route_mem crit_path_route_time crit_path_total_timing_analysis_time crit_path_total_sta_time router_lookahead_mem tile_lookahead_computation_time router_lookahead_computation_time -k6_frac_N10_40nm.xml apex4.pre-vpr.blif common 2.31 vpr 73.99 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 119 9 -1 -1 success v8.0.0-12648-g259ceba57-dirty release IPO VTR_ASSERT_LEVEL=2 Clang 18.1.3 on Linux-6.8.0-58-generic x86_64 2025-05-06T12:34:13 betzgrp-wintermute /home/zhan6738/VTR/vtr-verilog-to-routing/vtr_flow/tasks 75768 9 19 897 28 0 656 147 16 16 256 -1 mcnc_medium -1 -1 9465 7387 7500 653 5233 1614 74.0 MiB 1.83 0.00 6.84375 5.63197 -90.064 -5.63197 nan 0.04 0.00131708 0.00113824 0.0411484 0.0370479 74.0 MiB 1.83 74.0 MiB 1.31 11218 17.1267 2998 4.57710 4710 22969 767847 128278 1.05632e+07 6.41339e+06 1.26944e+06 4958.75 18 28900 206586 -1 6.05963 nan -96.1476 -6.05963 0 0 0.11 -1 -1 74.0 MiB 0.20 0.126178 0.115644 74.0 MiB -1 0.04 -k6_frac_N10_40nm.xml des.pre-vpr.blif common 1.42 vpr 74.60 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 179 256 -1 -1 success v8.0.0-12648-g259ceba57-dirty release IPO VTR_ASSERT_LEVEL=2 Clang 18.1.3 on Linux-6.8.0-58-generic x86_64 2025-05-06T12:34:13 betzgrp-wintermute /home/zhan6738/VTR/vtr-verilog-to-routing/vtr_flow/tasks 76388 256 245 954 501 0 743 680 22 22 484 -1 mcnc_large -1 -1 9276 7596 60460 2199 20502 37759 74.6 MiB 1.03 0.01 5.23911 4.36438 -841.143 -4.36438 nan 0.05 0.00189527 0.00178544 0.0499427 0.0473007 74.6 MiB 1.03 74.6 MiB 0.79 10985 14.7847 3053 4.10902 2501 6468 260198 59947 2.15576e+07 9.64703e+06 1.49107e+06 3080.73 14 47664 245996 -1 4.95172 nan -902.835 -4.95172 0 0 0.13 -1 -1 74.6 MiB 0.12 0.126567 0.120415 74.6 MiB -1 0.05 -k6_frac_N10_40nm.xml ex1010.pre-vpr.blif common 7.71 vpr 103.92 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 366 10 -1 -1 success v8.0.0-12648-g259ceba57-dirty release IPO VTR_ASSERT_LEVEL=2 Clang 18.1.3 on Linux-6.8.0-58-generic x86_64 2025-05-06T12:34:13 betzgrp-wintermute /home/zhan6738/VTR/vtr-verilog-to-routing/vtr_flow/tasks 106412 10 10 2659 20 0 1387 386 22 22 484 -1 mcnc_large -1 -1 28407 25969 52334 9214 38970 4150 103.9 MiB 6.23 0.01 8.84225 6.87893 -67.3793 -6.87893 nan 0.11 0.00413268 0.00332707 0.201364 0.170726 103.9 MiB 6.23 103.9 MiB 3.63 40223 29.0000 10345 7.45854 8587 59599 2538983 323136 2.15576e+07 1.97252e+07 3.51389e+06 7260.09 18 64568 594370 -1 7.19431 nan -69.2992 -7.19431 0 0 0.36 -1 -1 103.9 MiB 0.68 0.492176 0.435586 103.9 MiB -1 0.11 -k6_frac_N10_40nm.xml seq.pre-vpr.blif common 2.43 vpr 75.07 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 125 41 -1 -1 success v8.0.0-12648-g259ceba57-dirty release IPO VTR_ASSERT_LEVEL=2 Clang 18.1.3 on Linux-6.8.0-58-generic x86_64 2025-05-06T12:34:13 betzgrp-wintermute /home/zhan6738/VTR/vtr-verilog-to-routing/vtr_flow/tasks 76868 41 35 1006 76 0 665 201 16 16 256 -1 mcnc_medium -1 -1 9806 7711 9021 479 5180 3362 75.1 MiB 1.93 0.00 7.51244 5.32876 -152.164 -5.32876 nan 0.04 0.00142804 0.00124551 0.0391378 0.0356815 75.1 MiB 1.93 75.1 MiB 1.39 12022 18.0782 3251 4.88872 4219 22486 741180 125076 1.05632e+07 6.73675e+06 1.26944e+06 4958.75 17 28900 206586 -1 5.72072 nan -160.849 -5.72072 0 0 0.11 -1 -1 75.1 MiB 0.19 0.127975 0.117992 75.1 MiB -1 0.04 +k6_frac_N10_40nm.xml apex4.pre-vpr.blif common 2.93 vpr 76.75 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 130 9 -1 -1 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 78596 9 19 897 28 0 658 158 16 16 256 -1 mcnc_medium -1 -1 7563.39 6923 9125 651 6641 1833 76.8 MiB 2.29 0.01 6.51658 5.36579 -88.4441 -5.36579 nan 0.00 0.00162577 0.00126563 0.0570997 0.0484733 76.8 MiB 2.29 76.8 MiB 1.55 11116 16.9193 2929 4.45814 4716 24330 787581 129215 1.05632e+07 7.00622e+06 1.26944e+06 4958.75 18 28900 206586 -1 5.78608 nan -93.7909 -5.78608 0 0 0.19 -1 -1 76.8 MiB 0.27 0.244888 0.212058 32.7 MiB -1 0.05 +k6_frac_N10_40nm.xml des.pre-vpr.blif common 1.74 vpr 77.73 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 173 256 -1 -1 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 79600 256 245 954 501 0 760 674 22 22 484 -1 mcnc_large -1 -1 9292.95 7827 56800 1790 18880 36130 77.7 MiB 1.23 0.01 5.23911 4.45825 -854.38 -4.45825 nan 0.00 0.00211951 0.00189814 0.0535182 0.0484569 77.7 MiB 1.23 77.7 MiB 0.88 11106 14.6132 3086 4.06053 2658 7145 291226 67335 2.15576e+07 9.32366e+06 1.49107e+06 3080.73 14 47664 245996 -1 4.93512 nan -901.874 -4.93512 0 0 0.21 -1 -1 77.7 MiB 0.15 0.148325 0.136785 34.6 MiB -1 0.07 +k6_frac_N10_40nm.xml seq.pre-vpr.blif common 2.99 vpr 77.71 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 147 41 -1 -1 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 79572 41 35 1006 76 0 714 223 16 16 256 -1 mcnc_medium -1 -1 9169.27 7694 8335 415 5173 2747 77.7 MiB 2.36 0.01 6.36629 5.23793 -151.219 -5.23793 nan 0.00 0.00203238 0.00164862 0.0404664 0.0350253 77.7 MiB 2.36 77.7 MiB 1.61 12142 17.0056 3244 4.54342 4212 22271 689032 117413 1.05632e+07 7.92242e+06 1.26944e+06 4958.75 16 28900 206586 -1 5.65269 nan -156.023 -5.65269 0 0 0.18 -1 -1 77.7 MiB 0.26 0.236578 0.206181 32.3 MiB -1 0.05 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/no_fixed_blocks/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/no_fixed_blocks/config/golden_results.txt index 009b55cd6b..a9bbf47764 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/no_fixed_blocks/config/golden_results.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_ap/no_fixed_blocks/config/golden_results.txt @@ -1,6 +1,6 @@ arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time initial_placed_wirelength_est placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time initial_placed_CPD_est placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time routed_wirelength avg_routed_wirelength routed_wiresegment avg_routed_wiresegment total_nets_routed total_connections_routed total_heap_pushes total_heap_pops logic_block_area_total logic_block_area_used routing_area_total routing_area_per_tile crit_path_route_success_iteration num_rr_graph_nodes num_rr_graph_edges collapsed_nodes critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS create_rr_graph_time create_intra_cluster_rr_graph_time adding_internal_edges route_mem crit_path_route_time crit_path_total_timing_analysis_time crit_path_total_sta_time router_lookahead_mem tile_lookahead_computation_time router_lookahead_computation_time - k6_frac_N10_frac_chain_mem32K_40nm.xml boundtop.v common 13.60 vpr 84.67 MiB -1 -1 10.28 48164 3 0.64 -1 -1 38724 -1 -1 78 196 1 0 success v8.0.0-12807-gb9a610e4ea release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-05-26T12:39:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 86700 196 193 800 0 1 617 468 20 20 400 -1 vtr_extra_small -1 -1 4551.79 3335 67660 11256 49424 6980 84.7 MiB 1.85 0.01 2.99794 2.65144 -1220.33 -2.65144 2.65144 0.00 0.00196764 0.0016933 0.0869812 0.0762881 84.7 MiB 1.85 84.7 MiB 0.87 5403 8.88651 1576 2.59211 1637 2428 148736 41047 2.07112e+07 4.75173e+06 1.26946e+06 3173.65 11 38988 203232 -1 3.14851 3.14851 -1307.1 -3.14851 0 0 0.18 -1 -1 84.7 MiB 0.10 0.253777 0.227178 41.3 MiB -1 0.06 - k6_frac_N10_frac_chain_mem32K_40nm.xml ch_intrinsics.v common 1.41 vpr 77.76 MiB -1 -1 0.24 22136 3 0.07 -1 -1 37184 -1 -1 68 99 1 0 success v8.0.0-12807-gb9a610e4ea release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-05-26T12:39:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 79628 99 130 264 0 1 225 298 20 20 400 -1 vtr_extra_small -1 -1 927.937 681 36118 11514 18619 5985 77.8 MiB 0.67 0.00 1.85007 1.85007 -115.211 -1.85007 1.85007 0.00 0.000603813 0.000534685 0.0258211 0.0231026 77.8 MiB 0.67 77.8 MiB 0.30 1223 7.36747 392 2.36145 437 680 27699 8352 2.07112e+07 4.21279e+06 1.31074e+06 3276.84 11 39388 210115 -1 1.99059 1.99059 -134.028 -1.99059 0 0 0.19 -1 -1 77.8 MiB 0.03 0.0763687 0.0688854 39.8 MiB -1 0.06 - k6_frac_N10_frac_chain_mem32K_40nm.xml or1200.v common 26.75 vpr 136.18 MiB -1 -1 3.62 64888 8 3.02 -1 -1 45000 -1 -1 252 385 2 1 success v8.0.0-12807-gb9a610e4ea release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-05-26T12:39:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 139452 385 362 3324 0 1 2371 1002 30 30 900 -1 vtr_small -1 -1 44098.1 30988 507214 164336 316622 26256 136.2 MiB 16.82 0.07 10.8167 8.97166 -10306.7 -8.97166 8.97166 0.00 0.00951912 0.00820906 1.03378 0.89695 136.2 MiB 16.82 136.2 MiB 8.33 42405 17.9987 11044 4.68761 10195 33783 1818500 332274 4.8774e+07 1.50733e+07 6.56785e+06 7297.61 19 120772 1084977 -1 9.28418 9.28418 -10617.2 -9.28418 0 0 1.20 -1 -1 136.2 MiB 0.91 2.0873 1.855 84.5 MiB -1 0.28 - k6_frac_N10_frac_chain_mem32K_40nm.xml spree.v common 8.07 vpr 88.27 MiB -1 -1 2.71 35320 16 0.41 -1 -1 39076 -1 -1 61 45 3 1 success v8.0.0-12807-gb9a610e4ea release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-05-26T12:39:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 90392 45 32 936 0 1 770 142 20 20 400 -1 vtr_extra_small -1 -1 7959.32 6854 9392 1467 7682 243 88.3 MiB 3.91 0.01 11.8592 10.7084 -6927.96 -10.7084 10.7084 0.00 0.00233249 0.00190785 0.0816673 0.0690512 88.3 MiB 3.91 88.3 MiB 2.55 11323 14.7627 3001 3.91265 3570 9616 762496 186695 2.07112e+07 5.32753e+06 1.91495e+06 4787.38 15 44576 305072 -1 10.9684 10.9684 -7241.74 -10.9684 -0.00135869 -0.00135869 0.30 -1 -1 88.3 MiB 0.26 0.375846 0.327629 45.4 MiB -1 0.08 - k6_frac_N10_frac_chain_mem32K_40nm.xml stereovision3.v common 1.56 vpr 77.10 MiB -1 -1 0.48 26488 4 0.11 -1 -1 36728 -1 -1 15 11 0 0 success v8.0.0-12807-gb9a610e4ea release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-05-26T12:39:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 78948 11 2 140 0 2 85 28 20 20 400 -1 vtr_extra_small -1 -1 350.949 307 112 20 82 10 77.1 MiB 0.46 0.00 2.12187 2.12187 -168.584 -2.12187 1.99515 0.00 0.000442789 0.000363289 0.00459294 0.00425398 77.1 MiB 0.46 77.1 MiB 0.28 477 6.03797 123 1.55696 149 222 4271 1232 2.07112e+07 808410 1.12964e+06 2824.09 8 37792 180905 -1 2.20473 2.04223 -168.73 -2.20473 0 0 0.16 -1 -1 77.1 MiB 0.02 0.0430278 0.0379188 38.7 MiB -1 0.05 + k6_frac_N10_frac_chain_mem32K_40nm.xml boundtop.v common 12.82 vpr 84.53 MiB -1 -1 9.70 47988 3 0.66 -1 -1 38724 -1 -1 46 196 1 0 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 86556 196 193 800 0 1 606 436 20 20 400 -1 vtr_extra_small -1 -1 3860.11 2958 38432 5034 32612 786 84.5 MiB 1.64 0.01 3.05627 2.81427 -1157.09 -2.81427 2.81427 0.00 0.00196936 0.00169044 0.0574863 0.0506175 84.5 MiB 1.64 84.5 MiB 0.87 4856 8.13400 1474 2.46901 1576 2381 151545 44502 2.07112e+07 3.02712e+06 1.26946e+06 3173.65 11 38988 203232 -1 3.20993 3.20993 -1250.88 -3.20993 0 0 0.18 -1 -1 84.5 MiB 0.10 0.234356 0.210551 41.1 MiB -1 0.06 + k6_frac_N10_frac_chain_mem32K_40nm.xml ch_intrinsics.v common 1.31 vpr 78.14 MiB -1 -1 0.24 22392 3 0.07 -1 -1 36668 -1 -1 71 99 1 0 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 80020 99 130 264 0 1 227 301 20 20 400 -1 vtr_extra_small -1 -1 1257.27 747 38605 12435 21377 4793 78.1 MiB 0.57 0.00 2.33102 1.87385 -119.182 -1.87385 1.87385 0.00 0.00061211 0.000542712 0.0267923 0.0238329 78.1 MiB 0.57 78.1 MiB 0.27 1376 8.19048 424 2.52381 374 562 32070 9570 2.07112e+07 4.37447e+06 1.31074e+06 3276.84 11 39388 210115 -1 1.92986 1.92986 -139.81 -1.92986 0 0 0.19 -1 -1 78.1 MiB 0.03 0.0706636 0.0635038 39.8 MiB -1 0.06 + k6_frac_N10_frac_chain_mem32K_40nm.xml or1200.v common 24.27 vpr 136.09 MiB -1 -1 4.22 64248 8 3.04 -1 -1 44876 -1 -1 248 385 2 1 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 139356 385 362 3324 0 1 2363 998 30 30 900 -1 vtr_small -1 -1 38367.6 31621 325023 76668 244915 3440 136.1 MiB 13.60 0.07 10.8225 9.08544 -10440.1 -9.08544 9.08544 0.00 0.0102996 0.00916524 0.712821 0.627848 136.1 MiB 13.60 136.1 MiB 7.43 43233 18.4127 11166 4.75554 11029 37028 2050293 368090 4.8774e+07 1.48577e+07 6.56785e+06 7297.61 22 120772 1084977 -1 9.24865 9.24865 -10805.2 -9.24865 0 0 1.20 -1 -1 136.1 MiB 1.03 1.75073 1.56961 84.4 MiB -1 0.28 + k6_frac_N10_frac_chain_mem32K_40nm.xml spree.v common 7.77 vpr 88.11 MiB -1 -1 2.66 35704 16 0.42 -1 -1 39092 -1 -1 61 45 3 1 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 90220 45 32 936 0 1 776 142 20 20 400 -1 vtr_extra_small -1 -1 7105.82 6582 5322 807 4474 41 88.1 MiB 3.67 0.01 11.6538 11.2759 -7185.52 -11.2759 11.2759 0.00 0.00235374 0.00185015 0.0533413 0.0458798 88.1 MiB 3.67 88.1 MiB 2.59 10717 13.8642 2763 3.57439 3119 8687 657799 158649 2.07112e+07 5.32753e+06 1.91495e+06 4787.38 13 44576 305072 -1 11.2572 11.2572 -7442.26 -11.2572 0 0 0.30 -1 -1 88.1 MiB 0.23 0.310863 0.271769 45.7 MiB -1 0.08 + k6_frac_N10_frac_chain_mem32K_40nm.xml stereovision3.v common 1.53 vpr 77.11 MiB -1 -1 0.48 26788 4 0.11 -1 -1 36476 -1 -1 15 11 0 0 success v8.0.0-12967-g3fcd193802-dirty release VTR_ASSERT_LEVEL=3 GNU 13.3.0 on Linux-6.8.0-58-generic x86_64 2025-06-08T14:47:19 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 78960 11 2 140 0 2 78 28 20 20 400 -1 vtr_extra_small -1 -1 312.702 301 112 17 84 11 77.1 MiB 0.42 0.00 2.10685 2.10685 -167.794 -2.10685 1.95087 0.00 0.000432552 0.000357359 0.00458679 0.00425416 77.1 MiB 0.42 77.1 MiB 0.25 495 6.87500 126 1.75000 140 230 5128 1328 2.07112e+07 808410 1.12964e+06 2824.09 5 37792 180905 -1 2.12302 1.92786 -174.662 -2.12302 0 0 0.16 -1 -1 77.1 MiB 0.01 0.0401305 0.0353907 38.9 MiB -1 0.06