2022-05-31 12:37:00 +02:00
#!/usr/bin/env python3
2024-06-21 08:50:36 +02:00
''' starbench is an application that is able to measure the execution time of a user software suite in various conditions (different build modes and different execution modes)
'''
2022-06-02 13:01:16 +02:00
import argparse
2022-05-31 12:37:00 +02:00
import threading
import subprocess
import os
2022-06-07 12:44:25 +02:00
import sys
2024-06-21 08:50:36 +02:00
from typing import List , Dict , Optional , Tuple , Callable
2022-05-31 12:37:00 +02:00
from datetime import datetime
from pathlib import Path
2022-05-31 16:50:38 +02:00
from abc import ABC , abstractmethod
2022-06-07 12:44:25 +02:00
# from typing import ForwardRef
try :
2024-06-21 08:50:36 +02:00
from typing import ForwardRef # type: ignore pylint: disable=ungrouped-imports
2022-06-07 12:44:25 +02:00
except ImportError :
# python 3.6
from typing import _ForwardRef as ForwardRef
assert sys . version_info > = ( 3 , 5 , 0 ) , ' this code requires at least python 3.5 ' # type hints in arguments
2022-05-31 12:37:00 +02:00
2024-06-21 08:50:36 +02:00
class StarBenchException ( Exception ) :
''' base exception for user errors detected by starbench '''
2022-05-31 12:37:00 +02:00
2024-06-21 08:50:36 +02:00
RunId = int # identifier of a run
WorkerId = int # identifier of a worker (a run is performed on a worker)
DurationInSeconds = float
ProcessId = int
ReturnCode = int
class Run ( ) :
""" represents a run of a run of the benchmarked command within its CommandPerfEstimator
"""
id : RunId # uniquely identifies a run within its CommandPerfEstimator instance
worker_id : WorkerId # the worker used for this run (number of workers = number of parallel runs)
pid : Optional [ ProcessId ] # the process identifier of the process used by the command
start_time : datetime # the time at which the command process has started
return_code : ReturnCode # the exit code of the command process
end_time : Optional [ datetime ] # the time at which the command process has ended. None if the process is still running
def __init__ ( self , run_id : RunId , worker_id : WorkerId ) :
2022-05-31 12:37:00 +02:00
self . id = run_id
2024-06-21 08:50:36 +02:00
self . worker_id = worker_id
2022-05-31 12:37:00 +02:00
self . pid = None
self . return_code = 0
self . start_time = datetime . now ( )
self . end_time = None
2024-06-21 08:50:36 +02:00
def has_finished ( self ) - > bool :
""" indicates if this run has finished """
2022-05-31 12:37:00 +02:00
return self . end_time is not None
2024-06-21 08:50:36 +02:00
def get_duration ( self ) - > DurationInSeconds :
""" returns the duration of this run, provided it has finished
"""
2022-05-31 12:37:00 +02:00
assert self . has_finished ( )
return ( self . end_time - self . start_time ) . total_seconds ( )
2024-06-21 08:50:36 +02:00
CommandPerfEstimator = ForwardRef ( ' CommandPerfEstimator ' )
2022-05-31 16:50:38 +02:00
class IStarBencherStopCondition ( ABC ) :
2024-06-21 08:50:36 +02:00
""" abstract handler that decides if the given CommandPerfEstimator has enough runs to estimate the performance or should trigger new runs
2022-05-31 16:50:38 +02:00
2024-06-21 08:50:36 +02:00
"""
2022-05-31 16:50:38 +02:00
@abstractmethod
2024-06-21 08:50:36 +02:00
def should_stop ( self , star_bencher : CommandPerfEstimator ) - > bool :
""" decides if the given CommandPerfEstimator instance should trigger new runs
This method is called at the end of each run , to decide if another run should be triggered or not .
"""
2022-05-31 16:50:38 +02:00
class StopAfterSingleRun ( IStarBencherStopCondition ) :
2024-06-21 08:50:36 +02:00
""" a stop condition that causes the given CommandPerfEstimator to never start new runs
2022-05-31 16:50:38 +02:00
2024-06-21 08:50:36 +02:00
as a result , this causes the given CommandPerfEstimator to just use one single run of the command to estimate its performance .
"""
2022-05-31 16:50:38 +02:00
def __init__ ( self ) :
pass
2024-06-21 08:50:36 +02:00
def should_stop ( self , star_bencher : CommandPerfEstimator ) :
2022-05-31 16:50:38 +02:00
# never start a new run
return True
class StopWhenConverged ( IStarBencherStopCondition ) :
2024-06-21 08:50:36 +02:00
""" a stop condition that triggers when the just completed run doesn ' t have much effect on the average run ' s duration
"""
2022-05-31 16:50:38 +02:00
def __init__ ( self , max_error : float = 0.01 ) :
self . max_error = max_error
self . _last_mean_duration = None
2024-06-21 08:50:36 +02:00
def should_stop ( self , star_bencher : CommandPerfEstimator ) - > bool :
2022-05-31 16:50:38 +02:00
do_stop = False
2024-06-21 08:50:36 +02:00
mean_duration , _num_runs = star_bencher . get_run_mean_duration ( )
print ( f ' mean_duration = { mean_duration } ' )
2022-05-31 16:50:38 +02:00
if self . _last_mean_duration is not None :
diff = abs ( mean_duration - self . _last_mean_duration )
2024-06-21 08:50:36 +02:00
print ( f ' diff = { diff } ' )
2022-05-31 16:50:38 +02:00
if diff < self . max_error :
do_stop = True
self . _last_mean_duration = mean_duration
return do_stop
2024-06-21 08:50:36 +02:00
class CommandPerfEstimator ( ) : # (false positive) pylint: disable=function-redefined
''' a command runner that runs a given command multiple times and measures the average execution duration
the ' star ' term comes from hpl ' s stadgemm benchmark, where we launch `n` independent programs on `n` cores
2022-05-31 12:37:00 +02:00
'''
2024-06-21 08:50:36 +02:00
run_command : List [ str ] # the command that this instance of CommandPerfEstimator is expected to run (eg: ['ctest', '--output-on-failure', '-L', '^arch4_quick$']). The command supports the following tags:
run_command_cwd : Path # the current directory to use when executing run_command
stdout_filepath : Path # the path of the file that records the standard output of run_command
stderr_filepath : Path # the path of the file that records the standard error of run_command
num_cores_per_run : int # the max number of threads used by each run
num_parallel_runs : int # how many times run_command is run simultaneously
max_num_cores : int # the maximum allowed number of cores for this CommandPerfEstimator
stop_condition : IStarBencherStopCondition # the condition that is used so that this CommandPerfEstimator can decide to stop launching commands
stop_on_error : bool
_next_run_id : int
_runs : Dict [ int , Run ]
_last_mean_duration : Optional [ DurationInSeconds ]
_num_runs : int
_runs_lock : threading . Lock
_finished_event : threading . Event
2022-05-31 12:37:00 +02:00
2022-05-31 18:55:16 +02:00
def __init__ ( self , run_command : List [ str ] , num_cores_per_run : int , num_parallel_runs : int , max_num_cores : int , stop_condition : IStarBencherStopCondition , stop_on_error = True , run_command_cwd : Path = None , stdout_filepath : Path = None , stderr_filepath : Path = None ) :
2022-05-31 12:37:00 +02:00
assert num_cores_per_run * num_parallel_runs < = max_num_cores
2024-06-21 08:50:36 +02:00
self . run_command = run_command
2022-05-31 12:37:00 +02:00
self . run_command_cwd = run_command_cwd
2022-05-31 18:55:16 +02:00
self . stdout_filepath = stdout_filepath
self . stderr_filepath = stderr_filepath
2022-05-31 12:37:00 +02:00
self . num_cores_per_run = num_cores_per_run
self . num_parallel_runs = num_parallel_runs
2024-06-21 08:50:36 +02:00
self . max_num_cores = max_num_cores
self . stop_condition = stop_condition
2022-05-31 12:37:00 +02:00
self . stop_on_error = stop_on_error
2024-06-21 08:50:36 +02:00
self . _next_run_id = 0
self . _runs = { }
2022-05-31 12:37:00 +02:00
self . _last_mean_duration = None
self . _num_runs = 0
self . _runs_lock = threading . Lock ( )
self . _finished_event = threading . Event ( )
2024-06-21 08:50:36 +02:00
def popen_and_call ( self , popen_args : List [ str ] , on_exit : Callable [ [ ProcessId , ReturnCode , RunId ] , None ] , run_id : RunId , cwd : Path , stdout_filepath : Path = None , stderr_filepath : Path = None ) :
2022-05-31 12:37:00 +02:00
"""
Runs the given args in a subprocess . Popen , and then calls the function
on_exit when the subprocess completes .
on_exit is a callable object , and popen_args is a list / tuple of args that
would give to subprocess . Popen .
"""
2024-06-21 08:50:36 +02:00
def run_in_thread ( popen_args : List [ str ] , on_exit : Callable [ [ ProcessId , ReturnCode , RunId ] , None ] ) :
2022-05-31 18:55:16 +02:00
stdout = None
stderr = None
if stdout_filepath is not None :
2024-06-21 08:50:36 +02:00
stdout = open ( stdout_filepath , ' w ' , encoding = ' utf8 ' )
2022-05-31 18:55:16 +02:00
if stderr_filepath is not None :
2024-06-21 08:50:36 +02:00
stderr = open ( stderr_filepath , ' w ' , encoding = ' utf8 ' )
2022-06-01 12:06:58 +02:00
env = os . environ . copy ( )
# restrict the number of threads used by openmp
2024-06-21 08:50:36 +02:00
env [ ' OMP_NUM_THREADS ' ] = f ' { self . num_cores_per_run } '
2022-06-01 12:06:58 +02:00
# restrict the nu,ber of threads used by intel math kernel library
2024-06-21 08:50:36 +02:00
env [ ' MKL_NUM_THREADS ' ] = f ' { self . num_cores_per_run } '
2022-06-01 12:06:58 +02:00
proc = subprocess . Popen ( popen_args , cwd = cwd , stdout = stdout , stderr = stderr , env = env )
2022-05-31 12:37:00 +02:00
proc . wait ( )
2022-05-31 18:55:16 +02:00
if stderr is not None :
stderr . close ( )
if stdout is not None :
stdout . close ( )
2022-05-31 12:37:00 +02:00
on_exit ( proc . pid , proc . returncode , run_id )
return
thread = threading . Thread ( target = run_in_thread , args = ( popen_args , on_exit ) )
thread . start ( )
# returns immediately after the thread starts
return thread
2024-06-21 08:50:36 +02:00
def get_run_mean_duration ( self ) - > Tuple [ DurationInSeconds , int ] :
""" returns the average duration of all completed runs of this CommandPerfEstimator instance
"""
2022-06-07 12:44:25 +02:00
duration_sums = 0.0 # in python3.6+, replace with duration_sums: float = 0.0
num_finished_runs = 0 # in python3.6+, replace with num_finished_runs: int = 0
2022-05-31 12:37:00 +02:00
with self . _runs_lock :
for run in self . _runs . values ( ) :
if run . has_finished ( ) :
num_finished_runs + = 1
duration_sums + = run . get_duration ( )
assert num_finished_runs > 0
return duration_sums / num_finished_runs , num_finished_runs
def _all_runs_have_finished ( self ) :
with self . _runs_lock :
for run in self . _runs . values ( ) :
if not run . has_finished ( ) :
return False
return True
2024-06-21 08:50:36 +02:00
def on_exit ( self , pid : ProcessId , return_code : ReturnCode , run_id : RunId ) :
""" method called when the command executed by a run ends. Unless the stop condition is met, a new run is started.
pid : the process identifier of the process of the run that just finished
return_code : the return code of the process of the run that just finished
run_id : the run that just completed
"""
2022-05-31 12:37:00 +02:00
end_time = datetime . now ( )
# print(self, pid, run_id)
run = self . _runs [ run_id ]
run . pid = pid
run . end_time = end_time
run . return_code = return_code
2022-05-31 17:59:28 +02:00
2022-05-31 12:37:00 +02:00
do_stop = False
if self . stop_on_error and run . return_code != 0 :
do_stop = True
else :
2022-05-31 16:50:38 +02:00
do_stop = self . stop_condition . should_stop ( self )
2022-05-31 12:37:00 +02:00
if not do_stop :
2022-05-31 19:03:00 +02:00
# print('adding a run')
2022-05-31 17:59:28 +02:00
self . _start_run ( run . worker_id ) # reuse the same worker as the run that has just finished
2022-05-31 12:37:00 +02:00
if self . _all_runs_have_finished ( ) :
# tell the main thread that all the runs have finished
self . _finished_event . set ( )
2024-06-21 08:50:36 +02:00
@staticmethod
def _interpret_tags ( tagged_string : str , tags_value : Dict [ str , str ] ) - > str :
untagged_string = tagged_string
for tag_id , tag_value in tags_value . items ( ) :
untagged_string = untagged_string . replace ( tag_id , tag_value )
return untagged_string
def _start_run ( self , worker_id : WorkerId ) :
""" starts a run using the given worker """
tags_value = {
' <worker_id> ' : f ' { worker_id : 03d } '
}
run_command = [ CommandPerfEstimator . _interpret_tags ( s , tags_value ) for s in self . run_command ]
run_command_cwd = CommandPerfEstimator . _interpret_tags ( str ( self . run_command_cwd ) , tags_value )
2022-05-31 18:55:16 +02:00
stdout_filepath = None
if self . stdout_filepath is not None :
2024-06-21 08:50:36 +02:00
stdout_filepath = CommandPerfEstimator . _interpret_tags ( str ( self . stdout_filepath ) , tags_value )
2022-05-31 18:55:16 +02:00
stderr_filepath = None
if self . stderr_filepath is not None :
2024-06-21 08:50:36 +02:00
stderr_filepath = CommandPerfEstimator . _interpret_tags ( str ( self . stderr_filepath ) , tags_value )
2022-05-31 12:37:00 +02:00
with self . _runs_lock :
2022-05-31 17:59:28 +02:00
run = Run ( self . _next_run_id , worker_id )
2022-05-31 12:37:00 +02:00
self . _next_run_id + = 1
2024-06-21 08:50:36 +02:00
_run_thread = self . popen_and_call ( popen_args = run_command , on_exit = self . on_exit , run_id = run . id , cwd = run_command_cwd , stdout_filepath = stdout_filepath , stderr_filepath = stderr_filepath ) # noqa:F841
2022-05-31 12:37:00 +02:00
self . _runs [ run . id ] = run
2024-06-21 08:50:36 +02:00
def run ( self ) - > DurationInSeconds :
''' performs the runs of the command and returns the runs ' average duration '''
print ( f " executing the following command in parallel ( { self . num_parallel_runs } parallel runs) : ' { str ( self . run_command ) } ' " )
2022-05-31 17:59:28 +02:00
for worker_id in range ( self . num_parallel_runs ) :
self . _start_run ( worker_id )
2022-05-31 12:37:00 +02:00
# wait until all runs have finished
self . _finished_event . wait ( )
with self . _runs_lock :
2022-06-07 14:52:56 +02:00
workers_success = [ run . return_code == 0 for run in self . _runs . values ( ) ]
if not all ( workers_success ) :
2024-06-21 08:50:36 +02:00
raise StarBenchException ( f ' at least one run failed (workers_success = { workers_success } ) ' )
mean_duration , num_runs = self . get_run_mean_duration ( )
print ( f ' mean duration : { mean_duration : .3f } s ( { num_runs } runs) ' )
2022-05-31 16:50:38 +02:00
return mean_duration
2022-05-31 12:37:00 +02:00
2024-06-21 08:50:36 +02:00
# def test_starbencher():
# if False:
# stop_condition = StopAfterSingleRun()
# # stop_condition = StopWhenConverged(max_error=0.0001)
# bench = StarBencher(run_command=['sleep', '0.1415927'], num_cores_per_run=1, num_parallel_runs=2, max_num_cores=2, stop_condition=stop_condition)
# mean_duration = bench.run()
# print(mean_duration)
2022-06-02 13:01:16 +02:00
2024-06-21 08:50:36 +02:00
# if False:
# bench = StarBencher(run_command=['ls', '/tmp'], num_cores_per_run=1, num_parallel_runs=2, max_num_cores=2, max_error=0.0001)
# mean_duration = bench.run()
# print(mean_duration)
# pass
2022-06-02 13:01:16 +02:00
# end of starbencher
2022-06-07 14:52:56 +02:00
def starbench_cmake_app ( git_repos_url : str , code_version : str , tmp_dir : Path , num_cores : int , git_user : str , git_password : str , benchmark_command : List [ str ] , cmake_options : List [ str ] = None , cmake_exe_location : Path = None ) :
2022-06-01 16:17:10 +02:00
"""
tests_to_run : regular expression as understood by ctest ' s -L option. eg ' ^ arch4_quick $ '
"""
2022-05-31 12:37:00 +02:00
tmp_dir . mkdir ( exist_ok = True )
2022-06-02 13:01:16 +02:00
git_credentials = [ ]
if git_user :
git_credentials . append ( git_user )
if git_password :
git_credentials . append ( git_password )
if len ( git_credentials ) != 0 :
2024-06-21 08:50:36 +02:00
git_repos_url = git_repos_url . replace ( ' https:// ' , f " https:// { ' : ' . join ( git_credentials ) } @ " )
2022-06-02 15:58:00 +02:00
src_dir = tmp_dir / ' source.git '
# src_dir.mkdir(exist_ok=True)
2024-06-21 08:50:36 +02:00
subprocess . run ( [ ' git ' , ' clone ' , f ' { str ( git_repos_url ) } ' , str ( src_dir ) ] , cwd = str ( tmp_dir ) , check = True )
2022-06-02 14:34:14 +02:00
if code_version :
2024-06-21 08:50:36 +02:00
subprocess . run ( [ ' git ' , ' checkout ' , f ' { code_version } ' ] , cwd = str ( src_dir ) , check = True )
2022-05-31 16:50:38 +02:00
2022-06-02 17:34:16 +02:00
# we need one build for each parallel run, otherwise running ctest on parallel would overwrite the same file, which causes the test to randomly fail depnding on race conditions
2022-06-09 08:58:04 +02:00
worker_dir = tmp_dir / ' worker<worker_id> '
build_dir = worker_dir / ' build '
2024-06-21 08:50:36 +02:00
print ( f ' creating build directory { worker_dir } ' )
create_build_dir = CommandPerfEstimator (
2022-06-02 17:34:16 +02:00
run_command = [ ' mkdir ' , ' -p ' , build_dir ] ,
num_cores_per_run = 1 ,
num_parallel_runs = num_cores ,
max_num_cores = num_cores ,
stop_condition = StopAfterSingleRun ( ) ,
run_command_cwd = Path ( ' /tmp ' ) ,
stdout_filepath = None )
2024-06-21 08:50:36 +02:00
_create_build_dir_duration = create_build_dir . run ( ) # noqa: F841
2022-06-02 17:34:16 +02:00
# build_dir.mkdir(exist_ok=True)
2024-06-21 08:50:36 +02:00
print ( f ' configuring { src_dir } into { build_dir } ... ' )
2022-06-07 14:52:56 +02:00
cmake_prog = ' cmake '
if cmake_exe_location :
cmake_prog = str ( cmake_exe_location )
2024-06-21 08:50:36 +02:00
configure = CommandPerfEstimator (
2022-06-07 14:52:56 +02:00
run_command = [ cmake_prog ] + cmake_options + [ src_dir ] ,
2022-06-02 17:34:16 +02:00
num_cores_per_run = 1 ,
num_parallel_runs = num_cores ,
max_num_cores = num_cores ,
stop_condition = StopAfterSingleRun ( ) ,
run_command_cwd = build_dir ,
2022-06-09 08:58:04 +02:00
stdout_filepath = worker_dir / ' configure_stdout.txt ' ,
stderr_filepath = worker_dir / ' configure_stderr.txt ' )
2024-06-21 08:50:36 +02:00
_configure_duration = configure . run ( ) # noqa: F841
2022-06-02 17:34:16 +02:00
2024-06-21 08:50:36 +02:00
print ( f ' building { build_dir } ... ' )
build = CommandPerfEstimator (
2022-06-02 17:34:16 +02:00
run_command = [ ' make ' ] ,
num_cores_per_run = 1 ,
num_parallel_runs = num_cores ,
max_num_cores = num_cores ,
stop_condition = StopAfterSingleRun ( ) ,
run_command_cwd = build_dir ,
2022-06-09 08:58:04 +02:00
stdout_filepath = worker_dir / ' build_stdout.txt ' ,
stderr_filepath = worker_dir / ' build_stderr.txt ' )
2024-06-21 08:50:36 +02:00
_build_duration = build . run ( ) # noqa: F841
2022-06-02 17:34:16 +02:00
2024-06-21 08:50:36 +02:00
print ( f ' benchmarking { build_dir } ... ' )
2022-06-02 17:34:16 +02:00
stop_condition = StopAfterSingleRun ( )
2024-06-21 08:50:36 +02:00
bench = CommandPerfEstimator (
2022-06-02 17:52:38 +02:00
run_command = benchmark_command ,
2022-06-02 17:34:16 +02:00
num_cores_per_run = 1 ,
num_parallel_runs = num_cores ,
max_num_cores = num_cores ,
stop_condition = stop_condition ,
run_command_cwd = build_dir ,
2022-06-09 08:58:04 +02:00
stdout_filepath = worker_dir / ' bench_stdout.txt ' ,
stderr_filepath = worker_dir / ' bench_stderr.txt ' )
2022-06-02 17:34:16 +02:00
mean_duration = bench . run ( )
2024-06-21 08:50:36 +02:00
print ( f ' duration : { mean_duration : .3f } s ' % ( ) )
2022-05-31 12:37:00 +02:00
2024-06-21 08:50:36 +02:00
def main ( ) :
''' main program '''
2022-05-31 12:37:00 +02:00
2022-06-02 13:01:16 +02:00
example_text = ''' example:
2022-05-31 12:37:00 +02:00
2022-06-07 14:52:56 +02:00
% ( prog ) s - - git - repos - url https : / / github . com / hibridon / hibridon - - code - version a3bed1c3ccfbca572003020d3e3d3b1ff3934fad - - git - user g - raffy - - git - pass - file " $HOME/.github/personal_access_tokens/bench.hibridon.cluster.ipr.univ-rennes1.fr.pat " - - num - cores 2 - - output - dir = / tmp / hibench - - cmake - path = / opt / cmake / cmake - 3.23 .0 / bin / cmake - - cmake - option = - DCMAKE_BUILD_TYPE = Release - - cmake - option = - DBUILD_TESTING = ON - - benchmark - command = ' ctest --output-on-failure -L ^arch4_quick$ '
2022-06-02 13:01:16 +02:00
'''
2022-06-03 14:13:32 +02:00
parser = argparse . ArgumentParser ( description = ' performs a benchmark on a cmake buildable app hosted on a git repository ' , epilog = example_text , formatter_class = argparse . RawDescriptionHelpFormatter )
2022-06-02 14:34:14 +02:00
parser . add_argument ( ' --git-repos-url ' , required = True , help = ' the url of the code to benchmark (eg https://github.com/hibridon/hibridon) ' )
parser . add_argument ( ' --code-version ' , help = ' the version of the code to use; either a branch or a commit id (eg a3bed1c3ccfbca572003020d3e3d3b1ff3934fad) ' )
2022-06-02 13:01:16 +02:00
parser . add_argument ( ' --git-user ' , help = ' the git user to use to clone the code repository ' )
password_group = parser . add_mutually_exclusive_group ( )
password_group . add_argument ( ' --git-pass-file ' , help = ' the path to a file containing the password (or personal access token) ' )
password_group . add_argument ( ' --git-pass ' , type = str , help = ' the password (or personal access token) to use (not recommended for security reasons) ' )
parser . add_argument ( ' --num-cores ' , type = int , required = True , help = ' the number of cores that the benchmark will use ' )
parser . add_argument ( ' --output-dir ' , type = Path , required = True , help = ' where the output files will be placed ' )
2022-06-07 14:52:56 +02:00
parser . add_argument ( ' --cmake-path ' , type = Path , help = ' the path to the cmake executable to use in case a specific cmake is wanted ' )
2022-06-02 15:59:27 +02:00
parser . add_argument ( ' --cmake-option ' , type = str , action = ' append ' , help = ' additional option passed to cmake in the configure step (use this flag multiple times if you need more than one cmake option) ' )
2022-06-02 17:52:38 +02:00
parser . add_argument ( ' --benchmark-command ' , required = True , type = str , help = ' the command to benchmark ' )
2022-06-02 13:01:16 +02:00
args = parser . parse_args ( )
git_user = args . git_user
git_repos_url = args . git_repos_url
git_password = None
if args . git_pass :
git_password = args . git_pass
elif args . git_pass_file :
2024-06-21 08:50:36 +02:00
with open ( args . git_pass_file , ' r ' , encoding = ' utf8 ' ) as f :
2022-06-02 13:01:16 +02:00
git_password = f . readline ( ) . replace ( ' \n ' , ' ' ) # os.environ['HIBRIDON_REPOS_PAT']
2022-06-07 14:52:56 +02:00
starbench_cmake_app ( git_repos_url = git_repos_url , code_version = args . code_version , tmp_dir = args . output_dir , num_cores = args . num_cores , git_user = git_user , git_password = git_password , cmake_options = args . cmake_option , benchmark_command = args . benchmark_command . split ( ' ' ) , cmake_exe_location = args . cmake_path )
2024-06-21 08:50:36 +02:00
if __name__ == ' __main__ ' :
main ( )