@@ -418,59 +418,81 @@ def parse_placement_group_resource_str(
418418 placement_group_resource_str : str ) -> Tuple [str , Optional [str ]]:
419419 """Parse placement group resource in the form of following 3 cases:
420420 {resource_name}_group_{bundle_id}_{group_name};
421+ -> This case is ignored as it is duplicated to the case below.
421422 {resource_name}_group_{group_name};
422423 {resource_name}
423424
424425 Returns:
425- Tuple of (resource_name, placement_group_name). placement_group_name
426- could be None if its not a placement group resource.
426+ Tuple of (resource_name, placement_group_name, is_countable_resource).
427+ placement_group_name could be None if its not a placement group
428+ resource. is_countable_resource is True if the resource
429+ doesn't contain bundle index. We shouldn't count resources
430+ with bundle index because it will
431+ have duplicated resource information as
432+ wildcard resources (resource name without bundle index).
427433 """
428434 result = PLACEMENT_GROUP_RESOURCE_BUNDLED_PATTERN .match (
429435 placement_group_resource_str )
430436 if result :
431- return (result .group (1 ), result .group (3 ))
437+ return (result .group (1 ), result .group (3 ), False )
432438 result = PLACEMENT_GROUP_RESOURCE_PATTERN .match (
433439 placement_group_resource_str )
434440 if result :
435- return (result .group (1 ), result .group (2 ))
436- return (placement_group_resource_str , None )
441+ return (result .group (1 ), result .group (2 ), True )
442+ return (placement_group_resource_str , None , True )
437443
438444
439445def get_usage_report (lm_summary : LoadMetricsSummary ) -> str :
440446 # first collect resources used in placement groups
441- placement_group_resource_usage = collections .defaultdict (float )
447+ placement_group_resource_usage = {}
448+ placement_group_resource_total = collections .defaultdict (float )
442449 for resource , (used , total ) in lm_summary .usage .items ():
443- (pg_resource_name ,
444- pg_name ) = parse_placement_group_resource_str (resource )
450+ (pg_resource_name , pg_name ,
451+ is_countable ) = parse_placement_group_resource_str (resource )
445452 if pg_name :
446- placement_group_resource_usage [pg_resource_name ] += used
453+ if pg_resource_name not in placement_group_resource_usage :
454+ placement_group_resource_usage [pg_resource_name ] = 0
455+ if is_countable :
456+ placement_group_resource_usage [pg_resource_name ] += used
457+ placement_group_resource_total [pg_resource_name ] += total
447458 continue
448459
449460 usage_lines = []
450461 for resource , (used , total ) in sorted (lm_summary .usage .items ()):
451462 if "node:" in resource :
452463 continue # Skip the auto-added per-node "node:<ip>" resource.
453464
454- (_ , pg_name ) = parse_placement_group_resource_str (resource )
465+ (_ , pg_name , _ ) = parse_placement_group_resource_str (resource )
455466 if pg_name :
456467 continue # Skip resource used by placement groups
457468
458- used_in_pg = placement_group_resource_usage [resource ]
459-
460- line = f" { used } /{ total } { resource } "
461- if used_in_pg != 0 :
462- line = line + f" ({ used_in_pg } reserved in placement groups)"
469+ pg_used = 0
470+ pg_total = 0
471+ used_in_pg = resource in placement_group_resource_usage
472+ if used_in_pg :
473+ pg_used = placement_group_resource_usage [resource ]
474+ pg_total = placement_group_resource_total [resource ]
475+ # Used includes pg_total because when pgs are created
476+ # it allocates resources.
477+ # To get the real resource usage, we should subtract the pg
478+ # reserved resources from the usage and add pg used instead.
479+ used = used - pg_total + pg_used
463480
464481 if resource in ["memory" , "object_store_memory" ]:
465482 to_GiB = 1 / 2 ** 30
466- used *= to_GiB
467- total *= to_GiB
468- used_in_pg *= to_GiB
469- line = f" { used :.2f} /{ total :.3f} GiB { resource } "
470- if used_in_pg != 0 :
471- line = line + f" ({ used_in_pg :.2f} GiB reserved" \
472- + " in placement groups)"
473- usage_lines .append (line )
483+ line = (f" { (used * to_GiB ):.2f} /"
484+ f"{ (total * to_GiB ):.3f} GiB { resource } " )
485+ if used_in_pg :
486+ line = line + (f" ({ (pg_used * to_GiB ):.2f} used of "
487+ f"{ (pg_total * to_GiB ):.2f} GiB " +
488+ "reserved in placement groups)" )
489+ usage_lines .append (line )
490+ else :
491+ line = f" { used } /{ total } { resource } "
492+ if used_in_pg :
493+ line += (f" ({ pg_used } used of "
494+ f"{ pg_total } reserved in placement groups)" )
495+ usage_lines .append (line )
474496 usage_report = "\n " .join (usage_lines )
475497 return usage_report
476498
@@ -488,8 +510,8 @@ def filter_placement_group_from_bundle(bundle: ResourceBundle):
488510 using_placement_group = False
489511 result_bundle = dict ()
490512 for pg_resource_str , resource_count in bundle .items ():
491- (resource_name ,
492- pg_name ) = parse_placement_group_resource_str (pg_resource_str )
513+ (resource_name , pg_name ,
514+ _ ) = parse_placement_group_resource_str (pg_resource_str )
493515 result_bundle [resource_name ] = resource_count
494516 if pg_name :
495517 using_placement_group = True
@@ -600,6 +622,32 @@ def format_info_string(lm_summary, autoscaler_summary, time=None):
600622 return formatted_output
601623
602624
625+ def format_no_node_type_string (node_type : dict ):
626+ placement_group_resource_usage = {}
627+ regular_resource_usage = collections .defaultdict (float )
628+ for resource , total in node_type .items ():
629+ (pg_resource_name , pg_name ,
630+ is_countable ) = parse_placement_group_resource_str (resource )
631+ if pg_name :
632+ if not is_countable :
633+ continue
634+ if pg_resource_name not in placement_group_resource_usage :
635+ placement_group_resource_usage [pg_resource_name ] = 0
636+ placement_group_resource_usage [pg_resource_name ] += total
637+ else :
638+ regular_resource_usage [resource ] += total
639+
640+ output_lines = ["" ]
641+ for resource , total in regular_resource_usage .items ():
642+ output_line = f"{ resource } : { total } "
643+ if resource in placement_group_resource_usage :
644+ pg_resource = placement_group_resource_usage [resource ]
645+ output_line += f" ({ pg_resource } reserved in placement groups)"
646+ output_lines .append (output_line )
647+
648+ return "\n " .join (output_lines )
649+
650+
603651def format_info_string_no_node_types (lm_summary , time = None ):
604652 if time is None :
605653 time = datetime .now ()
@@ -608,7 +656,8 @@ def format_info_string_no_node_types(lm_summary, time=None):
608656
609657 node_lines = []
610658 for node_type , count in lm_summary .node_types :
611- line = f" { count } node(s) with resources: { node_type } "
659+ line = (f" { count } node(s) with resources:"
660+ f"{ format_no_node_type_string (node_type )} " )
612661 node_lines .append (line )
613662 node_report = "\n " .join (node_lines )
614663
0 commit comments