


# Copyright 2021 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os

from ...utils.constants import SAGEMAKER_PARALLEL_EC2_INSTANCES, TORCH_DYNAMO_MODES
from ...utils.dataclasses import ComputeEnvironment, SageMakerDistributedType
from ...utils.imports import is_botoa_available
from .config_args import SageMakerConfig
from .config_utils import (
    DYNAMO_BACKENDS,
    _ask_field,
    _ask_options,
    _convert_dynamo_backend,
    _convert_mixed_precision,
    _convert_sagemaker_distributed_mode,
    _convert_yes_no_to_bool,
)


if is_botoa_available():
     import botoa  # noqa: F401
def 				__lowerCamelCase						( UpperCAmelCase_						:		Dict						):




      """simple docstring"""





      a						:Tuple 							=       botoa.client('''iam'''						)

      a						:List[Any] 							=       {
          '''Version''': '''2012-10-17''',
          '''Statement''': [
              {'''Effect''': '''Allow''', '''Principal''': {'''Service''': '''sagemaker.amazonaws.com'''}, '''Action''': '''sts:AssumeRole'''}
          ],
      }
      try:
            # create the role, associated with the chosen trust policy
            iam_client.create_role(
                RoleName=UpperCAmelCase_ ,  AssumeRolePolicyDocument=json.dumps(UpperCAmelCase_ ,  indent=2						)						)
            a						:List[Any] 							=       {
                '''Version''': '''2012-10-17''',
                '''Statement''': [
                    {
                        '''Effect''': '''Allow''',
                        '''Action''': [
                            '''sagemaker:*''',
                            '''ecr:GetDownloadUrlForLayer''',
                            '''ecr:BatchGetImage''',
                            '''ecr:BatchCheckLayerAvailability''',
                            '''ecr:GetAuthorizationToken''',
                            '''cloudwatch:PutMetricData''',
                            '''cloudwatch:GetMetricData''',
                            '''cloudwatch:GetMetricStatistics''',
                            '''cloudwatch:ListMetrics''',
                            '''logs:CreateLogGroup''',
                            '''logs:CreateLogStream''',
                            '''logs:DescribeLogStreams''',
                            '''logs:PutLogEvents''',
                            '''logs:GetLogEvents''',
                            '''s3:CreateBucket''',
                            '''s3:ListBucket''',
                            '''s3:GetBucketLocation''',
                            '''s3:GetObject''',
                            '''s3:PutObject''',
                        ],
                        '''Resource''': '''*''',
                    }
                ],
            }
            # attach policy to role
            iam_client.put_role_policy(
                RoleName=UpperCAmelCase_ ,  PolicyName=F'''{role_name}_policy_permission''' ,  PolicyDocument=json.dumps(UpperCAmelCase_ ,  indent=2						) ,  )
      except iam_client.exceptions.EntityAlreadyExistsException:
            print(F'''role {role_name} already exists. Using existing one'''						)
def 				__lowerCamelCase						( UpperCAmelCase_						:		Optional[int]						):




      """simple docstring"""





      a						:List[Any] 							=       botoa.client('''iam'''						)
      return iam_client.get_role(RoleName=UpperCAmelCase_						)["Role"]["Arn"]






def 				__lowerCamelCase						( ):




      """simple docstring"""





      a						:int 							=       _ask_options(
          '''How do you want to authorize?''' ,  ['''AWS Profile''', '''Credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) '''] ,  UpperCAmelCase_ ,  )
      a						:Union[str, Any] 							=       None
      if credentials_configuration == 0:
            a						:Optional[Any] 							=       _ask_field('''Enter your AWS Profile name: [default] ''' ,  default='''default'''						)
            a						:List[Any] 							=       aws_profile
      else:
            print(
                '''Note you will need to provide AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY when you launch you training script with,'''
                '''`accelerate launch --aws_access_key_id XXX --aws_secret_access_key YYY`'''						)
            a						:Dict 							=       _ask_field('''AWS Access Key ID: '''						)
            a						:Dict 							=       aws_access_key_id

            a						:Union[str, Any] 							=       _ask_field('''AWS Secret Access Key: '''						)
            a						:str 							=       aws_secret_access_key

      a						:List[Any] 							=       _ask_field('''Enter your AWS Region: [us-east-1]''' ,  default='''us-east-1'''						)
      a						:List[str] 							=       aws_region

      a						:Dict 							=       _ask_options(
          '''Do you already have an IAM Role for executing Amazon SageMaker Training Jobs?''' ,  ['''Provide IAM Role name''', '''Create new IAM role using credentials'''] ,  UpperCAmelCase_ ,  )
      if role_management == 0:
            a						:Optional[int] 							=       _ask_field('''Enter your IAM role name: '''						)
      else:
            a						:Tuple 							=       '''accelerate_sagemaker_execution_role'''
            print(F'''Accelerate will create an iam role "{iam_role_name}" using the provided credentials'''						)
            _create_iam_role_for_sagemaker(UpperCAmelCase_						)

      a						:List[Any] 							=       _ask_field(
          '''Do you want to use custom Docker image? [yes/NO]: ''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )
      a						:Dict 							=       None
      if is_custom_docker_image:
            a						:List[Any] 							=       _ask_field('''Enter your Docker image: ''' ,  lambda UpperCAmelCase_						: str(UpperCAmelCase_						).lower()						)

      a						:str 							=       _ask_field(
          '''Do you want to provide SageMaker input channels with data locations? [yes/NO]: ''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )
      a						:int 							=       None
      if is_sagemaker_inputs_enabled:
            a						:Optional[int] 							=       _ask_field(
                '''Enter the path to the SageMaker inputs TSV file with columns (channel_name, data_location): ''' ,  lambda UpperCAmelCase_						: str(UpperCAmelCase_						).lower() ,  )

      a						:Dict 							=       _ask_field(
          '''Do you want to enable SageMaker metrics? [yes/NO]: ''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )
      a						:Optional[int] 							=       None
      if is_sagemaker_metrics_enabled:
            a						:Tuple 							=       _ask_field(
                '''Enter the path to the SageMaker metrics TSV file with columns (metric_name, metric_regex): ''' ,  lambda UpperCAmelCase_						: str(UpperCAmelCase_						).lower() ,  )

      a						:str 							=       _ask_options(
          '''What is the distributed mode?''' ,  ['''No distributed training''', '''Data parallelism'''] ,  _convert_sagemaker_distributed_mode ,  )
      a						:List[str] 							=       {}
      a						:Optional[int] 							=       _ask_field(
          '''Do you wish to optimize your script with torch dynamo?[yes/NO]:''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )
      if use_dynamo:
            a						:List[str] 							=       '''dynamo_'''
            a						:Optional[Any] 							=       _ask_options(
                '''Which dynamo backend would you like to use?''' ,  [x.lower() for x in DYNAMO_BACKENDS] ,  _convert_dynamo_backend ,  default=2 ,  )
            a						:List[str] 							=       _ask_field(
                '''Do you want to customize the defaults sent to torch.compile? [yes/NO]: ''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )

            if use_custom_options:
                  a						:Optional[int] 							=       _ask_options(
                      '''Which mode do you want to use?''' ,  UpperCAmelCase_ ,  lambda UpperCAmelCase_						: TORCH_DYNAMO_MODES[int(UpperCAmelCase_						)] ,  default='''default''' ,  )
                  a						:Optional[Any] 							=       _ask_field(
                      '''Do you want the fullgraph mode or it is ok to break model into several subgraphs? [yes/NO]: ''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )
                  a						:Union[str, Any] 							=       _ask_field(
                      '''Do you want to enable dynamic shape tracing? [yes/NO]: ''' ,  _convert_yes_no_to_bool ,  default=UpperCAmelCase_ ,  error_message='''Please enter yes or no.''' ,  )
      a						:Tuple 							=       '''Which EC2 instance type you want to use for your training?'''
      if distributed_type != SageMakerDistributedType.NO:
            a						:int 							=       _ask_options(
                UpperCAmelCase_ ,  UpperCAmelCase_ ,  lambda UpperCAmelCase_						: SAGEMAKER_PARALLEL_EC2_INSTANCES[int(UpperCAmelCase_						)]						)
      else:
            eca_instance_query += "? [ml.p3.2xlarge]:"
            a						:List[str] 							=       _ask_field(UpperCAmelCase_ ,  lambda UpperCAmelCase_						: str(UpperCAmelCase_						).lower() ,  default='''ml.p3.2xlarge'''						)

      a						:Dict 							=       1
      if distributed_type in (SageMakerDistributedType.DATA_PARALLEL, SageMakerDistributedType.MODEL_PARALLEL):
            a						:Union[str, Any] 							=       _ask_field(
                '''How many machines do you want use? [1]: ''' ,  UpperCAmelCase_ ,  default=1 ,  )

      a						:Optional[int] 							=       _ask_options(
          '''Do you wish to use FP16 or BF16 (mixed precision)?''' ,  ['''no''', '''fp16''', '''bf16''', '''fp8'''] ,  _convert_mixed_precision ,  )

      if use_dynamo and mixed_precision == "no":
            print(
                '''Torch dynamo used without mixed precision requires TF32 to be efficient. Accelerate will enable it by default when launching your scripts.'''						)

      return SageMakerConfig(
          image_uri=UpperCAmelCase_ ,  compute_environment=ComputeEnvironment.AMAZON_SAGEMAKER ,  distributed_type=UpperCAmelCase_ ,  use_cpu=UpperCAmelCase_ ,  dynamo_config=UpperCAmelCase_ ,  eca_instance_type=UpperCAmelCase_ ,  profile=UpperCAmelCase_ ,  region=UpperCAmelCase_ ,  iam_role_name=UpperCAmelCase_ ,  mixed_precision=UpperCAmelCase_ ,  num_machines=UpperCAmelCase_ ,  sagemaker_inputs_file=UpperCAmelCase_ ,  sagemaker_metrics_file=UpperCAmelCase_ ,  )









def 			_a (      SCREAMING_SNAKE_CASE						,				SCREAMING_SNAKE_CASE						,				SCREAMING_SNAKE_CASE     ):


		"""simple docstring"""




		if exponent == 1:
				return base
		if exponent % 2 == 0:
				lowercase__            =      _modexpt(SCREAMING_SNAKE_CASE						,				exponent // 2						,				SCREAMING_SNAKE_CASE     ) % modulo_value
				return (x * x) % modulo_value
		else:
				return (base * _modexpt(SCREAMING_SNAKE_CASE						,				exponent - 1						,				SCREAMING_SNAKE_CASE     )) % modulo_value
def 			_a (      SCREAMING_SNAKE_CASE = 17_77						,				SCREAMING_SNAKE_CASE = 18_55						,				SCREAMING_SNAKE_CASE = 8     ):


		"""simple docstring"""




		lowercase__            =      base
		for _ in range(1						,				SCREAMING_SNAKE_CASE     ):
				lowercase__            =      _modexpt(SCREAMING_SNAKE_CASE						,				SCREAMING_SNAKE_CASE						,				10**digits     )

		return result


if __name__ == "__main__":
			print(f"""{solution() = }""")


