Boavizta / boaviztapi

🛠 Giving access to BOAVIZTA reference data and methodologies trough a RESTful API
GNU Affero General Public License v3.0
66 stars 21 forks source link

No CPU core units default for lots of archetypes #270

Open VincentVillet opened 5 months ago

VincentVillet commented 5 months ago

Bug description

The following archetypes don’t have a default value for CPU core units: a1.metal c5.18xlarge c5.metal c5a.24xlarge c5ad.24xlarge c5d.18xlarge c5d.metal c5n.metal c6g.metal c6gd.metal c6gn.16xlarge g2.8xlarge g4dn.metal hs1.8xlarge i3.metal i3en.metal inf1.24xlarge m5.metal m5a.24xlarge m5ad.24xlarge m5d.metal m5dn.metal m5n.metal m5zn.metal m6g.metal m6gd.metal mac1.metal p3dn.24xlarge p4d.24xlarge r5.metal r5a.24xlarge r5ad.24xlarge r5b.metal r5d.metal r5dn.metal r5n.metal r6g.metal r6gd.metal ra3.16xlarge u-12tb1.metal u-18tb1.metal u-24tb1.metal u-6tb1.metal u-9tb1.metal x1.32xlarge x1e.32xlarge x2gd.metal z1d.metal m6a.metal c6a.metal c6i.metal c6id.metal c6in.metal c7a.metal-48xl c7g.metal c7gd.16xlarge c7gn.16xlarge c7i.48xlarge g5.48xlarge g5g.metal hpc7g.16xlarge i4g.16xlarge i4i.metal im4gn.16xlarge inf2.48xlarge is4gen.8xlarge m6i.metal m6id.metal m6idn.metal m6in.metal m7a.metal-48xl m7g.metal m7i.48xlarge p4de.24xlarge p5.48xlarge r6a.metal r6i.metal r6id.metal r6idn.metal r6in.metal r7a.metal-48xl r7g.metal r7gd.16xlarge r7iz.32xlarge trn1.32xlarge vt1.24xlarge x2idn.metal x2iedn.metal x2iezn.metal platform_aws_c1 platform_aws_c3 platform_aws_c4 platform_aws_cc2 platform_aws_cr1 platform_aws_d2 platform_aws_d3 platform_aws_d3en platform_aws_dc2 platform_aws_dl1 platform_aws_ds2 platform_aws_f1 platform_aws_g4ad platform_aws_h1 platform_aws_i2 platform_aws_m2 platform_aws_m3 platform_aws_m4-a platform_aws_m4-b platform_aws_m5-b platform_aws_p2 platform_aws_p3 platform_aws_r3 platform_aws_r4 platform_aws_t1 platform_aws_t2-a platform_aws_t2-b platform_aws_t3 platform_aws_t3a platform_aws_t4g

To Reproduce

curl -X 'GET' \ 'https://api.boavizta.org/v1/server/archetype_config?archetype=a1.metal' \ -H 'accept: application/json'

==> "CPU": { "units": { "default": 1 }, "core_units": {}, "die_size_per_core": {}, "name": { "default": "Annapurna Labs Graviton" }, "vcpu": {} }

Expected behavior

Having values for core units like "CPU": { "units": { "default": 2 }, "core_units": { "default": 24, "min": 18, "max": 48 }, "die_size_per_core": {}, "name": {}, "vcpu": {} }

Additional context

Bug found running this code:

import requests

def call_boaviztapi(url, method="GET", kwargs): headers = {'accept': 'application/json'} if method == "GET": response = requests.get(url, headers=headers, kwargs) elif method == "POST": headers["Content-Type"] = "application/json" response = requests.post(url, headers=headers, **kwargs)

if response.status_code == 200:
    return response.json()
else:
    print(f"{method} request to {url} with params {kwargs} failed with status code {response.status_code}")

def get_archetypes_and_their_configs_and_impacts(): output_dict = {} for archetype in call_boaviztapi('https://api.boavizta.org/v1/server/archetypes'): configuration = call_boaviztapi( url="https://api.boavizta.org/v1/server/archetype_config", params={"archetype": archetype}) impact = call_boaviztapi( url="https://api.boavizta.org/v1/server/", params={"archetype": archetype}) if impact is None: print(f"No impact for archetype {archetype}") else: output_dict[archetype] = {} output_dict[archetype]["config"] = configuration output_dict[archetype]["impact"] = impact

return output_dict

def print_archetypes_and_their_configs(): archetypes_data = get_archetypes_and_their_configs_and_impacts()

for archetype in archetypes_data.keys():
    config = archetypes_data[archetype]["config"]
    if "default" in config['CPU']['core_units'].keys():
        impact = archetypes_data[archetype]["impact"]
        nb_ssd_units = config['SSD']["units"]['default']
        nb_hdd_units = config['HDD']["units"]['default']

        if nb_hdd_units > 0 and nb_ssd_units > 0:
            raise ValueError(
                f"Archetype {archetype} has both SSD and HDD, please check and delete this exception raising if ok")
        storage_type = "SSD"
        if nb_hdd_units > 0:
            storage_type = "HDD"
        nb_storage_units = config[storage_type]["units"]['default']

        print(
            f"{archetype}: type {config['CASE']['case_type']['default']},\n"
            f"    {config['CPU']['units']['default']} cpu units with {config['CPU']['core_units']['default']} core units,\n"
            f"    {config['RAM']['units']['default']} RAM units with {config['RAM']['capacity']['default']} GB capacity,\n"
            f"    {nb_storage_units} {storage_type} units with {config[storage_type]['capacity']['default']} GB capacity,")

        total_gwp_embedded_value = impact["impacts"]["gwp"]["embedded"]["value"]
        storage_gwp_embedded_value = impact["verbose"][f"{storage_type}-1"]["impacts"]["gwp"]["embedded"]["value"]

        total_gwp_embedded_unit = impact["impacts"]["gwp"]["unit"]
        storage_gwp_embedded_unit = impact["verbose"][f"{storage_type}-1"]["impacts"]["gwp"]["unit"]

        assert total_gwp_embedded_unit == storage_gwp_embedded_unit

        average_power_value = impact["verbose"]["avg_power"]["value"]
        average_power_unit = impact["verbose"]["avg_power"]["unit"]

        print(
            f"    Impact fabrication compute: {total_gwp_embedded_value - storage_gwp_embedded_value} {total_gwp_embedded_unit},\n"
            f"    Impact fabrication storage: {storage_gwp_embedded_value} {storage_gwp_embedded_unit},\n"
            f"    Average power: {round(average_power_value, 1)} {average_power_unit}\n")
    else:
        print(f"No CPU core units default for {archetype}")
da-ekchajzer commented 5 months ago

imho this is not a bug.

/server/archetype_config returns the pre-recorded data in the API for a given archetype without completing the missing values.

It is only during the evaluation process that the missing data will be completed by the API with a lazy loading approach. For CPU core units it will be completed based on the name of the CPU or by default values (See https://doc.api.boavizta.org/Explanations/components/cpu/#complete)

For exemple c5.metal CPU is an Intel Xeon Platinum 8275CL. The API will complete CPU values based on this CPU name (cores_units = 32).

If you reported this as a bug it means either :

Could you describe your use case a little further ?

VincentVillet commented 5 months ago

Thank you for your answer David :)

What confused me is that the default values are filled up for some archetypes, and not for some others.

I didn’t have in mind that the default values were supposed to be filled up only during the evaluation process, what I had in mind was "BoaviztAPI always gives a value, be it a default".

And for my usage (having server builders relying on the API for e-footprint), always having a default value would be very useful.

da-ekchajzer commented 5 months ago

Some archetypes correspond to abstract servers (e.g. platform_compute_medium), in which case the attributes are set at the server level. Others correspond to specific servers, where the attributes are set from the CPU name with a completion process. In the latter case, I agree that we should return the CPU character tics in the /archetype route (WIP).

And for my usage (with server builders relying on the API for e-footprint), it would be very useful to always have a default value.

From what I can see, if you need to report a configuration along with the impacts, you should use the attribute in the verbose that returns the set of configuration data used. Each attribute has a ``STATUS'' which tells you whether the data comes from the archetype, is set by default, or is completed by the API.

The /archtype route was designed to be used in a front-end application to pre-fill a form used to request the API. You shouldn't use it as a way to characterize an impact calculation afterward.