in analysis/GreenSKU-Framework/src/carbon_model.py [0:0]
def __init__(self, config_file: str, data_source_dir: str="../data/carbon_data",
overwrite_params=None, print_out=True) -> None:
"""Initialize the class.
Args:
config_file: The YAML file containing the server configuration.
params_file: The YAML file containing the server parameters.
"""
if data_source_dir is None:
data_source_dir = "../data/carbon_data"
self.print_out = print_out
self.config = read_yaml(config_file)['server']
params_file = join_path(data_source_dir, 'params.yaml')
self.params = read_yaml(params_file)
if 'cpu_efficiency' not in self.params:
self.params['cpu_efficiency'] = 1.0
if 'power_factor' not in self.params:
self.params['power_factor'] = 1.0
if 'fan_slope' not in self.params:
self.params['fan_slope'] = -1.0
else:
if '2U_server_base' not in self.params or '1U_server_base' not in self.params:
raise ValueError('Fan slope specified but no base server power specified')
self.params['2U_server_base'] = strip_power(self.params['2U_server_base'])
self.params['1U_server_base'] = strip_power(self.params['1U_server_base'])
if self.print_out:
print(f"Calculating SKU carbon for {self.config['name']}...")
if overwrite_params is not None:
for key, value in overwrite_params.items():
if key in self.params:
self.params[key] = value
else:
raise ValueError(f'Parameter {key} not found in params.yaml')
if 'emissions_factor' in self.params:
# convert from kgCO2e/kWh to kgCO2e/kWMonth
self.params['emissions_factor'] = self.params['emissions_factor']*24*30
# set the number of sockets based on number of CPUs
self._set_socket_count()
# pull the data for the components
self.data = {}
self.data['cpu'] = index_cpu_data(self.config['cpu']['vendor'],
self.config['cpu']['type'],
self.config['cpu']['core_count'],
data_source=data_source_dir)
self.data['cpu']['number'] = self.config['cpu']['number']
self.data['memory'] = index_memory_data(self.config['memory']['type'],
self.config['memory']['frequency'],
self.config['memory']['size'],
data_source=data_source_dir)
self.data['memory']['number'] = self.config['memory']['number']
self.data['cxl'] = index_memory_data(self.config['cxl']['type'],
self.config['cxl']['frequency'],
self.config['cxl']['size'],
data_source=data_source_dir)
self.data['cxl']['number'] = self.config['cxl']['number']
if self.data['cxl']['number'] > 0:
self.data['cxl_controller'] = index_cxl_controller_data(self.config['cxl']['controller'],
data_source=data_source_dir)
controller_dimm_capacity = self.data['cxl_controller']['channels'] * self.data['cxl_controller']['dimms_per_channel']
self.data['cxl_controller']['number'] = ceil(self.config['cxl']['number'] / controller_dimm_capacity)
else:
self.data['cxl_controller'] = {'number': 0, 'power': 0, 'size': 0, 'carbon': 0}
self.data['ssd'] = index_ssd_data(self.config['ssd']['type'],
self.config['ssd']['size'],
data_source=data_source_dir)
self.data['ssd']['number'] = self.config['ssd']['number']
if 'ssd_reuse' in self.config:
self.data['ssd_reuse'] = index_ssd_data(self.config['ssd_reuse']['type'],
self.config['ssd_reuse']['size'],
data_source=data_source_dir,
reuse=True)
self.data['ssd_reuse']['number'] = self.config['ssd_reuse']['number']
self.data['nic'] = index_nic_data(self.config['nic']['bandwidth'],
data_source=data_source_dir)
self.data['nic']['number'] = self.config['nic']['number']
for key in self.data:
self.data[key] = convert_units(self.data[key])
# pull data for server and rack - these will both be lists of dicts
self.data['dc'], dc_config = index_dc_data(self.config['dc']['type'],
data_source=data_source_dir)
self.data['rack'] = index_rack_data(self.config['rack']['type'],
data_source=data_source_dir)
self.data['server'] = index_server_data(self.config['type'],
data_source=data_source_dir)
# set dc config
for key, value in dc_config.items():
self.config['dc'][key] = value
self.config['dc']['power_capacity'] = strip_power(self.config['dc']['power_capacity'])
self.config['dc']['rack_capacity'] = float(self.config['dc']['rack_capacity'])
for comp in self.data['server']:
if 'carbon' not in self.data['server'][comp]:
self.data['server'][comp]['carbon'] = 0.0
self.data['server'][comp] = convert_units(self.data['server'][comp])
for comp in self.data['rack']:
if 'carbon' not in self.data['rack'][comp]:
self.data['rack'][comp]['carbon'] = 0.0
self.data['rack'][comp] = convert_units(self.data['rack'][comp])
self.config['rack'] = convert_units(self.config['rack'])
for comp in self.data['dc']:
if 'carbon' not in self.data['dc'][comp]:
self.data['dc'][comp]['carbon'] = 0.0
self.data['dc'][comp] = convert_units(self.data['dc'][comp])
# dicts with component keys, values are derate curves
self.component_derate_curves = {}
self._set_derate_curves()
# set resource capacities
self.capacities = {}
self._set_capacities()
# set the components per server
self.num_components = {}
self._set_num_components()
# per component power
self.allocated_component_power = {}
self.provisioned_component_power = {}
self._set_component_power()
# set fan power for the server
self.server_power_no_fan = None
self._set_fan_power()
# reset since fan power has changed
self._set_component_power()
# per component operational and embodied emissions
self.component_operational = {}
self.component_embodied = {}
self.component_carbon = {}
self._set_component_carbon()
# get per-server operational and embodied emissions
self.component_server_operational = {}
self.component_server_embodied = {}
self.component_server_carbon = {}
self.server_carbon = 0
self.server_embodied = 0
self.server_operational = 0
self._set_server_carbon()
# set the number of servers
self.server_count = 0
self.power_limited = False
self._set_server_count()
# set the per-rack operational and embodied carbon
self.component_rack_operational = {}
self.component_rack_embodied = {}
self.component_rack_carbon = {}
self.rack_carbon = 0
self.rack_embodied = 0
self.rack_operational = 0
self._set_rack_carbon()
# set the number of racks
self.rack_count = 0
self.dc_power_limited = False
self._set_rack_count()
# set the per-dc operational and embodied carbon
self.component_dc_operational = {}
self.component_dc_embodied = {}
self.component_dc_carbon = {}
self.dc_carbon = 0
self.dc_embodied = 0
self.dc_operational = 0
self._set_dc_carbon()
# set the sellable cores
self.sellable_cores = self.vCores = 0
self._set_sellable_cores()
if print_out:
self.print_summary()