Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add batch size to energy response #45

Merged
merged 1 commit into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion protocol/innpv.proto
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ message HabitatResponse {
message EnergyResponse {
float total_consumption = 1;
repeated EnergyConsumptionComponent components = 2;
int32 batch_size = 3;

// A list of past energy measurements
repeated EnergyResponse past_measurements = 3;
repeated EnergyResponse past_measurements = 4;
}

// Reports the energy consumption of one system component (e.g. CPU+DRAM or GPU)
Expand Down
76 changes: 40 additions & 36 deletions skyline/analysis/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,45 +150,46 @@ def energy_compute(self) -> pm.EnergyResponse:
for _ in range(iterations):
iteration(*inputs)
energy_measurer.end_measurement()

resp.total_consumption = energy_measurer.total_energy()/float(iterations)

components = []
components_joules = []

if energy_measurer.cpu_energy() is not None:
cpu_component = pm.EnergyConsumptionComponent()
cpu_component.component_type = pm.ENERGY_CPU_DRAM
cpu_component.consumption_joules = energy_measurer.cpu_energy()/float(iterations)
components.append(cpu_component)
components_joules.append(cpu_component.consumption_joules)
else:
cpu_component = pm.EnergyConsumptionComponent()
cpu_component.component_type = pm.ENERGY_CPU_DRAM
cpu_component.consumption_joules = 0.0
components.append(cpu_component)
components_joules.append(cpu_component.consumption_joules)

gpu_component = pm.EnergyConsumptionComponent()
gpu_component.component_type = pm.ENERGY_NVIDIA
gpu_component.consumption_joules = energy_measurer.gpu_energy()/float(iterations)
components.append(gpu_component)
components_joules.append(gpu_component.consumption_joules)

resp.components.extend(components)

# get last 10 runs if they exist
path_to_entry_point = os.path.join(self._project_root, self._entry_point)
past_runs = self._energy_table_interface.get_latest_n_entries_of_entry_point(10, path_to_entry_point)
print(past_runs)
resp.past_measurements.extend(_convert_to_energy_responses(past_runs))

# add current run to database
self._energy_table_interface.add_entry([path_to_entry_point] + components_joules)

except PermissionError as err:
# Remind user to set their CPU permissions
print(err)

resp.total_consumption = energy_measurer.total_energy()/float(iterations)
resp.batch_size = self._batch_size

components = []
components_joules = []

if energy_measurer.cpu_energy() is not None:
cpu_component = pm.EnergyConsumptionComponent()
cpu_component.component_type = pm.ENERGY_CPU_DRAM
cpu_component.consumption_joules = energy_measurer.cpu_energy()/float(iterations)
components.append(cpu_component)
components_joules.append(cpu_component.consumption_joules)
else:
cpu_component = pm.EnergyConsumptionComponent()
cpu_component.component_type = pm.ENERGY_CPU_DRAM
cpu_component.consumption_joules = 0.0
components.append(cpu_component)
components_joules.append(cpu_component.consumption_joules)

gpu_component = pm.EnergyConsumptionComponent()
gpu_component.component_type = pm.ENERGY_NVIDIA
gpu_component.consumption_joules = energy_measurer.gpu_energy()/float(iterations)
components.append(gpu_component)
components_joules.append(gpu_component.consumption_joules)

resp.components.extend(components)

# get last 10 runs if they exist
path_to_entry_point = os.path.join(self._project_root, self._entry_point)
past_runs = self._energy_table_interface.get_latest_n_entries_of_entry_point(10, path_to_entry_point)
resp.past_measurements.extend(_convert_to_energy_responses(past_runs))

# add current run to database
current_entry = [path_to_entry_point] + components_joules
current_entry.append(self._batch_size)
self._energy_table_interface.add_entry(current_entry)
return resp

def habitat_compute_threshold(self, runnable, context):
Expand Down Expand Up @@ -602,5 +603,8 @@ def _convert_to_energy_responses(entries: list)-> List[pm.EnergyResponse]:

energy_response.total_consumption = gpu_component.consumption_joules+cpu_component.consumption_joules
energy_response.components.extend([cpu_component, gpu_component])

energy_response.batch_size = entry[3]
energy_response_list.append(energy_response)

return energy_response_list
15 changes: 8 additions & 7 deletions skyline/db/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
DB_PATH = os.path.join(BASE_DIR, "deepview.sqlite3")


class DatabaseInterface:
def __init__(self, database_name=DB_PATH) -> None:
self.connection = sqlite3.connect(database_name, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
Expand All @@ -16,6 +15,7 @@ def create_energy_table(self) -> None:
entry_point TEXT, \
cpu_component REAL, \
gpu_component REAL, \
batch_size INT, \
ts TIMESTAMP \
);")

Expand All @@ -31,17 +31,18 @@ def is_valid_entry(entry: list) -> bool:
and the types match the columns. Note that timestamp is not part of the entry.
Returns True if it is valid, else False
'''
return len(entry) == 3 and type(entry[0]) == str and type(entry[1]) == float \
and type(entry[2]) == float
return len(entry) == 4 and type(entry[0]) == str and type(entry[1]) == float \
and type(entry[2]) == float and type(entry[3]) == int

@staticmethod
def is_valid_entry_with_timestamp(entry: list) -> bool:
'''
Validates an entry in the Energy table by testing if the length is 4,
and the types match the columns. Returns True if it is valid, else False
'''
return len(entry) == 4 and type(entry[0]) == str and type(entry[1]) == float \
and type(entry[2]) == float and type(entry[3]) == datetime.datetime
return len(entry) == 5 and type(entry[0]) == str and type(entry[1]) == float \
and type(entry[2]) == float and type(entry[3]) == int \
and type(entry[4]) == datetime.datetime

def add_entry(self, entry: list) -> bool:
'''
Expand All @@ -53,14 +54,14 @@ def add_entry(self, entry: list) -> bool:
try:
entry.append(datetime.datetime.now())
cursor = self.database_connection.cursor()
cursor.execute("INSERT INTO ENERGY VALUES(?, ?, ?, ?)", entry)
cursor.execute("INSERT INTO ENERGY VALUES(?, ?, ?, ?, ?)", entry)
self.database_connection.commit()
return True
except sqlite3.IntegrityError as e:
print(e)
return False
else:
return True
return False

def get_latest_n_entries_of_entry_point(self, n: int, entry_point: str) -> list:
'''
Expand Down
Loading