cloud_instances = [
    {
        "service_provider": "Amazon",
        "instance_types": [
            # For Intel / AMD, this configuration assumes following
            # 1. No hyperthreading, for it could decrease performance
            # 2. Single process is assumed. Multi-process may squeeze out more perf in some cases
            {
                "type": "c5.large",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 2,
                "hyperthreading": True,
                "usd_per_hr": 0.085,
                "predictor_target": "c5.2xlarge",
                "predictor_num_threads": 4,
                "predictor_latency_scaling_factor": 4.0 / 1.0,
            },
            {
                "type": "c5.xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 4,
                "hyperthreading": True,
                "usd_per_hr": 0.170,
                "predictor_target": "c5.2xlarge",
                "predictor_num_threads": 4,
                "predictor_latency_scaling_factor": 4.0 / 2.0,
            },
            {
                "type": "c5.2xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 8,
                "hyperthreading": True,
                "usd_per_hr": 0.340,
                "predictor_target": "c5.2xlarge",
                "predictor_num_threads": 4,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5.4xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 16,
                "hyperthreading": True,
                "usd_per_hr": 0.680,
                "predictor_target": "c5.4xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5.9xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 36,
                "hyperthreading": True,
                "usd_per_hr": 1.530,
                "predictor_target": "c5.9xlarge",
                "predictor_num_threads": 18,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5.12xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 48,
                "hyperthreading": True,
                "usd_per_hr": 2.040,
                "predictor_target": "c5.12xlarge",
                "predictor_num_threads": 24,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5.18xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 72,
                "hyperthreading": True,
                "usd_per_hr": 3.060,
                "predictor_target": "c5.18xlarge",
                "predictor_num_threads": 36,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5.24xlarge",
                "class": "c5",
                "hw": "Intel Xeon",
                "cores": 96,
                "hyperthreading": True,
                "usd_per_hr": 4.080,
                "predictor_target": "c5.24xlarge",
                "predictor_num_threads": 48,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5a.large",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 2,
                "hyperthreading": True,
                "usd_per_hr": 0.077,
                "predictor_target": "c5a.4xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 8.0 / 1.0,
            },
            {
                "type": "c5a.xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 4,
                "hyperthreading": True,
                "usd_per_hr": 0.154,
                "predictor_target": "c5a.4xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 8.0 / 2.0,
            },
            {
                "type": "c5a.2xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 8,
                "hyperthreading": True,
                "usd_per_hr": 0.308,
                "predictor_target": "c5a.4xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 8.0 / 4.0,
            },
            {
                "type": "c5a.4xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 16,
                "hyperthreading": True,
                "usd_per_hr": 0.616,
                "predictor_target": "c5a.4xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5a.8xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 32,
                "hyperthreading": True,
                "usd_per_hr": 1.232,
                "predictor_target": "c5a.8xlarge",
                "predictor_num_threads": 16,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5a.12xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 48,
                "hyperthreading": True,
                "usd_per_hr": 1.848,
                "predictor_target": "c5a.12xlarge",
                "predictor_num_threads": 24,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5a.16xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 64,
                "hyperthreading": True,
                "usd_per_hr": 2.464,
                "predictor_target": "c5a.16xlarge",
                "predictor_num_threads": 32,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c5a.24xlarge",
                "class": "c5a",
                "hw": "AMD EPYC",
                "cores": 96,
                "hyperthreading": True,
                "usd_per_hr": 3.696,
                "predictor_target": "c5a.24xlarge",
                "predictor_num_threads": 48,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c6g.medium",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 1,
                "hyperthreading": False,
                "usd_per_hr": 0.034,
                "predictor_target": "c6g.2xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 8.0 / 1.0,
            },
            {
                "type": "c6g.large",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 2,
                "hyperthreading": False,
                "usd_per_hr": 0.068,
                "predictor_target": "c6g.2xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 8.0 / 2.0,
            },
            {
                "type": "c6g.xlarge",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 4,
                "hyperthreading": False,
                "usd_per_hr": 0.136,
                "predictor_target": "c6g.2xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 8.0 / 4.0,
            },
            {
                "type": "c6g.2xlarge",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 8,
                "hyperthreading": False,
                "usd_per_hr": 0.272,
                "predictor_target": "c6g.2xlarge",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c6g.4xlarge",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 16,
                "hyperthreading": False,
                "usd_per_hr": 0.544,
                "predictor_target": "c6g.4xlarge",
                "predictor_num_threads": 16,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c6g.8xlarge",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 32,
                "hyperthreading": False,
                "usd_per_hr": 1.088,
                "predictor_target": "c6g.8xlarge",
                "predictor_num_threads": 32,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c6g.12xlarge",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 48,
                "hyperthreading": False,
                "usd_per_hr": 1.632,
                "predictor_target": "c6g.12xlarge",
                "predictor_num_threads": 48,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "c6g.16xlarge",
                "class": "c6g",
                "hw": "Amazon Graviton2",
                "cores": 64,
                "hyperthreading": False,
                "usd_per_hr": 2.176,
                "predictor_target": "c6g.16xlarge",
                "predictor_num_threads": 64,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "T4",
                "class": "T4",
                "hw": "NVIDIA T4 GPUs",
                "cores": 8,
                "hyperthreading": False,
                "usd_per_hr": 0.752,
                "predictor_target": "T4",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "v100",
                "class": "v100",
                "hw": "NVIDIA V100 GPUs",
                "cores": 8,
                "hyperthreading": False,
                "usd_per_hr": 3.06,
                "predictor_target": "v100",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 1.0,
            },
            # {
            #   "type": "g3s.xlarge",
            #   "class": "g3s",
            #   "hw" : "NVIDIA Tesla M60 GPU",
            #   "cores" : 2,
            #   "hyperthreading": False,
            #   "usd_per_hr" : 0.75,
            #   "predictor_target": "g3s.xlarge",
            #   "predictor_num_threads": 4,
            #   "predictor_latency_scaling_factor": 1.0
            # },
        ],
    },
    {
        "service_provider": "Oracle",
        "instance_types": [
            {
                "type": "VM.Standard.A1.Flex 2vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 2,
                "hyperthreading": False,
                "usd_per_hr": 0.026,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 2,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 4vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 4,
                "hyperthreading": False,
                "usd_per_hr": 0.052,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 4,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 8vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 8,
                "hyperthreading": False,
                "usd_per_hr": 0.104,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 8,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 16vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 16,
                "hyperthreading": False,
                "usd_per_hr": 0.208,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 16,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 32vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 32,
                "hyperthreading": False,
                "usd_per_hr": 0.416,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 32,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 48vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 48,
                "hyperthreading": False,
                "usd_per_hr": 0.624,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 48,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 64vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 64,
                "hyperthreading": False,
                "usd_per_hr": 0.832,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 64,
                "predictor_latency_scaling_factor": 1.0,
            },
            {
                "type": "VM.Standard.A1.Flex 80vCPU",
                "class": "VM.Standard.A1.Flex",
                "hw": "Ampere Altra",
                "cores": 80,
                "hyperthreading": False,
                "usd_per_hr": 1.040,
                "predictor_target": "VM.Standard.A1.Flex",
                "predictor_num_threads": 80,
                "predictor_latency_scaling_factor": 1.0,
            },
        ],
    },
]

supported_hardwares = [
    {
        "name": "Ampere Altra",
        "vendor": "Ampere",
        "arch": "armv8.2+",
    },
    {
        "name": "Intel Xeon",
        "vendor": "Intel",
        "arch": "x86",
    },
    {
        "name": "AMD EPYC",
        "vendor": "AMD",
        "arch": "amd64",
    },
    {
        "name": "Amazon Graviton2",
        "vendor": "Amazon",
        "arch": "Arm64 Neoverse",
    },
    {
        "name": "NVIDIA T4 GPUs",
        "vendor": "NVIDIA T4 GPUs",
        "arch": "NVIDIA T4 GPUs",
    },
    {
        "name": "NVIDIA V100 GPUs",
        "vendor": "NVIDIA V100 GPUs",
        "arch": "NVIDIA V100 GPUs",
    },
]

supported_quants = [
    "FP32",
    "FP16",
    "INT8",
]

supported_frameworks = ["TENSORFLOW", "ONNX", "PYTORCH", "TFLITE"]

supported_domains = [
    {
        "domain": "Computer Vision",
        "tasks": [
            "Classification",
            "Object Detection",
            "Image Segmentation",
            "Depth Estimation",
            "Pose Estimation",
        ],
    },
    {"domain": "NLP", "tasks": ["Translation", "Text Classification", "BERT"]},
]


def is_domain_task_supported(domain, task):
    for supported_domain in supported_domains:
        if supported_domain["domain"] == domain:
            for supported_task in supported_domain["tasks"]:
                if supported_task == task:
                    return True
    return False


def find_instances_with_config(hw, num_threads):
    instances_list = []
    for service in cloud_instances:
        for instance in service["instance_types"]:
            num_cores = num_threads
            # Our prediction do not use hyperthreading(which is not efficient)
            # So, the num threads column refers to num of phyical cores used
            # Need to multiply it by 2 for looking up within instance table
            if instance["hyperthreading"] == True:
                num_cores = num_cores * 2

            if instance["hw"] == hw and instance["cores"] == num_cores:
                instances_list.append(
                    (
                        service["service_provider"],
                        instance["type"],
                        instance["usd_per_hr"],
                    )
                )
    return instances_list
