Source code for utils.make_envs

import os

import gymnasium as gym
from gymnasium import spaces

import numpy as np
import pandas as pd

from envs.sustaindc.battery_env import BatteryEnvFwd as battery_env_fwd
from envs.sustaindc.timeloadshifting_env import CarbonLoadEnv
from envs.sustaindc.dc_gym import dc_gymenv

import envs.sustaindc.datacenter_model as DataCenter
from utils.dc_config_reader import DC_Config

import itertools

[docs] def make_ls_env(month, n_vars_ci: int = 4, n_vars_energy : int = 4, n_vars_battery : int = 1, queue_max_len: int = 500, test_mode = False): """Method to build the Load shifting environment Args: month (int): Month of the year in which the agent is training. n_vars_energy (int, optional): Number of variables from the Energy environment. Defaults to 4. n_vars_battery (int, optional): Number of variables from the Battery environment. Defaults to 1. queue_max_len (int, optional): The size of the queue where the tasks are stored to be processed latter. Default to 500. Returns: CarbonLoadEnv: Load Shifting environment """ return CarbonLoadEnv(n_vars_ci=n_vars_ci, n_vars_energy=n_vars_energy, n_vars_battery=n_vars_battery, queue_max_len=queue_max_len, test_mode=test_mode)
[docs] def make_bat_fwd_env(month, max_bat_cap_Mwh : float = 2.0, charging_rate : float = 0.5, max_dc_pw_MW : float = 7.23, dcload_max : float = 2.5, dcload_min : float = 0.1, n_fwd_steps : int = 4, init_day : int = 0, ): """Method to build the Battery environment. Args: month (int): Month of the year in which the agent is training. max_bat_cap_Mwh (float, optional): Max battery capacity. Defaults to 2.0. charging_rate (float, optional): Charging rate of the battery. Defaults to 0.5. reward_method (str, optional): Method used to calculate the rewards. Defaults to 'default_bat_reward'. Returns: battery_env_fwd: Batery environment. """ env_config= {'n_fwd_steps':n_fwd_steps, 'max_dc_pw_MW':max_dc_pw_MW, 'max_bat_cap':max_bat_cap_Mwh, 'charging_rate':charging_rate, 'start_point':init_day, 'dcload_max':dcload_max, 'dcload_min':dcload_min} bat_env = battery_env_fwd(env_config) return bat_env
[docs] def make_dc_env(month : int = 1, location : str = 'NYIS', dc_config_file: str = 'dc_config_file.json', datacenter_capacity_mw: int = 1, max_bat_cap_Mw : float = 2.0, add_cpu_usage : bool = True, add_gpu_usage : bool = True, # Added GPU usage flag add_CI : bool = True, episode_length_in_time : pd.Timedelta = None, use_ls_cpu_load : bool = False, use_ls_gpu_load : bool = False, # Added GPU load flag num_sin_cos_vars : int = 4, total_cores : int = 0, total_gpus : int = 0, dc_memory_GB : int = 0, ): """Method that creates the data center environment with the timeline, location, proper data files, gym specifications and auxiliary methods Args: month (int, optional): The month of the year for which the Environment uses the weather and Carbon Intensity data. Defaults to 1. location (str, optional): The geographical location in a standard format for which Carbon Intensity files are accessed. Supported options are 'NYIS', 'AZPS', 'BPAT'. Defaults to 'NYIS'. dc_memory_GB (int, optional): The total avaialble memory in a datacenter datacenter_capacity_mw (int, optional): Maximum capacity (MW) of the data center. This value will scale the number of servers installed in the data center. max_bat_cap_Mw (float, optional): The battery capacity in Megawatts for the installed battery. Defaults to 2.0. add_cpu_usage (bool, optional): Boolean Flag to indicate whether cpu usage is part of the environment statespace. Defaults to True. add_gpu_usage (bool, optional): Boolean Flag to indicate whether gpu usage is part of the environment statespace. Defaults to True. add_CI (bool, optional): Boolean Flag to indicate whether Carbon Intensity is part of the environment statespace. Defaults to True. episode_length_in_time (pd.Timedelta, optional): Length of an episode in terms of pandas time-delta object. Defaults to None. use_ls_cpu_load (bool, optional): Use the cpu workload value from a separate Load Shifting agent. This turns of reading default cpu data. Defaults to False. use_ls_gpu_load (bool, optional): Use the gpu workload value from a separate Load Shifting agent. This turns of reading default gpu data. Defaults to False. num_sin_cos_vars (int, optional): Number of sin and cosine variable that will be added externally from the centralized data source Returns: envs.dc_gym.dc_gymenv: The environment instantiated with the particular month. """ observation_variables = [] ############################################################################ ######################### Standard Variables included as default ########### ############################################################################ observation_variables += [ 'Site Outdoor Air Drybulb Temperature(Environment)', 'Zone Thermostat Cooling Setpoint Temperature(West Zone)', 'Zone Air Temperature(West Zone)', 'Facility Total HVAC Electricity Demand Rate(Whole Building)', # 'HVAC POWER' # TODO: Will add sum of IT POWER and HVAC Power Here if AGP wants it 'Facility Total Building Electricity Demand Rate(Whole Building)', # 'IT POWER' ] # Update observation space dimensions to include GPU observation_space = spaces.Box(low=np.float32(-1.0*np.ones(15)), # Increased dimension for GPU high=np.float32(1.0*np.ones(15)), ) ################################################################################ ########################## Action Variables #################################### ################################################################################ action_variables = ['Cooling_Setpoint_RL'] action_definition = {'cooling setpoints': {'name': 'Cooling_Setpoint_RL', 'initial_value': 18}} min_temp = 15.0 max_temp = 21.6 action_mapping = { 0: (-1), 1: (0), 2: (1), } action_space = spaces.Discrete(len(action_mapping)) ################################################################################ ########################## System Sizing ##################################### ################################################################################ # from DC_Config, scale the variable number of CPUs to have a similar value to "datacenter_capacity_mw" # print(f"[INFO] Datacenter at {location} scaled to capacity: {datacenter_capacity_mw:.2f} MW") # print(f"[INFO] the datacenter has {total_cores} cores, {total_gpus} GPUs and {dc_memory_GB} GB of memory") dc_config = DC_Config(dc_config_file=dc_config_file, total_cores=total_cores, total_gpus=total_gpus, total_mem_GB=dc_memory_GB, datacenter_capacity_mw=datacenter_capacity_mw) # Specify the relative or absolute path # Perform Cooling Tower Sizing # This step determines the potential maximum loading of the CT # setting a higher ambient temp here will cause the CT to consume less power for cooling water under normal ambient temperature. Lower amb temp -> higher HVAC power # setting a lower value of min_CRAC_setpoint will cause the CT to consume more power for higher crac setpoints during normal use. Lower min_CRAC_set -> higher HVAC power # dictionary with locations and min_CRAC_setpoint/max_amb_temp # if 'NY'.lower() in location.lower(): max_amb_temperature = 30.0 # elif 'AZ'.lower() in location.lower(): # max_amb_temperature = 50.0 # elif 'WA'.lower() in location.lower(): # max_amb_temperature = 20.0 # else: # print('WARNING, using default values for chiller sizing...') # max_amb_temperature = 50.0 ctafr, ct_rated_load = DataCenter.chiller_sizing(dc_config, dc_memory_GB, min_CRAC_setpoint=min_temp, max_CRAC_setpoint=max_temp, max_ambient_temp=max_amb_temperature) dc_config.CT_REFRENCE_AIR_FLOW_RATE = ctafr dc_config.CT_FAN_REF_P = ct_rated_load # Perform sizing of ITE power and ambient temperature # Find highest and lowest values of ITE power, rackwise outlet temperature dc = DataCenter.DataCenter_ITModel(num_racks=dc_config.NUM_RACKS, dc_memory_GB=dc_memory_GB, rack_supply_approach_temp_list=dc_config.RACK_SUPPLY_APPROACH_TEMP_LIST, rack_CPU_config=dc_config.RACK_CPU_CONFIG, rack_GPU_config=dc_config.RACK_GPU_CONFIG, # Added GPU config max_W_per_rack=dc_config.MAX_W_PER_RACK, DC_ITModel_config=dc_config) raw_curr_stpt = 27 # coldest setpoint → max HVAC response cpu_load = 100 # full CPU load gpu_load = 100 # full GPU load mem_load = 100 # full MEMORY load ITE_load_pct_list = [cpu_load for _ in range(dc_config.NUM_RACKS)] GPU_load_pct_list = [gpu_load for _ in range(dc_config.NUM_RACKS)] MEMORY_load_pct_list = [mem_load for _ in range(dc_config.NUM_RACKS)] result = dc.compute_datacenter_IT_load_outlet_temp( ITE_load_pct_list=ITE_load_pct_list, CRAC_setpoint=raw_curr_stpt, GPU_load_pct_list=GPU_load_pct_list, MEMORY_load_pct_list=MEMORY_load_pct_list ) rackwise_gpu_pwr = 0 if len(result) == 5: # GPU and memory included rackwise_cpu_pwr, rackwise_itfan_pwr, memory_power, rackwise_gpu_pwr, rackwise_outlet_temp = result else: rackwise_cpu_pwr, rackwise_itfan_pwr, rackwise_outlet_temp = result ite_pwr = sum(rackwise_cpu_pwr) + sum(rackwise_itfan_pwr) + sum(memory_power) + sum(rackwise_gpu_pwr) cpu_pwr = sum(rackwise_cpu_pwr) gpu_pwr = sum(rackwise_gpu_pwr) mem_pwr = sum(memory_power) # print(f"[INFO] ITE real power: {ite_pwr:.2f} W, CPU real power: {cpu_pwr:.2f} W, GPU real power: {gpu_pwr:.2f} W, Memory real power: {mem_pwr:.2f} W") # Calculate the maximum power consumption of the chiller # Assume worst-case outside temp ambient_temp = max_amb_temperature chiller_max_load = DataCenter.calculate_chiller_power( max_cooling_cap=ct_rated_load, load=ite_pwr, ambient_temp=ambient_temp ) max_dc_power_w = 1.1 * (ite_pwr + ct_rated_load + chiller_max_load) ranges = { 'sinhour': [-1.0, 1.0], #0 'coshour': [-1.0, 1.0], #1 'sindayOTY':[-1.0, 1.0], #2 'cosdayOTY':[-1.0, 1.0], #3 'hour':[0.0, 23.0], #4 'dayOTY':[1.0, 366.0], #5 'Site Outdoor Air Drybulb Temperature(Environment)': [-10.0, 40.0], #6 'Zone Thermostat Cooling Setpoint Temperature(West Zone)': [15.0, 30.0], # reasonable range for setpoint; can be updated based on need #7 'Facility Total HVAC Electricity Demand Rate(Whole Building)': [0.0, 1.1*ct_rated_load + 1.1*chiller_max_load], # cooling tower power and chiller power 'cpuUsage':[0.0, 1.0], 'gpuUsage':[0.0, 1.0], # Added GPU usage range 'carbonIntensity':[0.0, 1000.0], 'batterySoC': [0.0, 0*1e6], 'max_battery_energy_Mwh' : 0 } ################################################################################ ############################## Create the Environment ########################## ################################################################################ dc_env = dc_gymenv(observation_variables=observation_variables, dc_memory_GB=dc_memory_GB, observation_space=observation_space, action_variables=action_variables, action_space=action_space, action_mapping=action_mapping, ranges=ranges, add_cpu_usage=add_cpu_usage, add_gpu_usage=add_gpu_usage, # Added GPU usage flag min_temp=min_temp, max_temp=max_temp, action_definition=action_definition, DC_Config=dc_config, episode_length_in_time=episode_length_in_time ) # Update max DC power to include all components (CPU, GPU, cooling) max_dc_pw = 0 return dc_env, max_dc_pw