diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f93834b..92a401a4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ aws-parallelcluster-node CHANGELOG This file is used to list changes made in each version of the aws-parallelcluster-node package. +3.14.0 +------ + +**CHANGES** +- Support prioritized and capacity-optimized-prioritized Allocation Strategy + 3.13.2 ------ diff --git a/src/slurm_plugin/fleet_manager.py b/src/slurm_plugin/fleet_manager.py index d4e37aa99..8fc932192 100644 --- a/src/slurm_plugin/fleet_manager.py +++ b/src/slurm_plugin/fleet_manager.py @@ -296,11 +296,18 @@ def _evaluate_template_overrides(self) -> list: if self._compute_resource_config.get("MaxPrice"): overrides.update({"MaxPrice": str(self._compute_resource_config["MaxPrice"])}) + priority = 0.0 for instance_type in self._compute_resource_config["Instances"]: - subnet_ids = self._compute_resource_config["Networking"]["SubnetIds"] + subnet_ids = self._compute_resource_config.get("Networking", {}).get("SubnetIds", []) for subnet_id in subnet_ids: - overrides.update({"InstanceType": instance_type["InstanceType"], "SubnetId": subnet_id}) + if self._uses_subnet_prioritization(): + overrides.update( + {"InstanceType": instance_type["InstanceType"], "SubnetId": subnet_id, "Priority": priority} + ) + else: + overrides.update({"InstanceType": instance_type["InstanceType"], "SubnetId": subnet_id}) template_overrides.append(copy.deepcopy(overrides)) + priority += 1.0 return template_overrides def _uses_single_instance_type(self): @@ -312,6 +319,15 @@ def _uses_single_az(self): subnet_ids = self._compute_resource_config.get("Networking", {}).get("SubnetIds", []) return len(subnet_ids) == 1 + def _uses_subnet_prioritization(self): + return ( + self._compute_resource_config.get("AllocationStrategy") == "prioritized" + and self._compute_resource_config["CapacityType"] == "on-demand" + ) or ( + self._compute_resource_config.get("AllocationStrategy") == "capacity-optimized-prioritized" + and self._compute_resource_config["CapacityType"] == "spot" + ) + def _evaluate_launch_params(self, count): """Evaluate parameters to be passed to create_fleet call.""" try: diff --git a/tests/common.py b/tests/common.py index 95fd16ccb..cb5cf85fd 100644 --- a/tests/common.py +++ b/tests/common.py @@ -110,6 +110,56 @@ def client_error(error_code): "CapacityReservationId": "cr-234567", }, }, + "queue-single-az": { + "c5xlarge": {"Api": "run-instances", "Instances": [{"InstanceType": "c5.xlarge"}]}, + "fleet1": { + "Api": "create-fleet", + "Instances": [{"InstanceType": "t2.medium"}, {"InstanceType": "t2.large"}], + "AllocationStrategy": "prioritized", + "CapacityType": "on-demand", + "Networking": MULTIPLE_SUBNETS, + }, + }, + "queue-prioritized": { + "c5xlarge": {"Api": "run-instances", "Instances": [{"InstanceType": "c5.xlarge"}]}, + "fleet1": { + "Api": "create-fleet", + "Instances": [{"InstanceType": "t2.medium"}, {"InstanceType": "t2.large"}], + "AllocationStrategy": "prioritized", + "CapacityType": "on-demand", + "Networking": MULTIPLE_SUBNETS, + }, + }, + "queue-capacity-optimized-prioritized": { + "c5xlarge": {"Api": "run-instances", "Instances": [{"InstanceType": "c5.xlarge"}]}, + "fleet1": { + "Api": "create-fleet", + "Instances": [{"InstanceType": "t2.medium"}, {"InstanceType": "t2.large"}], + "AllocationStrategy": "capacity-optimized-prioritized", + "CapacityType": "spot", + "Networking": MULTIPLE_SUBNETS, + }, + }, + "queue-prioritized-all-or-nothing": { + "c5xlarge": {"Api": "run-instances", "Instances": [{"InstanceType": "c5.xlarge"}]}, + "fleet1": { + "Api": "create-fleet", + "Instances": [{"InstanceType": "t2.medium"}], + "AllocationStrategy": "prioritized", + "CapacityType": "on-demand", + "Networking": MULTIPLE_SUBNETS, + }, + }, + "queue-capacity-optimized-prioritized-all-or-nothing": { + "c5xlarge": {"Api": "run-instances", "Instances": [{"InstanceType": "c5.xlarge"}]}, + "fleet1": { + "Api": "create-fleet", + "Instances": [{"InstanceType": "t2.medium"}], + "AllocationStrategy": "capacity-optimized-prioritized", + "CapacityType": "spot", + "Networking": MULTIPLE_SUBNETS, + }, + }, } LAUNCH_OVERRIDES = {} diff --git a/tests/slurm_plugin/test_fleet_manager.py b/tests/slurm_plugin/test_fleet_manager.py index 1f6e96e88..9db222bd3 100644 --- a/tests/slurm_plugin/test_fleet_manager.py +++ b/tests/slurm_plugin/test_fleet_manager.py @@ -391,6 +391,15 @@ class TestEc2CreateFleetManager: {}, "All-or-Nothing is only available with single instance type compute resources or single subnet queues", ), + # Use "prioritized" Allocation Strategy AND Launch Override with Priority + (5, "queue-prioritized", "fleet1", False, {}, None), + # Use "capacity-optimized-prioritized" Allocation Strategy AND Launch Override with Priority + (5, "queue-capacity-optimized-prioritized", "fleet1", False, {}, None), + # Use "prioritized" Allocation Strategy AND Launch Override with Priority AND all_or_nothing is True + (5, "queue-prioritized-all-or-nothing", "fleet1", True, {}, None), + # Use "capacity-optimized-prioritized" Allocation Strategy + # AND Launch Override with Priority AND all_or_nothing is True + (5, "queue-capacity-optimized-prioritized-all-or-nothing", "fleet1", True, {}, None), ], ids=[ "fleet_spot", @@ -402,6 +411,10 @@ class TestEc2CreateFleetManager: "fleet-multi-az-single-it-all_or_nothing", "fleet-multi-az-multi-it", "fleet-multi-az-multi-it-all_or_nothing", + "prioritized", + "capacity_optimized_prioritized", + "prioritized_all_or_nothing", + "capacity_optimized_prioritized_all_or_nothing", ], ) def test_evaluate_launch_params( diff --git a/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/capacity_optimized_prioritized/expected_launch_params.json b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/capacity_optimized_prioritized/expected_launch_params.json new file mode 100644 index 000000000..6cc00f9cc --- /dev/null +++ b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/capacity_optimized_prioritized/expected_launch_params.json @@ -0,0 +1,42 @@ +{ + "LaunchTemplateConfigs": [ + { + "LaunchTemplateSpecification": { + "LaunchTemplateName": "hit-queue-capacity-optimized-prioritized-fleet1", + "Version": "$Latest" + }, + "Overrides": [ + { + "InstanceType": "t2.medium", + "SubnetId": "1234567", + "Priority": 0.0 + }, + { + "InstanceType": "t2.medium", + "SubnetId": "7654321", + "Priority": 1.0 + }, + { + "InstanceType": "t2.large", + "SubnetId": "1234567", + "Priority": 2.0 + }, + { + "InstanceType": "t2.large", + "SubnetId": "7654321", + "Priority": 3.0 + } + ] + } + ], + "SpotOptions": { + "SingleInstanceType": false, + "SingleAvailabilityZone": false, + "AllocationStrategy": "capacity-optimized-prioritized" + }, + "TargetCapacitySpecification": { + "TotalTargetCapacity": 5, + "DefaultTargetCapacityType": "spot" + }, + "Type": "instant" +} \ No newline at end of file diff --git a/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/capacity_optimized_prioritized_all_or_nothing/expected_launch_params.json b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/capacity_optimized_prioritized_all_or_nothing/expected_launch_params.json new file mode 100644 index 000000000..b032f4da6 --- /dev/null +++ b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/capacity_optimized_prioritized_all_or_nothing/expected_launch_params.json @@ -0,0 +1,33 @@ +{ + "LaunchTemplateConfigs": [ + { + "LaunchTemplateSpecification": { + "LaunchTemplateName": "hit-queue-capacity-optimized-prioritized-all-or-nothing-fleet1", + "Version": "$Latest" + }, + "Overrides": [ + { + "InstanceType": "t2.medium", + "SubnetId": "1234567", + "Priority": 0.0 + }, + { + "InstanceType": "t2.medium", + "SubnetId": "7654321", + "Priority": 1.0 + } + ] + } + ], + "SpotOptions": { + "SingleInstanceType": true, + "SingleAvailabilityZone": false, + "AllocationStrategy": "capacity-optimized-prioritized", + "MinTargetCapacity": 5 + }, + "TargetCapacitySpecification": { + "TotalTargetCapacity": 5, + "DefaultTargetCapacityType": "spot" + }, + "Type": "instant" +} \ No newline at end of file diff --git a/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/prioritized/expected_launch_params.json b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/prioritized/expected_launch_params.json new file mode 100644 index 000000000..c214d7d0c --- /dev/null +++ b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/prioritized/expected_launch_params.json @@ -0,0 +1,45 @@ +{ + "LaunchTemplateConfigs": [ + { + "LaunchTemplateSpecification": { + "LaunchTemplateName": "hit-queue-prioritized-fleet1", + "Version": "$Latest" + }, + "Overrides": [ + { + "InstanceType": "t2.medium", + "SubnetId": "1234567", + "Priority": 0.0 + }, + { + "InstanceType": "t2.medium", + "SubnetId": "7654321", + "Priority": 1.0 + }, + { + "InstanceType": "t2.large", + "SubnetId": "1234567", + "Priority": 2.0 + }, + { + "InstanceType": "t2.large", + "SubnetId": "7654321", + "Priority": 3.0 + } + ] + } + ], + "OnDemandOptions": { + "AllocationStrategy": "prioritized", + "SingleInstanceType": false, + "SingleAvailabilityZone": false, + "CapacityReservationOptions": { + "UsageStrategy": "use-capacity-reservations-first" + } + }, + "TargetCapacitySpecification": { + "TotalTargetCapacity": 5, + "DefaultTargetCapacityType": "on-demand" + }, + "Type": "instant" +} \ No newline at end of file diff --git a/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/prioritized_all_or_nothing/expected_launch_params.json b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/prioritized_all_or_nothing/expected_launch_params.json new file mode 100644 index 000000000..de8ba7fae --- /dev/null +++ b/tests/slurm_plugin/test_fleet_manager/TestEc2CreateFleetManager/test_evaluate_launch_params/prioritized_all_or_nothing/expected_launch_params.json @@ -0,0 +1,36 @@ +{ + "LaunchTemplateConfigs": [ + { + "LaunchTemplateSpecification": { + "LaunchTemplateName": "hit-queue-prioritized-all-or-nothing-fleet1", + "Version": "$Latest" + }, + "Overrides": [ + { + "InstanceType": "t2.medium", + "SubnetId": "1234567", + "Priority": 0.0 + }, + { + "InstanceType": "t2.medium", + "SubnetId": "7654321", + "Priority": 1.0 + } + ] + } + ], + "OnDemandOptions": { + "AllocationStrategy": "prioritized", + "SingleInstanceType": true, + "SingleAvailabilityZone": false, + "CapacityReservationOptions": { + "UsageStrategy": "use-capacity-reservations-first" + }, + "MinTargetCapacity": 5 + }, + "TargetCapacitySpecification": { + "TotalTargetCapacity": 5, + "DefaultTargetCapacityType": "on-demand" + }, + "Type": "instant" +} \ No newline at end of file