1616#include " vpr_utils.h"
1717#include " vtr_log.h"
1818
19+ /* *
20+ * @brief Counts how many instances of the given logical block type the device
21+ * can hold.
22+ */
23+ static size_t count_available_instances (const t_logical_block_type& type,
24+ const DeviceGrid& device_grid) {
25+ size_t num_instances = 0 ;
26+ for (const t_physical_tile_type_ptr equivalent_tile : type.equivalent_tiles )
27+ num_instances += device_grid.num_instances (equivalent_tile, -1 );
28+ return num_instances;
29+ }
30+
31+ /* *
32+ * @brief Logs a table showing, for each logical block type the netlist uses, how
33+ * many instances the device has, how many the netlist is estimated to
34+ * need, and the multiplier applied to that type's max candidate distance
35+ * threshold (1.0 = unchanged).
36+ */
37+ static void log_device_size_adjustments (
38+ const std::map<t_logical_block_type_ptr, size_t >& estimated_type_instance_counts,
39+ const std::map<t_logical_block_type_ptr, float >& type_th_multiplier,
40+ const std::vector<t_logical_block_type>& logical_block_types,
41+ const DeviceGrid& device_grid) {
42+
43+ VTR_LOG (" \n APPack device size estimate reaction (per used block type):\n " );
44+ VTR_LOG (" %-20s %12s %12s %10s %10s\n " ,
45+ " Block Type" , " Available" , " Estimated" , " Util(%)" , " DistThMul" );
46+ for (const t_logical_block_type& type : logical_block_types) {
47+ auto itr = estimated_type_instance_counts.find (&type);
48+ size_t estimated = (itr != estimated_type_instance_counts.end ()) ? itr->second : 0 ;
49+ if (estimated == 0 )
50+ continue ; // Skip block types the netlist does not use.
51+
52+ size_t available = count_available_instances (type, device_grid);
53+ float utilization = (available != 0 ) ? 100 .0f * estimated / available : 0 .0f ;
54+
55+ auto mul_itr = type_th_multiplier.find (&type);
56+ float th_multiplier = (mul_itr != type_th_multiplier.end ()) ? mul_itr->second : 1 .0f ;
57+
58+ VTR_LOG (" %-20s %12zu %12zu %10.1f %10.2f\n " ,
59+ type.name .c_str (), available, estimated, utilization, th_multiplier);
60+ }
61+ VTR_LOG (" \n " );
62+ }
63+
1964void APPackContext::adjust_for_device_size_estimate (
2065 const std::map<t_logical_block_type_ptr, size_t >& estimated_type_instance_counts,
2166 const std::vector<t_logical_block_type>& logical_block_types,
@@ -26,32 +71,26 @@ void APPackContext::adjust_for_device_size_estimate(
2671 if (!appack_options.use_appack )
2772 return ;
2873
29- bool any_type_needs_denser_packing = false ;
74+ // Max distance threshold multiplier applied to each block type, recorded for
75+ // logging. Types not present here were left unchanged (multiplier of 1.0).
76+ std::map<t_logical_block_type_ptr, float > type_th_multiplier;
77+
3078 for (const t_logical_block_type& type : logical_block_types) {
3179 if (is_empty_type (&type))
3280 continue ;
3381
34- size_t num_total_instances = 0 ;
35- for ( const t_physical_tile_type_ptr equivalent_tile : type. equivalent_tiles )
36- num_total_instances += device_grid. num_instances (equivalent_tile, - 1 );
82+ size_t num_total_instances = count_available_instances (type, device_grid) ;
83+ if (num_total_instances == 0 )
84+ continue ; // No capacity for this type on the device; ignoring for now.
3785
3886 auto itr = estimated_type_instance_counts.find (&type);
3987 size_t estimated_instances = (itr != estimated_type_instance_counts.end ()) ? itr->second : 0 ;
4088
41- if (num_total_instances == 0 ) {
42- if (estimated_instances == 0 )
43- continue ; // Nothing of this type needed; leave untouched.
44- // No capacity at all for this type on the device; ignoring for now.
45- continue ;
46- }
47-
4889 // Compute the utilization of this block type.
4990 float utilization = static_cast <float >(estimated_instances) / static_cast <float >(num_total_instances);
5091 if (utilization < device_size_min_utilization_for_th_bump)
5192 continue ; // Comfortably fits.
5293
53- any_type_needs_denser_packing = true ;
54-
5594 // Linearly scale the multiplier applied to this type's normal max
5695 // distance threshold from 1x to device_size_max_dist_th_scale_multiplier
5796 // as utilization goes from device_size_min_utilization_for_th_bump to
@@ -60,12 +99,13 @@ void APPackContext::adjust_for_device_size_estimate(
6099 float th_multiplier = 1 .0f + (utilization_clamped - device_size_min_utilization_for_th_bump) / (device_size_severe_utilization_cutoff - device_size_min_utilization_for_th_bump) * (device_size_max_dist_th_scale_multiplier - 1 .0f );
61100 float base_max_dist_th = max_distance_threshold_manager.get_max_dist_threshold (type);
62101 max_distance_threshold_manager.set_max_dist_threshold (type, base_max_dist_th * th_multiplier);
63- }
64102
65- if (any_type_needs_denser_packing) {
66- VTR_LOG (" Device size estimate predicts a tight packing; increased the max candidate distance threshold for the affected block type(s).\n " );
103+ type_th_multiplier[&type] = th_multiplier;
67104 }
68105
106+ log_device_size_adjustments (estimated_type_instance_counts, type_th_multiplier,
107+ logical_block_types, device_grid);
108+
69109 // TODO: This should be capable of turning on unrelated clustering as well if the
70110 // utilization is high enough. I chose to keep that out for now as I explore
71111 // when it is best to use unrelated clustering. From many experiments, I have
0 commit comments