def _GenerateCreateCommand()

in perfkitbenchmarker/providers/aws/aws_virtual_machine.py [0:0]


  def _GenerateCreateCommand(self):
    """Generate VM Create Command."""
    assert self.network is not None
    placement = []
    if not util.IsRegion(self.zone):
      placement.append('AvailabilityZone=%s' % self.zone)
    if self.use_dedicated_host:
      placement.append('Tenancy=host,HostId=%s' % self.host.id)
      self.num_hosts = len(self.host_list)
    elif self.placement_group:
      placement.append('GroupName=%s' % self.placement_group.name)

    placement = ','.join(placement)
    block_device_map = GetBlockDeviceMap(self)
    if not self.aws_tags:
      # Set tags for the AWS VM. If we are retrying the create, we have to use
      # the same tags from the previous call.
      self.aws_tags.update(self.vm_metadata)
      self.aws_tags.update(util.MakeDefaultTags())
      # Signal (along with timeout_utc) that VM is short lived.
      self.aws_tags['vm_nature'] = 'ephemeral'
    reservation_id = aws_flags.AWS_CAPACITY_BLOCK_RESERVATION_ID.value
    if reservation_id:
      reservation_args = [
          '--count=1',
          '--instance-market-options=MarketType="capacity-block"',
          '--capacity-reservation-specification=CapacityReservationTarget='
          '{CapacityReservationId=%s}' % reservation_id]
    else:
      reservation_args = []
    create_cmd = util.AWS_PREFIX + [
        'ec2',
        'run-instances',
        '--region=%s' % self.region,
        '--client-token=%s' % self.client_token,
        '--image-id=%s' % self.image,
        '--instance-type=%s' % self.machine_type,
        '--key-name=%s' % AwsKeyFileManager.GetKeyNameForRun(),
        '--tag-specifications=%s'
        % util.FormatTagSpecifications('instance', self.aws_tags),
    ] + reservation_args

    if FLAGS.aws_vm_hibernate:
      create_cmd.extend([
          '--hibernation-options=Configured=true',
      ])

    # query fails on hpc6a.48xlarge which already disables smt.
    if FLAGS.disable_smt and self.machine_type not in (
        'hpc6a.48xlarge',
        'hpc6id.32xlarge',
        'hpc7a.96xlarge',
    ):
      query_cmd = util.AWS_PREFIX + [
          'ec2',
          'describe-instance-types',
          '--instance-types',
          self.machine_type,
          '--query',
          'InstanceTypes[0].VCpuInfo.DefaultCores',
      ]
      stdout, _, _ = vm_util.IssueCommand(query_cmd)
      cores = int(json.loads(stdout))
      create_cmd.append(f'--cpu-options=CoreCount={cores},ThreadsPerCore=1')
    if FLAGS.aws_efa:
      efas = ['--network-interfaces']
      for device_index in range(FLAGS.aws_efa_count):
        # You can assign up to one EFA per network card.
        efa_params = _EFA_PARAMS.copy()
        efa_params.update({
            'NetworkCardIndex': device_index,
            'DeviceIndex': device_index,
            'Groups': self.group_id,
            'SubnetId': self.network.subnet.id,
        })
        # https://aws.amazon.com/blogs/aws/new-amazon-ec2-p5en-instances-with-nvidia-h200-tensor-core-gpus-and-efav3-networking/
        if self.machine_type in _EFA_V3_MACHINE_TYPES and device_index % 4:
          efa_params['InterfaceType'] = 'efa-only'
        if (
            self.machine_type in _EFA_V2_MACHINE_TYPES + _EFA_V3_MACHINE_TYPES
            and efa_params['DeviceIndex']
        ):
          efa_params['DeviceIndex'] = 1
        if FLAGS.aws_efa_count == 1 and self.assign_external_ip:
          efa_params['AssociatePublicIpAddress'] = True
        efas.append(
            ','.join(
                f'{key}={value}' for key, value in sorted(efa_params.items())
            )
        )
      create_cmd.extend(efas)
    elif self.network_eni_count > 1:
      enis = ['--network-interfaces']
      enis_per_network_card = self.network_eni_count // self.network_card_count
      for device_index in range(self.network_eni_count):
        eni_params = _ENI_PARAMS.copy()
        eni_params.update({
            'NetworkCardIndex': device_index // enis_per_network_card,
            'DeviceIndex': device_index,
            'Groups': self.group_id,
            'SubnetId': self.network.subnet.id,
        })
        enis.append(
            ','.join(
                f'{key}={value}' for key, value in sorted(eni_params.items())
            )
        )
      create_cmd.extend(enis)
    else:
      if self.assign_external_ip:
        create_cmd.append('--associate-public-ip-address')
      create_cmd.append(f'--subnet-id={self.network.subnet.id}')
    if block_device_map:
      create_cmd.append('--block-device-mappings=%s' % block_device_map)
    if placement:
      create_cmd.append('--placement=%s' % placement)
    if FLAGS.aws_credit_specification:
      create_cmd.append(
          '--credit-specification=%s' % FLAGS.aws_credit_specification
      )
    if self.user_data:
      create_cmd.append('--user-data=%s' % self.user_data)
    if self.capacity_reservation_id:
      create_cmd.append(
          '--capacity-reservation-specification=CapacityReservationTarget='
          '{CapacityReservationId=%s}'
          % self.capacity_reservation_id
      )
    if self.use_spot_instance:
      instance_market_options = collections.OrderedDict()
      spot_options = collections.OrderedDict()
      spot_options['SpotInstanceType'] = 'one-time'
      spot_options['InstanceInterruptionBehavior'] = 'terminate'
      if self.spot_price:
        spot_options['MaxPrice'] = str(self.spot_price)
      if self.spot_block_duration_minutes:
        spot_options['BlockDurationMinutes'] = self.spot_block_duration_minutes
      instance_market_options['MarketType'] = 'spot'
      instance_market_options['SpotOptions'] = spot_options
      create_cmd.append(
          '--instance-market-options=%s' % json.dumps(instance_market_options)
      )
    if self.instance_profile:
      create_cmd.append(f'--iam-instance-profile=Name={self.instance_profile}')
    return create_cmd