Skip to content

Commit

Permalink
[Core] Added functionality in show_gpus to have an option to show all…
Browse files Browse the repository at this point in the history
… regions' pricing for an accelerator (#2892)

* Added functionality in show_gpus to have an option to show all regions' pricing for an accelerator

* Removed all-regions from kubernetes

* Removed all-regions from kubernetes

* Removed all-regions from kubernetes

* Fixed kubernetes unused variable issue

* Fixed kubernetes unused variable issue

* Fixed kubernetes unused variable issue

* Fixed kubernetes unused variable issue

* Update sky/cli.py

Co-authored-by: Romil Bhardwaj <[email protected]>

* Update sky/cli.py

Co-authored-by: Romil Bhardwaj <[email protected]>

* Fixed kubernetes unused variable issue

---------

Co-authored-by: Romil Bhardwaj <[email protected]>
  • Loading branch information
Vaibhav2001 and romilbhardwaj authored Dec 30, 2023
1 parent 3eb6f2f commit 6c30d79
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 44 deletions.
32 changes: 27 additions & 5 deletions sky/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3395,13 +3395,20 @@ def check(verbose: bool):
('The region to use. If not specified, shows accelerators from all regions.'
),
)
@click.option(
'--all-regions',
is_flag=True,
default=False,
help='Show pricing and instance details for a specified accelerator across '
'all regions and clouds.')
@service_catalog.fallback_to_default_catalog
@usage_lib.entrypoint
def show_gpus(
accelerator_str: Optional[str],
all: bool, # pylint: disable=redefined-builtin
cloud: Optional[str],
region: Optional[str]):
region: Optional[str],
all_regions: Optional[bool]):
"""Show supported GPU/TPU/accelerators and their prices.
The names and counts shown can be set in the ``accelerators`` field in task
Expand All @@ -3415,21 +3422,35 @@ def show_gpus(
To show all accelerators, including less common ones and their detailed
information, use ``sky show-gpus --all``.
To show all regions for a specified accelerator, use
``sky show-gpus <accelerator> --all-regions``.
Definitions of certain fields:
* ``DEVICE_MEM``: Memory of a single device; does not depend on the device
count of the instance (VM).
* ``HOST_MEM``: Memory of the host instance (VM).
If ``--region`` is not specified, the price displayed for each instance
type is the lowest across all regions for both on-demand and spot
instances. There may be multiple regions with the same lowest price.
If ``--region`` or ``--all-regions`` is not specified, the price displayed
for each instance type is the lowest across all regions for both on-demand
and spot instances. There may be multiple regions with the same lowest
price.
"""
# validation for the --region flag
if region is not None and cloud is None:
raise click.UsageError(
'The --region flag is only valid when the --cloud flag is set.')

# validation for the --all-regions flag
if all_regions and accelerator_str is None:
raise click.UsageError(
'The --all-regions flag is only valid when an accelerator '
'is specified.')
if all_regions and region is not None:
raise click.UsageError(
'--all-regions and --region flags cannot be used simultaneously.')

# This will validate 'cloud' and raise if not found.
clouds.CLOUD_REGISTRY.from_str(cloud)
service_catalog.validate_region_zone(region, None, clouds=cloud)
Expand Down Expand Up @@ -3514,7 +3535,8 @@ def _output():
quantity_filter=quantity,
region_filter=region,
clouds=cloud,
case_sensitive=False)
case_sensitive=False,
all_regions=all_regions)

if len(result) == 0:
if cloud == 'kubernetes':
Expand Down
4 changes: 2 additions & 2 deletions sky/clouds/service_catalog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ def _map_clouds_catalog(clouds: CloudFilter, method_name: str, *args, **kwargs):
# kubernetes_catalog.py
if method_name != 'list_accelerators':
clouds.remove('kubernetes')

single = isinstance(clouds, str)
if single:
clouds = [clouds] # type: ignore
Expand Down Expand Up @@ -61,6 +60,7 @@ def list_accelerators(
quantity_filter: Optional[int] = None,
clouds: CloudFilter = None,
case_sensitive: bool = True,
all_regions: bool = False,
) -> 'Dict[str, List[common.InstanceTypeInfo]]':
"""List the names of all accelerators offered by Sky.
Expand All @@ -72,7 +72,7 @@ def list_accelerators(
"""
results = _map_clouds_catalog(clouds, 'list_accelerators', gpus_only,
name_filter, region_filter, quantity_filter,
case_sensitive)
case_sensitive, all_regions)
if not isinstance(results, list):
results = [results]
ret: Dict[str,
Expand Down
7 changes: 4 additions & 3 deletions sky/clouds/service_catalog/aws_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,13 @@ def list_accelerators(
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True
) -> Dict[str, List[common.InstanceTypeInfo]]:
case_sensitive: bool = True,
all_regions: bool = False) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in AWS offering accelerators."""
return common.list_accelerators_impl('AWS', _get_df(), gpus_only,
name_filter, region_filter,
quantity_filter, case_sensitive)
quantity_filter, case_sensitive,
all_regions)


def get_image_id_from_tag(tag: str, region: Optional[str]) -> Optional[str]:
Expand Down
6 changes: 3 additions & 3 deletions sky/clouds/service_catalog/azure_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ def list_accelerators(
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True
) -> Dict[str, List[common.InstanceTypeInfo]]:
case_sensitive: bool = True,
all_regions: bool = False) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in Azure offering GPUs."""
return common.list_accelerators_impl('Azure', _df, gpus_only, name_filter,
region_filter, quantity_filter,
case_sensitive)
case_sensitive, all_regions)
21 changes: 15 additions & 6 deletions sky/clouds/service_catalog/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ def list_accelerators_impl(
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[InstanceTypeInfo]]:
"""Lists accelerators offered in a cloud service catalog.
Expand Down Expand Up @@ -500,12 +501,20 @@ def list_accelerators_impl(
grouped = df.groupby('AcceleratorName')

def make_list_from_df(rows):
# Only keep the lowest prices across regions.
rows = rows.groupby([
'InstanceType', 'AcceleratorName', 'AcceleratorCount', 'vCPUs',
'MemoryGiB'
],
dropna=False).aggregate('min').reset_index()
if all_regions:
# Keep all regions.
rows = rows.groupby([
'InstanceType', 'AcceleratorName', 'AcceleratorCount', 'vCPUs',
'MemoryGiB', 'Region'
],
dropna=False).aggregate('min').reset_index()
else:
# Only keep the lowest prices across regions.
rows = rows.groupby([
'InstanceType', 'AcceleratorName', 'AcceleratorCount', 'vCPUs',
'MemoryGiB'
],
dropna=False).aggregate('min').reset_index()
ret = rows.apply(
lambda row: InstanceTypeInfo(
cloud,
Expand Down
3 changes: 2 additions & 1 deletion sky/clouds/service_catalog/gcp_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,12 @@ def list_accelerators(
region_filter: Optional[str] = None,
quantity_filter: Optional[int] = None,
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in GCP offering GPUs."""
results = common.list_accelerators_impl('GCP', _df, gpus_only, name_filter,
region_filter, quantity_filter,
case_sensitive)
case_sensitive, all_regions)

# Remove GPUs that are unsupported by SkyPilot.
new_results = {}
Expand Down
13 changes: 7 additions & 6 deletions sky/clouds/service_catalog/ibm_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,17 @@ def get_region_zones_for_instance_type(instance_type: str,


def list_accelerators(
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in IBM offering accelerators."""
return common.list_accelerators_impl('IBM', _df, gpus_only, name_filter,
region_filter, quantity_filter,
case_sensitive)
case_sensitive, all_regions)


def get_default_instance_type(cpus: Optional[str] = None,
Expand Down
12 changes: 7 additions & 5 deletions sky/clouds/service_catalog/kubernetes_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ def is_image_tag_valid(tag: str, region: Optional[str]) -> bool:


def list_accelerators(
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[common.InstanceTypeInfo]]:
k8s_cloud = Kubernetes()
del all_regions # unused
if not any(
map(k8s_cloud.is_same_cloud, global_user_state.get_enabled_clouds())
) or not kubernetes_utils.check_credentials()[0]:
Expand Down
13 changes: 7 additions & 6 deletions sky/clouds/service_catalog/lambda_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,14 @@ def get_region_zones_for_instance_type(instance_type: str,


def list_accelerators(
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in Lambda offering GPUs."""
return common.list_accelerators_impl('Lambda', _df, gpus_only, name_filter,
region_filter, quantity_filter,
case_sensitive)
case_sensitive, all_regions)
14 changes: 8 additions & 6 deletions sky/clouds/service_catalog/oci_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,18 @@ def get_region_zones_for_instance_type(instance_type: str,


def list_accelerators(
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True
gpus_only: bool,
name_filter: Optional[str],
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in OCI offering GPUs."""
return common.list_accelerators_impl('OCI', _get_df(), gpus_only,
name_filter, region_filter,
quantity_filter, case_sensitive)
quantity_filter, case_sensitive,
all_regions)


def get_vcpus_mem_from_instance_type(
Expand Down
3 changes: 2 additions & 1 deletion sky/clouds/service_catalog/scp_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,12 @@ def list_accelerators(
region_filter: Optional[str],
quantity_filter: Optional[int],
case_sensitive: bool = True,
all_regions: bool = False,
) -> Dict[str, List[common.InstanceTypeInfo]]:
"""Returns all instance types in SCP offering GPUs."""
return common.list_accelerators_impl('scp', _df, gpus_only, name_filter,
region_filter, quantity_filter,
case_sensitive)
case_sensitive, all_regions)


def get_image_id_from_tag(tag: str, region: Optional[str]) -> Optional[str]:
Expand Down

0 comments on commit 6c30d79

Please sign in to comment.