@@ -103,11 +103,47 @@ ucp_proto_select_add_lane(ucp_proto_lane_selection_t *selection,
103103 selection -> dev_count [dev_index ]++ ;
104104}
105105
106+ static UCS_F_ALWAYS_INLINE void
107+ ucp_proto_multi_limit_device_paths (
108+ const ucp_proto_init_params_t * params ,
109+ const ucp_lane_index_t * lanes ,
110+ ucp_lane_index_t lane , ucp_lane_index_t max_paths_per_device ,
111+ ucp_lane_index_t max_lanes ,
112+ const ucp_proto_lane_selection_t * selection ,
113+ ucp_lane_map_t * index_map_p )
114+ {
115+ const uct_iface_attr_t * iface_attr ;
116+ ucp_rsc_index_t dev_index ;
117+ ucp_lane_index_t candidate_index ;
118+
119+ if (max_paths_per_device == 0 ) {
120+ return ;
121+ }
122+
123+ iface_attr = ucp_proto_common_get_iface_attr (params , lane );
124+ if (iface_attr -> dev_num_paths <= max_lanes ) {
125+ return ;
126+ }
127+
128+ dev_index = ucp_proto_common_get_dev_index (params , lane );
129+ if (selection -> dev_count [dev_index ] < max_paths_per_device ) {
130+ return ;
131+ }
132+
133+ ucs_for_each_bit (candidate_index , * index_map_p ) {
134+ if (ucp_proto_common_get_dev_index (params , lanes [candidate_index ]) ==
135+ dev_index ) {
136+ * index_map_p &= ~UCS_BIT (candidate_index );
137+ }
138+ }
139+ }
140+
106141static void
107142ucp_proto_multi_select_bw_lanes (const ucp_proto_init_params_t * params ,
108143 const ucp_lane_index_t * lanes ,
109144 ucp_lane_index_t num_lanes ,
110145 ucp_lane_index_t max_lanes ,
146+ ucp_lane_index_t max_paths_per_device ,
111147 const ucp_proto_common_tl_perf_t * lanes_perf ,
112148 int fixed_first_lane ,
113149 ucp_proto_lane_selection_t * selection )
@@ -123,6 +159,9 @@ ucp_proto_multi_select_bw_lanes(const ucp_proto_init_params_t *params,
123159 if (fixed_first_lane ) {
124160 ucp_proto_select_add_lane (selection , params , lanes [0 ]);
125161 index_map &= ~UCS_BIT (0 );
162+ ucp_proto_multi_limit_device_paths (params , lanes , lanes [0 ],
163+ max_paths_per_device , max_lanes ,
164+ selection , & index_map );
126165 }
127166
128167 for (i = fixed_first_lane ? 1 : 0 ; i < ucs_min (max_lanes , num_lanes ); ++ i ) {
@@ -136,6 +175,13 @@ ucp_proto_multi_select_bw_lanes(const ucp_proto_init_params_t *params,
136175
137176 ucp_proto_select_add_lane (selection , params , lanes [lane_index ]);
138177 index_map &= ~UCS_BIT (lane_index );
178+ ucp_proto_multi_limit_device_paths (params , lanes , lanes [lane_index ],
179+ max_paths_per_device , max_lanes ,
180+ selection , & index_map );
181+
182+ if (index_map == 0 ) {
183+ break ;
184+ }
139185 }
140186
141187 /* TODO: Aggregate performance:
@@ -409,7 +455,8 @@ ucs_status_t ucp_proto_multi_init(const ucp_proto_multi_init_params_t *params,
409455 }
410456
411457 ucp_proto_multi_select_bw_lanes (& params -> super .super , lanes , num_lanes ,
412- params -> max_lanes , lanes_perf ,
458+ params -> max_lanes ,
459+ params -> max_paths_per_device , lanes_perf ,
413460 fixed_first_lane , & selection );
414461
415462 ucs_trace ("selected %u lanes for %s" , selection .num_lanes ,
0 commit comments