Loading raps/cooling.py +12 −14 Original line number Diff line number Diff line Loading @@ -206,7 +206,7 @@ class ThermoFluidsModel: return fmu_inputs def calculate_pue(self, cooling_input, datacenter_output, cep_output): def calculate_pue(self, cooling_input, cooling_output): """ Calculate the Power Usage Effectiveness (PUE) of the data center. Loading @@ -230,13 +230,13 @@ class ThermoFluidsModel: return np.array(value_in_kw) * 1e3 if value_in_kw is not None else 0.0 # Convert values from kW to Watts using the utility function W_HTWPs = convert_to_watts(cep_output.get(W_HTWPs_KEY)) W_CTWPs = convert_to_watts(cep_output.get(W_CTWPs_KEY)) W_CTs = convert_to_watts(cep_output.get(W_CTs_KEY)) W_HTWPs = convert_to_watts(cooling_output.get(W_HTWPs_KEY)) W_CTWPs = convert_to_watts(cooling_output.get(W_CTWPs_KEY)) W_CTs = convert_to_watts(cooling_output.get(W_CTs_KEY)) # Get the sum of the work done by all CDU pumps W_CDUPs = sum( convert_to_watts(datacenter_output.get(f'simulator[1].datacenter[1].computeBlock[{idx+1}].cdu[1].summary.W_flow_CDUP_kW')) convert_to_watts(cooling_output.get(f'simulator[1].datacenter[1].computeBlock[{idx+1}].cdu[1].summary.W_flow_CDUP_kW')) for idx in range(NUM_CDUS) ) Loading Loading @@ -283,22 +283,20 @@ class ThermoFluidsModel: self.fmu.doStep(currentCommunicationPoint=current_time, communicationStepSize=step_size) # Initialize dictionaries for cooling input, datacenter output, and CEP output cooling_input = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.inputs} datacenter_output = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.outputs if "datacenter" in v.name} cep_output = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.outputs if "centralEnergyPlant" in v.name} cooling_inputs = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.inputs} cooling_outputs = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.outputs} # Calculate PUE pue = self.calculate_pue(cooling_input, datacenter_output, cep_output) pue = self.calculate_pue(cooling_inputs, cooling_outputs) # Append time to each dictionary cooling_input['time'] = current_time datacenter_output['time'] = current_time cep_output['time'] = current_time cooling_inputs['time'] = current_time cooling_outputs['pue'] = pue # Append the combined results to the history self.fmu_history.append({**cooling_input, **datacenter_output, **cep_output}) self.fmu_history.append({**cooling_inputs, **cooling_outputs}) return cooling_input, datacenter_output, cep_output, pue return cooling_inputs, cooling_outputs def terminate(self): """ Loading raps/scheduler.py +6 −10 Original line number Diff line number Diff line Loading @@ -81,9 +81,7 @@ class TickData: g_flops_w: float system_util: float fmu_inputs: Optional[dict] fmu_datacenter_outputs: Optional[dict] fmu_cep_outputs: Optional[dict] pue: Optional[float] fmu_outputs: Optional[dict] def get_utilization(trace, time_quanta_index): Loading Loading @@ -315,7 +313,7 @@ class Scheduler: # Render the updated layout power_df = None cooling_inputs, datacenter_outputs, cep_outputs, pue = None, None, None, None cooling_inputs, cooling_outputs = None, None # Update power history every 15s if self.current_time % POWER_UPDATE_FREQ == 0: Loading @@ -339,7 +337,7 @@ class Scheduler: # FMU inputs are N powers and the wetbulb temp fmu_inputs = self.cooling_model.generate_fmu_inputs(runtime_values, \ uncertainties=self.power_manager.uncertainties) cooling_inputs, datacenter_outputs, cep_outputs, pue = \ cooling_inputs, cooling_outputs =\ self.cooling_model.step(self.current_time, fmu_inputs, FMU_UPDATE_FREQ) # Get a dataframe of the power data Loading @@ -347,9 +345,9 @@ class Scheduler: if self.layout_manager: self.layout_manager.update_powertemp_array(power_df, \ datacenter_outputs, pue, pflops, gflop_per_watt, \ cooling_outputs, pflops, gflop_per_watt, \ system_util, uncertainties=self.power_manager.uncertainties) self.layout_manager.update_pressflow_array(datacenter_outputs) self.layout_manager.update_pressflow_array(cooling_outputs) if self.current_time % UI_UPDATE_FREQ == 0: # Get a dataframe of the power data Loading @@ -373,9 +371,7 @@ class Scheduler: g_flops_w = gflop_per_watt, system_util = system_util, fmu_inputs = cooling_inputs, fmu_datacenter_outputs = datacenter_outputs, fmu_cep_outputs = cep_outputs, pue = pue fmu_outputs = cooling_outputs, ) self.current_time += 1 Loading raps/ui.py +7 −7 Original line number Diff line number Diff line Loading @@ -163,10 +163,10 @@ class LayoutManager: # Update the layout self.layout["status"].update(Panel(Align(table, align="center"), title="Scheduler Stats")) def update_pressflow_array(self, datacenter_outputs): def update_pressflow_array(self, cooling_outputs): columns = ["Output", "Average Value"] datacenter_df = self.get_datacenter_df(datacenter_outputs) datacenter_df = self.get_datacenter_df(cooling_outputs) # List of keys to include in the table relevant_keys = [ Loading @@ -187,7 +187,7 @@ class LayoutManager: self.add_table_rows(table, data) self.layout["pressflow"].update(Panel(table)) def get_datacenter_df(self, datacenter_outputs): def get_datacenter_df(self, cooling_outputs): # Initialize data dictionary with keys from FMU_COLUMN_MAPPING data = {key: [] for key in FMU_COLUMN_MAPPING.keys()} Loading @@ -197,7 +197,7 @@ class LayoutManager: # Append data to the corresponding lists dynamically using FMU_COLUMN_MAPPING keys for key in FMU_COLUMN_MAPPING.keys(): data[key].append(datacenter_outputs.get(compute_block_key + key)) data[key].append(cooling_outputs.get(compute_block_key + key)) # Convert to DataFrame df = pd.DataFrame(data) Loading @@ -205,7 +205,7 @@ class LayoutManager: return df def update_powertemp_array(self, power_df, datacenter_outputs, pue, pflops, gflop_per_watt, system_util, uncertainties=False): def update_powertemp_array(self, power_df, cooling_outputs, pflops, gflop_per_watt, system_util, uncertainties=False): """ Updates the displayed power and temperature table with the provided data. Loading @@ -222,7 +222,7 @@ class LayoutManager: # Updated cooling keys to include temperature instead of pressure cooling_keys = ["T_prim_s_C", "T_prim_r_C", "T_sec_s_C", "T_sec_r_C"] datacenter_df = self.get_datacenter_df(datacenter_outputs) datacenter_df = self.get_datacenter_df(cooling_outputs) # Create column headers with appropriate styles columns = [f"{col} (kW)" if col != "CDU" else col for col in power_columns] Loading Loading @@ -278,7 +278,7 @@ class LayoutManager: str(f"{pflops:.2f}"), str(f"{gflop_per_watt:.1f}"), total_loss_str + " (" + percent_loss_str+ ")", f"{pue:.2f}", f"{cooling_outputs['pue']:.2f}", style="white" # Apply white style to all elements in the row ) Loading Loading
raps/cooling.py +12 −14 Original line number Diff line number Diff line Loading @@ -206,7 +206,7 @@ class ThermoFluidsModel: return fmu_inputs def calculate_pue(self, cooling_input, datacenter_output, cep_output): def calculate_pue(self, cooling_input, cooling_output): """ Calculate the Power Usage Effectiveness (PUE) of the data center. Loading @@ -230,13 +230,13 @@ class ThermoFluidsModel: return np.array(value_in_kw) * 1e3 if value_in_kw is not None else 0.0 # Convert values from kW to Watts using the utility function W_HTWPs = convert_to_watts(cep_output.get(W_HTWPs_KEY)) W_CTWPs = convert_to_watts(cep_output.get(W_CTWPs_KEY)) W_CTs = convert_to_watts(cep_output.get(W_CTs_KEY)) W_HTWPs = convert_to_watts(cooling_output.get(W_HTWPs_KEY)) W_CTWPs = convert_to_watts(cooling_output.get(W_CTWPs_KEY)) W_CTs = convert_to_watts(cooling_output.get(W_CTs_KEY)) # Get the sum of the work done by all CDU pumps W_CDUPs = sum( convert_to_watts(datacenter_output.get(f'simulator[1].datacenter[1].computeBlock[{idx+1}].cdu[1].summary.W_flow_CDUP_kW')) convert_to_watts(cooling_output.get(f'simulator[1].datacenter[1].computeBlock[{idx+1}].cdu[1].summary.W_flow_CDUP_kW')) for idx in range(NUM_CDUS) ) Loading Loading @@ -283,22 +283,20 @@ class ThermoFluidsModel: self.fmu.doStep(currentCommunicationPoint=current_time, communicationStepSize=step_size) # Initialize dictionaries for cooling input, datacenter output, and CEP output cooling_input = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.inputs} datacenter_output = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.outputs if "datacenter" in v.name} cep_output = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.outputs if "centralEnergyPlant" in v.name} cooling_inputs = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.inputs} cooling_outputs = {v.name: self.fmu.getReal([v.valueReference])[0] for v in self.outputs} # Calculate PUE pue = self.calculate_pue(cooling_input, datacenter_output, cep_output) pue = self.calculate_pue(cooling_inputs, cooling_outputs) # Append time to each dictionary cooling_input['time'] = current_time datacenter_output['time'] = current_time cep_output['time'] = current_time cooling_inputs['time'] = current_time cooling_outputs['pue'] = pue # Append the combined results to the history self.fmu_history.append({**cooling_input, **datacenter_output, **cep_output}) self.fmu_history.append({**cooling_inputs, **cooling_outputs}) return cooling_input, datacenter_output, cep_output, pue return cooling_inputs, cooling_outputs def terminate(self): """ Loading
raps/scheduler.py +6 −10 Original line number Diff line number Diff line Loading @@ -81,9 +81,7 @@ class TickData: g_flops_w: float system_util: float fmu_inputs: Optional[dict] fmu_datacenter_outputs: Optional[dict] fmu_cep_outputs: Optional[dict] pue: Optional[float] fmu_outputs: Optional[dict] def get_utilization(trace, time_quanta_index): Loading Loading @@ -315,7 +313,7 @@ class Scheduler: # Render the updated layout power_df = None cooling_inputs, datacenter_outputs, cep_outputs, pue = None, None, None, None cooling_inputs, cooling_outputs = None, None # Update power history every 15s if self.current_time % POWER_UPDATE_FREQ == 0: Loading @@ -339,7 +337,7 @@ class Scheduler: # FMU inputs are N powers and the wetbulb temp fmu_inputs = self.cooling_model.generate_fmu_inputs(runtime_values, \ uncertainties=self.power_manager.uncertainties) cooling_inputs, datacenter_outputs, cep_outputs, pue = \ cooling_inputs, cooling_outputs =\ self.cooling_model.step(self.current_time, fmu_inputs, FMU_UPDATE_FREQ) # Get a dataframe of the power data Loading @@ -347,9 +345,9 @@ class Scheduler: if self.layout_manager: self.layout_manager.update_powertemp_array(power_df, \ datacenter_outputs, pue, pflops, gflop_per_watt, \ cooling_outputs, pflops, gflop_per_watt, \ system_util, uncertainties=self.power_manager.uncertainties) self.layout_manager.update_pressflow_array(datacenter_outputs) self.layout_manager.update_pressflow_array(cooling_outputs) if self.current_time % UI_UPDATE_FREQ == 0: # Get a dataframe of the power data Loading @@ -373,9 +371,7 @@ class Scheduler: g_flops_w = gflop_per_watt, system_util = system_util, fmu_inputs = cooling_inputs, fmu_datacenter_outputs = datacenter_outputs, fmu_cep_outputs = cep_outputs, pue = pue fmu_outputs = cooling_outputs, ) self.current_time += 1 Loading
raps/ui.py +7 −7 Original line number Diff line number Diff line Loading @@ -163,10 +163,10 @@ class LayoutManager: # Update the layout self.layout["status"].update(Panel(Align(table, align="center"), title="Scheduler Stats")) def update_pressflow_array(self, datacenter_outputs): def update_pressflow_array(self, cooling_outputs): columns = ["Output", "Average Value"] datacenter_df = self.get_datacenter_df(datacenter_outputs) datacenter_df = self.get_datacenter_df(cooling_outputs) # List of keys to include in the table relevant_keys = [ Loading @@ -187,7 +187,7 @@ class LayoutManager: self.add_table_rows(table, data) self.layout["pressflow"].update(Panel(table)) def get_datacenter_df(self, datacenter_outputs): def get_datacenter_df(self, cooling_outputs): # Initialize data dictionary with keys from FMU_COLUMN_MAPPING data = {key: [] for key in FMU_COLUMN_MAPPING.keys()} Loading @@ -197,7 +197,7 @@ class LayoutManager: # Append data to the corresponding lists dynamically using FMU_COLUMN_MAPPING keys for key in FMU_COLUMN_MAPPING.keys(): data[key].append(datacenter_outputs.get(compute_block_key + key)) data[key].append(cooling_outputs.get(compute_block_key + key)) # Convert to DataFrame df = pd.DataFrame(data) Loading @@ -205,7 +205,7 @@ class LayoutManager: return df def update_powertemp_array(self, power_df, datacenter_outputs, pue, pflops, gflop_per_watt, system_util, uncertainties=False): def update_powertemp_array(self, power_df, cooling_outputs, pflops, gflop_per_watt, system_util, uncertainties=False): """ Updates the displayed power and temperature table with the provided data. Loading @@ -222,7 +222,7 @@ class LayoutManager: # Updated cooling keys to include temperature instead of pressure cooling_keys = ["T_prim_s_C", "T_prim_r_C", "T_sec_s_C", "T_sec_r_C"] datacenter_df = self.get_datacenter_df(datacenter_outputs) datacenter_df = self.get_datacenter_df(cooling_outputs) # Create column headers with appropriate styles columns = [f"{col} (kW)" if col != "CDU" else col for col in power_columns] Loading Loading @@ -278,7 +278,7 @@ class LayoutManager: str(f"{pflops:.2f}"), str(f"{gflop_per_watt:.1f}"), total_loss_str + " (" + percent_loss_str+ ")", f"{pue:.2f}", f"{cooling_outputs['pue']:.2f}", style="white" # Apply white style to all elements in the row ) Loading