Skip to content
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test/**/*gt/*
test/**/*generated/*
**/__pycache__
/Dockerfile*
env.bash
Expand Down
3 changes: 2 additions & 1 deletion src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class GameTime(object):
"""Contains methods and variables that allow a user to import
GameTime as a module.
"""

@staticmethod
def analyze(project_config: ProjectConfiguration) -> Analyzer:
"""
Expand All @@ -25,4 +26,4 @@ def analyze(project_config: ProjectConfiguration) -> Analyzer:
return gametime_analyzer
except GameTimeError as e:
logger.error(str(e))
raise e
raise e
3 changes: 2 additions & 1 deletion src/analyze_project.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python


def main():
"""Main function invoked when this script is run."""


if __name__ == "__main__":
main()
main()
324 changes: 205 additions & 119 deletions src/analyzer.py

Large diffs are not rendered by default.

59 changes: 41 additions & 18 deletions src/backend/arm_backend/arm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from defaults import logger
from gametime_error import GameTimeError


class ArmBackend(Backend):
timing_func = """
static inline unsigned long long read_cycle_count() {
Expand All @@ -18,12 +19,14 @@ class ArmBackend(Backend):
unsigned long long nanoTime = time.tv_sec * 1000000000L + time.tv_nsec;
return nanoTime;
}
"""
"""

def __init__(self, project_config: ProjectConfiguration):
super(ArmBackend, self).__init__(project_config, "Arm")

def generate_executable(self, filepath: str, func_name: str, inputs: str, measure_folder: str) -> str:
def generate_executable(
self, filepath: str, func_name: str, inputs: str, measure_folder: str
) -> str:
"""
Modifies the input program to use INPUTS and generates the executable code. Stored at MEASURE_FOLDER/driver

Expand All @@ -38,14 +41,30 @@ def generate_executable(self, filepath: str, func_name: str, inputs: str, measur
The folder to store generated executable.

Returns:
str:
str:
Path to the executable code.
"""
exec_file = generate_executable(filepath, measure_folder, func_name, inputs, self.timing_func)
modified_bitcode_file_path = clang_helper.compile_to_llvm_for_exec(exec_file, measure_folder, "modified_output", self.project_config.included, self.project_config.compile_flags)
return clang_helper.bc_to_executable(modified_bitcode_file_path, measure_folder, "driver", self.project_config.included, self.project_config.compile_flags)

def run_backend_and_parse_output(self, stored_folder: str, executable_path: str) -> int:
exec_file = generate_executable(
filepath, measure_folder, func_name, inputs, self.timing_func
)
modified_bitcode_file_path = clang_helper.compile_to_llvm_for_exec(
exec_file,
measure_folder,
"modified_output",
self.project_config.included,
self.project_config.compile_flags,
)
return clang_helper.bc_to_executable(
modified_bitcode_file_path,
measure_folder,
"driver",
self.project_config.included,
self.project_config.compile_flags,
)

def run_backend_and_parse_output(
self, stored_folder: str, executable_path: str
) -> int:
"""
Runs the executable in EXECUTABLE_PATH in host machine and extracts the outputs from program.
Temperaries are stored in STORED_FOLDER.
Expand All @@ -65,21 +84,21 @@ def run_backend_and_parse_output(self, stored_folder: str, executable_path: str)

out_file_path = os.path.join(stored_folder, "measure.out")
while not os.path.exists(out_file_path):
print('Waiting for measure.out file')
print("Waiting for measure.out file")
time.sleep(5)

out_filepath = os.path.join(stored_folder, "measure.out")
while not os.path.exists(out_filepath):
print('Waiting for measure.out file')
print("Waiting for measure.out file")
time.sleep(5)

with open(out_filepath, "r") as out_file:
lines = out_file.readlines()

last_line = lines[-1] if lines else ''

match = re.search(r'\d+$', last_line)

last_line = lines[-1] if lines else ""

match = re.search(r"\d+$", last_line)

if match:
extracted_integer = int(match.group())
return extracted_integer
Expand All @@ -103,11 +122,15 @@ def measure(self, inputs: str, measure_folder: str) -> int:
stored_folder: str = measure_folder
filepath: str = self.project_config.location_orig_file
func_name: str = self.project_config.func
executable_path: str = self.generate_executable(filepath, func_name, inputs, measure_folder)
executable_path: str = self.generate_executable(
filepath, func_name, inputs, measure_folder
)
cycle_count: int = -1
try:
cycle_count: int = self.run_backend_and_parse_output(stored_folder, executable_path)
cycle_count: int = self.run_backend_and_parse_output(
stored_folder, executable_path
)
except EnvironmentError as e:
err_msg: str = ("Error in measuring the cycle count of a path in Arm: %s" % e)
err_msg: str = "Error in measuring the cycle count of a path in Arm: %s" % e
logger.info(err_msg)
return cycle_count
return cycle_count
7 changes: 4 additions & 3 deletions src/backend/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
from project_configuration import ProjectConfiguration
from typing import List

"""See the LICENSE file, located in the root directory of
the source distribution and
at http://verifun.eecs.berkeley.edu/gametime/about/LICENSE,
Expand All @@ -19,7 +20,7 @@ class Backend(object):
that is being analyzed.
"""

def __init__(self, project_config: ProjectConfiguration, name: str=""):
def __init__(self, project_config: ProjectConfiguration, name: str = ""):
"""
Parameters:
project_config: ProjectConfiguration:
Expand All @@ -32,7 +33,7 @@ def __init__(self, project_config: ProjectConfiguration, name: str=""):

#: GameTime project configuration for the code that is being analyzed.
self.project_config: ProjectConfiguration = project_config

def measure(self, inputs: str, measure_folder: str) -> int:
"""
Perform measurement using the backend.
Expand All @@ -47,4 +48,4 @@ def measure(self, inputs: str, measure_folder: str) -> int:
int:
The measured value of path
"""
return 0
return 0
42 changes: 24 additions & 18 deletions src/backend/flexpret_backend/flexpret_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
from gametime_error import GameTimeError
import command_utils


class FlexpretBackend(Backend):

timing_func = """
static inline unsigned long read_cycle_count() {
return rdcycle();
Expand All @@ -22,7 +23,9 @@ class FlexpretBackend(Backend):
def __init__(self, project_config: ProjectConfiguration):
super(FlexpretBackend, self).__init__(project_config, "Flexpret")

def generate_executable_c(self, filepath: str, func_name: str, inputs: str, measure_folder: str) -> str:
def generate_executable_c(
self, filepath: str, func_name: str, inputs: str, measure_folder: str
) -> str:
"""
Modifies the input program to use INPUTS and returns path to modifed C program.

Expand All @@ -40,11 +43,12 @@ def generate_executable_c(self, filepath: str, func_name: str, inputs: str, meas
str:
Path to the modified C file.
"""
exec_file = generate_executable(filepath, measure_folder, func_name, inputs, self.timing_func, True)
exec_file = generate_executable(
filepath, measure_folder, func_name, inputs, self.timing_func, True
)
return exec_file


def compile_c_file (self, stored_folder: str, file_name: str) -> str:
def compile_c_file(self, stored_folder: str, file_name: str) -> str:
"""Use same Make file mechanism as Flexpret to generate .mem file from .c

Parameters:
Expand All @@ -57,7 +61,7 @@ def compile_c_file (self, stored_folder: str, file_name: str) -> str:
int:
Measured cycle count for C_FILEPATH.
"""

# Generate CMakeList.txt
cmakelist_path = os.path.join(stored_folder, "CMakeLists.txt")
cmakelist_content = f"""
Expand Down Expand Up @@ -87,10 +91,10 @@ def compile_c_file (self, stored_folder: str, file_name: str) -> str:

fp_add_outputs({file_name})
"""
with open(cmakelist_path, 'w', encoding='utf-8') as f:

with open(cmakelist_path, "w", encoding="utf-8") as f:
f.write(cmakelist_content)

# Run cmake
cwd = os.getcwd()
os.chdir(stored_folder)
Expand All @@ -113,7 +117,7 @@ def run_backend_and_parse_output(self, file_name: str, build_folder: str) -> int
Folder to put all the generated tempraries.
mem_filepath: str :
Path to the .mem file
:return the measurement value
:return the measurement value

Returns:
int:
Expand All @@ -127,17 +131,17 @@ def run_backend_and_parse_output(self, file_name: str, build_folder: str) -> int

out_filepath = os.path.join(build_folder, "measure.out")
while not os.path.exists(out_filepath):
print('Waiting for measure.out file to be generated by FlexPRET')
print("Waiting for measure.out file to be generated by FlexPRET")
time.sleep(5)

with open(out_filepath, "r") as out_file:
lines = out_file.readlines()

#flexpret console output has two extra lines at the end
print_line = lines[0].split(" ")[-1] if lines else ''

match = re.search(r'\d+$', print_line)

# flexpret console output has two extra lines at the end
print_line = lines[0].split(" ")[-1] if lines else ""

match = re.search(r"\d+$", print_line)

if match:
extracted_integer = int(match.group())
return extracted_integer
Expand All @@ -162,7 +166,9 @@ def measure(self, inputs: str, measure_folder: str) -> int:
stored_folder: str = measure_folder
filepath: str = self.project_config.location_orig_file
func_name: str = self.project_config.func
c_filepath: str = self.generate_executable_c(filepath, func_name, inputs, measure_folder)
c_filepath: str = self.generate_executable_c(
filepath, func_name, inputs, measure_folder
)
build_folder: str = self.compile_c_file(stored_folder, file_name)
cycle_count: int = self.run_backend_and_parse_output(file_name, build_folder)
return cycle_count
return cycle_count
Loading
Loading