diff --git a/sky/clouds/aws.py b/sky/clouds/aws.py index 74654fdcb04..b2cbf4f292a 100644 --- a/sky/clouds/aws.py +++ b/sky/clouds/aws.py @@ -441,7 +441,7 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> resources_utils.FeasibleResources: if resources.instance_type is not None: assert resources.is_launchable(), resources # Check the instance type is valid in the cloud @@ -452,10 +452,10 @@ def _get_feasible_launchable_resources( region=resources.region, zone=resources.zone) if not regions: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) # Treat Resources(AWS, p3.2x, V100) as Resources(AWS, p3.2x). resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -481,9 +481,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -499,10 +499,10 @@ def _make(instance_list): zone=resources.zone, clouds='aws') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), - fuzzy_candidate_list, None) + return resources_utils.FeasibleResources(_make(instance_list), + fuzzy_candidate_list, None) @classmethod @functools.lru_cache(maxsize=1) # Cache since getting identity is slow. diff --git a/sky/clouds/azure.py b/sky/clouds/azure.py index f42d33bf8d5..cd3d9ff4059 100644 --- a/sky/clouds/azure.py +++ b/sky/clouds/azure.py @@ -378,17 +378,17 @@ def _failover_disk_tier() -> Optional[resources_utils.DiskTier]: def _get_feasible_launchable_resources( self, - resources: 'resources.Resources') -> 'resources.FeasibleResources': + resources: 'resources.Resources') -> 'resources_utils.FeasibleResources': if resources.instance_type is not None: assert resources.is_launchable(), resources ok, _ = Azure.check_disk_tier(resources.instance_type, resources.disk_tier) if not ok: - return resources.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) # Treat Resources(Azure, Standard_NC4as_T4_v3, T4) as # Resources(Azure, Standard_NC4as_T4_v3). resources = resources.copy(accelerators=None) - return resources.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -418,9 +418,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -436,8 +436,8 @@ def _make(instance_list): zone=resources.zone, clouds='azure') if instance_list is None: - return resources.FeasibleResources([], fuzzy_candidate_list, None) - return resources.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/cloud.py b/sky/clouds/cloud.py index b3d4d532932..fb9f2af989c 100644 --- a/sky/clouds/cloud.py +++ b/sky/clouds/cloud.py @@ -343,7 +343,7 @@ def is_label_valid(cls, label_key: str, def get_feasible_launchable_resources( self, resources: 'resources_lib.Resources', - num_nodes: int = 1) -> 'resources_lib.FeasibleResources': + num_nodes: int = 1) -> 'resources_utils.FeasibleResources': """Returns FeasibleResources for the given resources. Feasible resources refer to an offering respecting the resource @@ -376,7 +376,7 @@ def get_feasible_launchable_resources( # TODO(zhwu): The resources are now silently filtered out. We # should have some logging telling the user why the resources # are not considered. - return resources_lib.FeasibleResources(resources_list=[], + return resources_utils.FeasibleResources(resources_list=[], fuzzy_candidate_list=[], hint=None) return self._get_feasible_launchable_resources(resources) diff --git a/sky/clouds/cudo.py b/sky/clouds/cudo.py index 0658a7fcf31..56cff711fbf 100644 --- a/sky/clouds/cudo.py +++ b/sky/clouds/cudo.py @@ -215,13 +215,13 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': if resources.use_spot: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -244,9 +244,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -262,9 +262,9 @@ def _make(instance_list): zone=resources.zone, clouds='cudo') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/fluidstack.py b/sky/clouds/fluidstack.py index 73658696f2c..bb996d0f534 100644 --- a/sky/clouds/fluidstack.py +++ b/sky/clouds/fluidstack.py @@ -211,7 +211,7 @@ def _get_feasible_launchable_resources( assert resources.is_launchable(), resources # Accelerators are part of the instance type in Fluidstack Cloud resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -239,9 +239,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -257,9 +257,9 @@ def _make(instance_list): zone=resources.zone, clouds='fluidstack') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/gcp.py b/sky/clouds/gcp.py index 241b3dc1f68..17806883b14 100644 --- a/sky/clouds/gcp.py +++ b/sky/clouds/gcp.py @@ -526,10 +526,10 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, - resources: 'resources.Resources') -> 'resources.FeasibleResources': + resources: 'resources.Resources') -> 'resources_utils.FeasibleResources': if resources.instance_type is not None: assert resources.is_launchable(), resources - return resources.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) if resources.accelerators is None: # Return a default instance type with the given number of vCPUs. @@ -538,7 +538,7 @@ def _get_feasible_launchable_resources( memory=resources.memory, disk_tier=resources.disk_tier) if host_vm_type is None: - return resources.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: r = resources.copy( cloud=GCP(), @@ -547,7 +547,7 @@ def _get_feasible_launchable_resources( cpus=None, memory=None, ) - return resources.FeasibleResources([r], [], None) + return resources_utils.FeasibleResources([r], [], None) # Find instance candidates to meet user's requirements assert len(resources.accelerators.items() @@ -569,7 +569,7 @@ def _get_feasible_launchable_resources( clouds='gcp') if instance_list is None: - return resources.FeasibleResources([], fuzzy_candidate_list, None) + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) assert len( instance_list ) == 1, f'More than one instance type matched, {instance_list}' @@ -584,13 +584,13 @@ def _get_feasible_launchable_resources( if resources.cpus.endswith('+'): cpus = float(resources.cpus[:-1]) if cpus > num_cpus_in_tpu_vm: - return resources.FeasibleResources([], - fuzzy_candidate_list, - None) + return resources_utils.FeasibleResources([], + fuzzy_candidate_list, + None) else: cpus = float(resources.cpus) if cpus != num_cpus_in_tpu_vm: - return resources.FeasibleResources([], + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) # FIXME(woosuk, wei-lin): This leverages the fact that TPU VMs @@ -601,13 +601,13 @@ def _get_feasible_launchable_resources( if resources.memory.endswith('+'): memory = float(resources.memory[:-1]) if memory > memory_in_tpu_vm: - return resources.FeasibleResources([], + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) else: memory = float(resources.memory) if memory != memory_in_tpu_vm: - return resources.FeasibleResources([], + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) else: @@ -621,7 +621,7 @@ def _get_feasible_launchable_resources( cpus=None, memory=None, ) - return resources.FeasibleResources([r], fuzzy_candidate_list, None) + return resources_utils.FeasibleResources([r], fuzzy_candidate_list, None) @classmethod def get_accelerators_from_instance_type( diff --git a/sky/clouds/ibm.py b/sky/clouds/ibm.py index 42fe05ba46c..5bd2c5d9b0c 100644 --- a/sky/clouds/ibm.py +++ b/sky/clouds/ibm.py @@ -266,12 +266,12 @@ def get_default_instance_type( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': fuzzy_candidate_list: List[str] = [] if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], + return resources_utils.FeasibleResources([resources], fuzzy_candidate_list, None) def _make(instance_list): @@ -297,9 +297,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -314,9 +314,9 @@ def _make(instance_list): zone=resources.zone, clouds='ibm') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/kubernetes.py b/sky/clouds/kubernetes.py index d1a401d46f2..7c6416fda5f 100644 --- a/sky/clouds/kubernetes.py +++ b/sky/clouds/kubernetes.py @@ -338,12 +338,12 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': fuzzy_candidate_list: List[str] = [] if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], + return resources_utils.FeasibleResources([resources], fuzzy_candidate_list, None) def _make(instance_list): @@ -400,10 +400,10 @@ def _make(instance_list): logger.debug(f'Instance type {chosen_instance_type} does ' 'not fit in the Kubernetes cluster. ' f'Reason: {reason}') - return resources_lib.FeasibleResources([], [], reason) + return resources_utils.FeasibleResources([], [], reason) # No fuzzy lists for Kubernetes - return resources_lib.FeasibleResources(_make([chosen_instance_type]), + return resources_utils.FeasibleResources(_make([chosen_instance_type]), [], None) @classmethod diff --git a/sky/clouds/lambda_cloud.py b/sky/clouds/lambda_cloud.py index 4fb92fddf72..b4a98520738 100644 --- a/sky/clouds/lambda_cloud.py +++ b/sky/clouds/lambda_cloud.py @@ -178,12 +178,12 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': if resources.instance_type is not None: assert resources.is_launchable(), resources # Accelerators are part of the instance type in Lambda Cloud resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -209,9 +209,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -227,9 +227,9 @@ def _make(instance_list): zone=resources.zone, clouds='lambda') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/oci.py b/sky/clouds/oci.py index 747564be0ba..7971713d2d4 100644 --- a/sky/clouds/oci.py +++ b/sky/clouds/oci.py @@ -295,11 +295,11 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -326,9 +326,9 @@ def _make(instance_list): disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -345,10 +345,10 @@ def _make(instance_list): zone=resources.zone, clouds='oci') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/paperspace.py b/sky/clouds/paperspace.py index 986b32e0816..72cbc3e7ee5 100644 --- a/sky/clouds/paperspace.py +++ b/sky/clouds/paperspace.py @@ -196,11 +196,11 @@ def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources'): """Returns a list of feasible resources for the given resources.""" if resources.use_spot: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -223,9 +223,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -242,9 +242,9 @@ def _make(instance_list): clouds='paperspace', )) if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/runpod.py b/sky/clouds/runpod.py index 075c7b46414..465b4714062 100644 --- a/sky/clouds/runpod.py +++ b/sky/clouds/runpod.py @@ -187,12 +187,12 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': """Returns a list of feasible resources for the given resources.""" if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -215,9 +215,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -232,9 +232,9 @@ def _make(instance_list): zone=resources.zone, clouds='runpod') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/scp.py b/sky/clouds/scp.py index 43bb10c94bd..9f52ebaf8f5 100644 --- a/sky/clouds/scp.py +++ b/sky/clouds/scp.py @@ -251,16 +251,16 @@ def _get_default_ami(cls, region_name: str, instance_type: str) -> str: def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources' - ) -> 'resources_lib.FeasibleResources': + ) -> 'resources_utils.FeasibleResources': # Check if the host VM satisfies the min/max disk size limits. is_allowed = self._is_disk_size_allowed(resources) if not is_allowed: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) if resources.instance_type is not None: assert resources.is_launchable(), resources # Accelerators are part of the instance type in SCP Cloud resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -287,9 +287,9 @@ def _make(instance_list): memory=resources.memory, disk_tier=resources.disk_tier) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -305,9 +305,9 @@ def _make(instance_list): zone=resources.zone, clouds='scp') if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/clouds/vsphere.py b/sky/clouds/vsphere.py index a9836de95b8..61724cd0d70 100644 --- a/sky/clouds/vsphere.py +++ b/sky/clouds/vsphere.py @@ -197,11 +197,11 @@ def make_deploy_resources_variables( def _get_feasible_launchable_resources( self, resources: 'resources_lib.Resources'): if resources.use_spot: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) if resources.instance_type is not None: assert resources.is_launchable(), resources resources = resources.copy(accelerators=None) - return resources_lib.FeasibleResources([resources], [], None) + return resources_utils.FeasibleResources([resources], [], None) def _make(instance_list): resource_list = [] @@ -226,9 +226,9 @@ def _make(instance_list): disk_tier=resources.disk_tier, ) if default_instance_type is None: - return resources_lib.FeasibleResources([], [], None) + return resources_utils.FeasibleResources([], [], None) else: - return resources_lib.FeasibleResources( + return resources_utils.FeasibleResources( _make([default_instance_type]), [], None) assert len(accelerators) == 1, resources @@ -247,9 +247,9 @@ def _make(instance_list): clouds=_CLOUD_VSPHERE, ) if instance_list is None: - return resources_lib.FeasibleResources([], fuzzy_candidate_list, + return resources_utils.FeasibleResources([], fuzzy_candidate_list, None) - return resources_lib.FeasibleResources(_make(instance_list), + return resources_utils.FeasibleResources(_make(instance_list), fuzzy_candidate_list, None) @classmethod diff --git a/sky/optimizer.py b/sky/optimizer.py index bf76c45b859..3c1c3456bb6 100644 --- a/sky/optimizer.py +++ b/sky/optimizer.py @@ -1246,7 +1246,7 @@ def _fill_in_launchable_resources( # Assume feasible_resources is sorted by prices. Guaranteed by # the implementation of get_feasible_launchable_resources and # the underlying service_catalog filtering - cheapest = feasible_resources[0] + cheapest = feasible_resources.resources_list[0] # Generate region/zone-specified resources. launchable[resources].extend( _make_launchables_for_valid_region_zones(cheapest)) diff --git a/sky/resources.py b/sky/resources.py index 2ee3bd81fce..f0cb1abda1e 100644 --- a/sky/resources.py +++ b/sky/resources.py @@ -1567,21 +1567,3 @@ def __setstate__(self, state): '_cluster_config_overrides', None) self.__dict__.update(state) - - -@dataclasses.dataclass -class FeasibleResources: - """Feasible resources returned by cloud. - - Used to represent a collection of feasible resources returned by cloud, - any fuzzy candidates, and optionally a string hint if no feasible resources - are found. - - Fuzzy candidates example: when the requested GPU is A100:1 but is not - available in a cloud/region, the fuzzy candidates are results of a fuzzy - search in the catalog that are offered in the location. E.g., - ['A100-80GB:1', 'A100-80GB:2', 'A100-80GB:4', 'A100:8'] - """ - resources_list: List[Resources] - fuzzy_candidate_list: List[str] - hint: Optional[str] diff --git a/sky/utils/resources_utils.py b/sky/utils/resources_utils.py index 87a62dab95b..0a45242779e 100644 --- a/sky/utils/resources_utils.py +++ b/sky/utils/resources_utils.py @@ -9,6 +9,7 @@ from sky.utils import ux_utils if typing.TYPE_CHECKING: + from sky import resources as resources_lib from sky import backends _PORT_RANGE_HINT_MSG = ('Invalid port range {}. Please use the format ' @@ -157,3 +158,21 @@ def get_readable_resources_repr(handle: 'backends.CloudVmRayResourceHandle', launched_resource_str) return f'{handle.launched_nodes}x {launched_resource_str}' return _DEFAULT_MESSAGE_HANDLE_INITIALIZING + + +@dataclasses.dataclass +class FeasibleResources: + """Feasible resources returned by cloud. + + Used to represent a collection of feasible resources returned by cloud, + any fuzzy candidates, and optionally a string hint if no feasible resources + are found. + + Fuzzy candidates example: when the requested GPU is A100:1 but is not + available in a cloud/region, the fuzzy candidates are results of a fuzzy + search in the catalog that are offered in the location. E.g., + ['A100-80GB:1', 'A100-80GB:2', 'A100-80GB:4', 'A100:8'] + """ + resources_list: List['resources_lib.Resources'] + fuzzy_candidate_list: List[str] + hint: Optional[str]