def write(file_path, json_data): """Writes JSON to file. Args: file_path (str): JSON file to write to. json_data (json): JSON data to write. """ try: file.write(file_path, json.dumps(json_data, sort_keys=True, indent=4)) except IOError as err: logging.error(err)
def disable_hugepages(): """Disables transparent hugepages.""" transparent_hugepage = "/sys/kernel/mm/transparent_hugepage/enabled" try: if os.path.isfile(transparent_hugepage): file.write(transparent_hugepage, "never") return True return False except IOError as err: logging.debug(err)
def write(lock_file): """Write the persistant SPET run number. Args: lock_file (str): The path to the .lock file. """ try: run_num = 1 if os.path.isfile(lock_file): current_value = file.read(lock_file) if current_value: run_num = int(current_value) + 1 file.write(lock_file, str(run_num)) except IOError as err: logging.error(err)
def prerun(): """Clear up system resources before running a benchmark.""" try: cleared = False if shutil.which("sync"): execute.output("sudo sync") cleared = True drop_caches = "/proc/sys/vm/drop_caches" if os.path.isfile(drop_caches): file.write(drop_caches, "3") cleared = True return cleared except ValueError as err: logging.debug(err) except IOError as err: logging.debug(err)
def run(self): """Run MLC three times. Returns: If success: A dict containing (unit, run1, run2, run3, average, median). unit (str): Latency units. run1 (list): Latency for each NUMA node of the first run. run2 (list): Latency for each NUMA node of the second run. run3 (list): Latency for each NUMA node of the third run. average (list): Average for each NUMA node of run1, run2, and run3. median (list): Median for each NUMA node of run1, run2, and run3. If error: A dict containing (error). error (str): Error message. """ bin_loc = self.mlc_dir + "/Linux/mlc_avx512" cmd = "modprobe msr; {} --latency_matrix".format(bin_loc) results = {"unit": "ns"} if not os.path.isfile(bin_loc): text = 'Cannot run MLC because "{}" could not be found.'.format( bin_loc) prettify.error_message(text) return {"error": text} os.makedirs(self.results_dir, exist_ok=True) self.commands.append("Run: " + cmd) output = execute.output(cmd, self.mlc_dir) file.write(self.results_dir + "/mlc_output.txt", output) found_lines = grep.text(output, r"^\s*0") if found_lines: node_latencies = found_lines[0].strip().split() node_latencies.pop(0) # Remove leading '0' for first node for index, latency in enumerate(node_latencies): node_latencies[index] = float(latency) results["latencies"] = node_latencies logging.info("MLC results: %s", str(results)) return results
def performance_governor(): """Sets the CPU scaling governor to performance.""" cpu_root = "/sys/devices/system/cpu/" try: if not os.path.isdir(cpu_root): return False pattern = r"cpu[0-9]" for cpu in next(os.walk(cpu_root))[1]: if not re.match(pattern, cpu): continue governor = cpu_root + cpu + "/cpufreq/scaling_governor" if os.path.isfile(governor): file.write(governor, "performance") return True except IOError as err: logging.debug(err)
def nofiles(): """Sets the number of files limit.""" limits_conf = "/etc/security/limits.conf" sysctl_conf = "/etc/sysctl.conf" try: if os.path.isfile(limits_conf): lines = grep.file(limits_conf, "nofile 1048576") if not lines: file.write(limits_conf, "* - nofile 1048576", append=True) if os.path.isfile(sysctl_conf): lines = grep.file(sysctl_conf, "fs.file-max = 1048576") if not lines: file.write(sysctl_conf, "fs.file-max = 1048576", append=True) if shutil.which("sysctl"): execute.output("sudo sysctl -p") return True except ValueError as err: logging.debug(err) except IOError as err: logging.debug(err)
def run(self, threads): """Run OpenSSL three times. Args: threads (int): The total number of threads on the system. Returns: If success, a dict containing (unit, run1, run2, run3, average, median). unit (str): Score units. run1 (list): A list of (encrypt, decrypt). encrypt (float): The encryption score for the first run. decrypt (float): The decryption score for the first run. run2 (list): A list of (encrypt, decrypt). encrypt (float): The encryption score for the second run. decrypt (float): The decryption score for the second run. run3 (list): A list of (encrypt, decrypt). encrypt (float): The encryption score for the third run. decrypt (float): The decryption score for the third run. average (list): A list of (encrypt, decrypt). encrypt (float): The encryption average of run1, run2, and run3. decrypt (float): The decryption average of run1, run2, and run3. median (list): A list of (encrypt, decrypt). encrypt (float): The encryption median of run1, run2, and run3. decrypt (float): The decryption median of run1, run2, and run3. Else, a dict containing (error). error (str): Error message. """ taskset_ids = self.__taskset_ids(threads) multi_num = self.__multi_num(threads, taskset_ids) bin_loc = self.openssl_dir + "/apps/openssl" results = { "aes-128-gcm": { "unit": "B/s", "score_size": 8192, "score_size_unit": "B", "test_bit_size": 128, "test": "AES-GCM", }, "aes-256-gcm": { "unit": "B/s", "score_size": 8192, "score_size_unit": "B", "test_bit_size": 256, "test": "AES-GCM", }, } shell_env = os.environ.copy() if "LD_LIBRARY_PATH" in shell_env: shell_env["LD_LIBRARY_PATH"] = "{}:{}".format( shell_env["LD_LIBRARY_PATH"], self.openssl_dir) else: shell_env["LD_LIBRARY_PATH"] = self.openssl_dir if not os.path.isfile(bin_loc): text = 'Could not find OpenSSL binaries at "{}".'.format(bin_loc) prettify.error_message(text) return {"error": text} logging.info( "Running OpenSSL on ids %s using a total of %d threads.", taskset_ids, multi_num, ) os.makedirs(self.results_dir, exist_ok=True) for test in results: encrypt_results = [] decrypt_results = [] cmd_base = "taskset -c {} {} speed -multi {} -evp {}".format( taskset_ids, bin_loc, multi_num, test) cmd_decrypt = cmd_base + " -decrypt" self.commands.append("Run: " + cmd_base) self.commands.append("Run: " + cmd_decrypt) for count in range(1, 4): run_num = "run" + str(count) encrypt_result_file = "{}/openssl_{}_encrypt_{}.txt".format( self.results_dir, test, run_num) decrypt_result_file = "{}/openssl_{}_decrypt_{}.txt".format( self.results_dir, test, run_num) cmd_decrypt = cmd_base + " -decrypt" logging.debug("Encrypt command: %s", cmd_base) logging.debug("LD_LIBRARY_PATH: %s", shell_env["LD_LIBRARY_PATH"]) optimize.prerun() time.sleep(10) encrypt_output = execute.output(cmd_base, environment=shell_env) file.write(encrypt_result_file, encrypt_output) logging.debug("Decrypt command: %s", cmd_base) logging.debug("LD_LIBRARY_PATH: %s", shell_env["LD_LIBRARY_PATH"]) optimize.prerun() time.sleep(10) decrypt_output = execute.output(cmd_decrypt, environment=shell_env) file.write(decrypt_result_file, decrypt_output) encrypt_scores = encrypt_output.rstrip().split("\n") decrypt_scores = decrypt_output.rstrip().split("\n") if not encrypt_scores: continue if not decrypt_scores: continue encrypt_score = encrypt_scores[-1].split()[6] decrypt_score = decrypt_scores[-1].split()[6] if "k" in encrypt_score: encrypt_score = re.sub(r"[^0-9.]", "", encrypt_score) if "k" in decrypt_score: decrypt_score = re.sub(r"[^0-9.]", "", decrypt_score) # The 'numbers' are in 1000s of bytes per second processed. encrypt_score = float(encrypt_score) * 1000.0 decrypt_score = float(decrypt_score) * 1000.0 encrypt_results.append(encrypt_score) decrypt_results.append(decrypt_score) results[test][run_num] = {} results[test][run_num]["encrypt"] = encrypt_score results[test][run_num]["decrypt"] = decrypt_score if encrypt_results and decrypt_results: results[test]["average"] = {} results[test]["average"]["encrypt"] = statistics.mean( encrypt_results) results[test]["average"]["decrypt"] = statistics.mean( decrypt_results) results[test]["median"] = {} results[test]["median"]["encrypt"] = statistics.median( encrypt_results) results[test]["median"]["decrypt"] = statistics.median( decrypt_results) results[test]["variance"] = {} results[test]["variance"]["encrypt"] = statistics.variance( encrypt_results) results[test]["variance"]["decrypt"] = statistics.variance( decrypt_results) results[test]["range"] = {} sorted_encrypt = sorted(encrypt_results) results[test]["range"]["encrypt"] = (sorted_encrypt[-1] - sorted_encrypt[0]) sorted_decrypt = sorted(decrypt_results) results[test]["range"]["decrypt"] = (sorted_decrypt[-1] - sorted_decrypt[0]) logging.info("OpenSSL results: %s", str(results)) return results
def run(self, cores=None, cflags=None): """Run three timed Linux kernel compilations. Args: cores (int, optional): The number of cores on the system. Returns: If success, a dict containing (unit, run1, run2, run3, average, median). unit (str): Score units. run1 (float): Score for the first run. run2 (float): Score for the second run. run3 (float): Score for the third run. average (float): Average of run1, run2, and run3. median (float): Median of run1, run2, and run3. Else, a dict containing (error). error (str): Error message. """ if cores is None: cores = 1 if cflags is None: cflags = "-march=native -mtune=native" if "-O" not in cflags: cflags += " -O3 " shell_env = os.environ.copy() shell_env["CFLAGS"] = cflags results = {"unit": "s"} config_loc = self.kernel_dir + "/.config" tmp_results = [] if not os.path.isfile(config_loc): text = ('Cannot run timed Linux kernel because "{}" could not ' "be found.".format(config_loc)) prettify.error_message(text) return {"error": text} logging.info( "Running timed Linux kernel compilation using %d Make " "thread.", cores) os.makedirs(self.results_dir, exist_ok=True) clean_cmd = "make -s -j {} clean".format(cores) build_cmd = "make -s -j {}".format(cores) self.commands.append("Run: CFLAGS = " + cflags) self.commands.append("Prerun: " + clean_cmd) self.commands.append("Run: " + build_cmd) for count in range(1, 4): run_num = "run" + str(count) result_file = "{}/zlib_{}.txt".format(self.results_dir, run_num) execute.output(clean_cmd, self.kernel_dir, environment=shell_env) optimize.prerun() time.sleep(10) compile_speed = execute.timed(build_cmd, working_dir=self.kernel_dir, environment=shell_env) if (not os.path.isfile(self.kernel_dir + "/vmlinux") or compile_speed is None): return {"error": "Linux Kernel failed to compile."} file.write( result_file, "{}\nLinux Kernel Compilation Speed: {}\n".format( build_cmd, compile_speed), ) results[run_num] = float(compile_speed) tmp_results.append(compile_speed) if tmp_results: results["average"] = statistics.mean(tmp_results) results["median"] = statistics.median(tmp_results) results["variance"] = statistics.variance(tmp_results) sorted_results = sorted(tmp_results) results["range"] = sorted_results[-1] - sorted_results[0] logging.info("Timed Linux kernel compilation results:\n%s", str(results)) return results
def run(self, threads): """Run YCSB with MySQL three times. Args: threads (int): The number of threads on the system. """ shell_env = os.environ.copy() maven_dir = self.src_dir + "/maven" error = False results = {"unit": {"throughput": "ops/sec", "latency": "us"}} if os.path.isdir(maven_dir): shell_env["M2_HOME"] = maven_dir shell_env["M2"] = maven_dir + "/bin" else: return {"error": "Maven not found."} mysql_dir = self.src_dir + "/mysql" mysql_data = mysql_dir + "/mysql-files" if not os.path.exists(mysql_data + "/ycsb"): text = 'Unable to find "ycsb" table in MySQL.' prettify.error_message(text) return {"error": text} os.makedirs(self.results_dir, exist_ok=True) # Start MySQL service subprocess.Popen( "{0}/bin/mysqld_safe --user=root --basedir={0} --datadir={1} " "--plugin-dir={0}/lib/plugin --pid-file=/tmp/mysql.pid " "--log-error=ycsb.err &".format(mysql_dir, mysql_data), cwd=mysql_dir, shell=True, env=shell_env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) time.sleep(20) read_latency_results = [] update_latency_results = [] throughput_results = [] run_cmd = ("./bin/ycsb run jdbc -s -P workloads/workloada -p " "db.driver=com.mysql.jdbc.Driver -p " "db.url=jdbc:mysql://localhost:3306/ycsb?useSSL=false -p " 'db.user=root -p db.passwd="" -threads {} -p ' "operationcount=1000000".format(threads)) self.commands.append("Run: " + run_cmd) for count in range(1, 4): run_num = "run" + str(count) result_file = "{}/ycsb-sql_{}.txt".format(self.results_dir, run_num) optimize.prerun() time.sleep(10) # Run YCSB output = execute.output(run_cmd, working_dir=self.ycsb_dir, environment=shell_env) file.write(result_file, output) if "UPDATE-FAILED" in output or "READ-FAILED" in output: error = True break throughput_line = grep.text(output, r"\[OVERALL\], Throughput\(ops/sec\),") if throughput_line: throughput = float(throughput_line[-1].split(",")[2].strip()) throughput_results.append(throughput) readlat_line = grep.text(output, r"\[READ\], 95thPercentileLatency\(us\),") if readlat_line: readlat = float(readlat_line[-1].split(",")[2].strip()) read_latency_results.append(readlat) updatelat_line = grep.text( output, r"\[UPDATE\], 95thPercentileLatency\(us\),") if updatelat_line: updatelat = float(updatelat_line[-1].split(",")[2].strip()) update_latency_results.append(updatelat) if throughput_line and readlat_line and updatelat_line: results[run_num] = { "throughput": throughput, "read_latency": readlat, "update_latency": updatelat, } # Stop MySQL service if os.path.exists("/tmp/mysql.pid"): pid = file.read("/tmp/mysql.pid").strip() execute.kill(pid) execute.kill(pid) execute.kill(pid) if error: return {"error": "YCSB failed to update and/or read database."} if "run1" in results: results["average"] = {} results["median"] = {} results["variance"] = {} results["range"] = {} results["average"]["throughput"] = statistics.mean( throughput_results) results["median"]["throughput"] = statistics.median( throughput_results) results["variance"]["throughput"] = statistics.variance( throughput_results) sorted_throughput = sorted(throughput_results) results["range"]["throughput"] = (sorted_throughput[-1] - sorted_throughput[0]) results["average"]["read_latency"] = statistics.mean( read_latency_results) results["median"]["read_latency"] = statistics.median( read_latency_results) results["variance"]["read_latency"] = statistics.variance( read_latency_results) sorted_read_latency = sorted(read_latency_results) results["range"]["read_latency"] = (sorted_read_latency[-1] - sorted_read_latency[0]) results["average"]["update_latency"] = statistics.mean( update_latency_results) results["median"]["update_latency"] = statistics.median( update_latency_results) results["variance"]["update_latency"] = statistics.variance( update_latency_results) sorted_update_latency = sorted(update_latency_results) results["range"]["update_latency"] = (sorted_update_latency[-1] - sorted_update_latency[0]) logging.info("YCSB MySQL results: %s", str(results)) return results
def run(self, threads): """Run YCSB with Cassandra three times. Args: threads (int): The number of threads on the system. """ pid = None shell_env = os.environ.copy() maven_dir = self.src_dir + "/maven" error = False results = {"unit": {"throughput": "ops/sec", "latency": "us"}} if os.path.isdir(maven_dir): shell_env["M2_HOME"] = maven_dir shell_env["M2"] = maven_dir + "/bin" else: prettify.error_message("Maven could not be found.") return False cassandra_dir = self.src_dir + "/cassandra" if not os.path.exists(cassandra_dir + "/data/data/ycsb"): text = 'Unable to find "ycsb" table in Cassandra.' prettify.error_message(text) return {"error": text} read_latency_results = [] update_latency_results = [] throughput_results = [] os.makedirs(self.results_dir, exist_ok=True) # Start Cassandra service subprocess.Popen( "./bin/cassandra -R -p /tmp/cassandra.pid &", shell=True, cwd=cassandra_dir, env=shell_env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) time.sleep(20) if os.path.isfile("/tmp/cassandra.pid"): pid = file.read("/tmp/cassandra.pid").strip() if not pid or not os.path.dirname("/proc/" + pid): text = "Cassandra failed to start." prettify.error_message(text) return {"error": text} run_cmd = ("./bin/ycsb run cassandra-cql -s -P workloads/workloada " '-p hosts="localhost" -threads {} ' "-p operationcount=10000000".format(threads)) self.commands.append("Run: " + run_cmd) for count in range(1, 4): run_num = "run" + str(count) result_file = "{}/ycsb-nosql_{}.txt".format(self.results_dir, run_num) optimize.prerun() time.sleep(10) output = execute.output(run_cmd, working_dir=self.ycsb_dir, environment=shell_env) file.write(result_file, output) if "UPDATE-FAILED" in output or "READ-FAILED" in output: error = True break throughput_line = grep.text(output, r"\[OVERALL\], Throughput\(ops/sec\),") if throughput_line: throughput = float(throughput_line[-1].split(",")[2].strip()) throughput_results.append(throughput) readlat_line = grep.text(output, r"\[READ\], 95thPercentileLatency\(us\),") if readlat_line: readlat = float(readlat_line[-1].split(",")[2].strip()) read_latency_results.append(readlat) updatelat_line = grep.text( output, r"\[UPDATE\], 95thPercentileLatency\(us\),") if updatelat_line: updatelat = float(updatelat_line[-1].split(",")[2].strip()) update_latency_results.append(updatelat) if throughput_line and readlat_line and updatelat_line: results[run_num] = { "throughput": throughput, "read_latency": readlat, "update_latency": updatelat, } # Stop Cassandra service if pid: execute.kill(pid) execute.kill(pid) execute.kill(pid) if error: return {"error": "YCSB failed to update and/or read database."} if "run1" in results: results["average"] = {} results["median"] = {} results["variance"] = {} results["range"] = {} results["average"]["throughput"] = statistics.mean( throughput_results) results["median"]["throughput"] = statistics.median( throughput_results) results["variance"]["throughput"] = statistics.variance( throughput_results) sorted_throughput = sorted(throughput_results) results["range"]["throughput"] = (sorted_throughput[-1] - sorted_throughput[0]) results["average"]["read_latency"] = statistics.mean( read_latency_results) results["median"]["read_latency"] = statistics.median( read_latency_results) results["variance"]["read_latency"] = statistics.variance( read_latency_results) sorted_read_latency = sorted(read_latency_results) results["range"]["read_latency"] = (sorted_read_latency[-1] - sorted_read_latency[0]) results["average"]["update_latency"] = statistics.mean( update_latency_results) results["median"]["update_latency"] = statistics.median( update_latency_results) results["variance"]["update_latency"] = statistics.variance( update_latency_results) sorted_update_latency = sorted(update_latency_results) results["range"]["update_latency"] = (sorted_update_latency[-1] - sorted_update_latency[0]) logging.info("YCSB Cassandra results: %s", str(results)) return results
def run(self, threads): """Run GCC compiled STREAM three times. Args: threads (int): The total number of threads on the system. Returns: If success, a dict containing (unit, run1, run2, run3, average, median). unit (str): Score units. run1 (float): Score for the first run. run2 (float): Score for the second run. run3 (float): Score for the third run. average (float): Average of run1, run2, and run3. median (float): Median of run1, run2, and run3. Else, a dict containing (error). error (str): Error message. """ stream_bin = self.stream_dir + "/stream" shell_env = os.environ.copy() shell_env["OMP_NUM_THREADS"] = str(threads) mpi_root = self.src_dir + "/openmpi/build" mpi_path = mpi_root + "/bin" mpi_lib = mpi_root + "/lib" shell_env["PATH"] += ":" + mpi_path if "LD_LIBRARY_PATH" in shell_env: shell_env["LD_LIBRARY_PATH"] += mpi_lib else: shell_env["LD_LIBRARY_PATH"] = mpi_lib results = {"unit": "MB/s"} shell_env["OMP_PROC_BIND"] = "true" if not os.path.isfile(stream_bin): text = 'Cannot run STREAM because "{}" could not be found.'.format( stream_bin) prettify.error_message(text) return {"error": text} logging.info("Running STREAM with %d OMP threads.", threads) os.makedirs(self.results_dir, exist_ok=True) tmp_results = [] cmd = "./stream" self.commands.append("Run: OMP_NUM_THREADS = " + str(threads)) self.commands.append("Run: OMP_PROC_BIND = true") self.commands.append("Run: " + cmd) for count in range(1, 4): run_num = "run" + str(count) result_file = "{}/stream_{}.txt".format(self.results_dir, run_num) optimize.prerun() time.sleep(10) output = execute.output(cmd, working_dir=self.stream_dir, environment=shell_env) file.write(result_file, output) result = grep.text(output, "Triad") result = result[0].split()[1] # 2nd word result = float(result) results[run_num] = result tmp_results.append(result) results["average"] = statistics.mean(tmp_results) results["median"] = statistics.median(tmp_results) results["variance"] = statistics.variance(tmp_results) sorted_results = sorted(tmp_results) results["range"] = sorted_results[-1] - sorted_results[0] logging.info("STREAM results: %s", str(results)) return results
def run(self): """Run zlib compression (level 6) and decompression three times. Returns: If success, a dict containing (unit, run1, run2, run3, average, median). unit (str): Score units. run1 (list): A list of (compress, decompress). compress (float): The compression score for the first run. decompress (float): The decompression score for the first run. run2 (list): A list of (compress, decompress). compress (float): The compression score for the second run. decompress (float): The decompression score for the second run. run3 (list): A list of (compress, decompress). compress (float): The compression score for the third run. decompress (float): The decompression score for the third run. average (list): A list of (compress, decompress). compress (float): The compression average of run1, run2, and run3. decompress (float): The decompression average of run1, run2, and run3. median (list): A list of (compress, decompress). compress (float): The compression median of run1, run2, and run3. decompress (float): The decompression median of run1, run2, and run3. Else, a dict containing (error). error (str): Error message. """ bin32_loc = self.zlib_dir + "/minigzip" bin64_loc = self.zlib_dir + "/minigzip64" level = 6 corpus_file = self.corpus_dir + "/corpus.txt" corpus_archive = corpus_file + ".zlib" results = {"unit": "s"} compress_times = [] decompress_times = [] if not os.path.isfile(bin32_loc) or not os.path.isfile(bin64_loc): text = ('Cannot run zlib because neither "{}" or "{}" could not be' " found.".format(bin32_loc, bin64_loc)) prettify.error_message(text) return {"error": text} if not os.path.isfile(corpus_file): self.create_corpus() logging.info("Running zlib.") used_bin = bin64_loc if not os.path.isfile(bin64_loc): used_bin = bin32_loc os.makedirs(self.results_dir, exist_ok=True) compress_warmup = "{} -1 < {} > /dev/null".format(used_bin, corpus_file) compress_cmd = "{} -{} < {} > {}".format(used_bin, level, corpus_file, corpus_archive) decompress_warmup = "{} -d < {} > /dev/null".format( used_bin, corpus_archive) decompress_cmd = "{} -d < {} > /dev/null".format( used_bin, corpus_archive) self.commands.append("Run - Warmup: " + compress_warmup) self.commands.append("Run: " + compress_cmd) self.commands.append("Run - Warmup: " + decompress_warmup) self.commands.append("Run: " + decompress_cmd) for count in range(1, 4): run_num = "run" + str(count) result_file = "{}/zlib_{}.txt".format(self.results_dir, run_num) optimize.prerun() time.sleep(10) # warm up execute.output(compress_warmup, self.corpus_dir) compress_time = execute.timed(compress_cmd, self.corpus_dir) optimize.prerun() time.sleep(10) # warm up execute.output(decompress_warmup, self.corpus_dir) decompress_time = execute.timed(decompress_cmd, self.corpus_dir) file.write( result_file, "Compress Time (Level {}): {}\n" "Decompress Time: {}\n".format(level, compress_time, decompress_time), ) compress_times.append(compress_time) decompress_times.append(decompress_time) results[run_num] = {} results[run_num]["compress"] = compress_time results[run_num]["decompress"] = decompress_time os.remove(corpus_archive) results["average"] = {} results["average"]["compress"] = statistics.mean(compress_times) results["average"]["decompress"] = statistics.mean(decompress_times) results["median"] = {} results["median"]["compress"] = statistics.median(compress_times) results["median"]["decompress"] = statistics.median(decompress_times) results["variance"] = {} results["variance"]["compress"] = statistics.variance(compress_times) results["variance"]["decompress"] = statistics.variance( decompress_times) results["range"] = {} sorted_compress_times = sorted(compress_times) sorted_decompress_times = sorted(decompress_times) results["range"]["compress"] = (sorted_compress_times[-1] - sorted_compress_times[0]) results["range"]["decompress"] = (sorted_decompress_times[-1] - sorted_decompress_times[0]) logging.info("zlib results: %s", str(results)) return results
def run(self, l1_cache, l2_cache, l3_cache, arch=None, threads=None): """Run High-Performance Linpack three times. Args: l1_cache (int): The L1-Cache size in B for the system. l2_cache (int): The L2-Cache size in B for the system. l3_cache (int): The L3-Cache size in B for the system. arch (str, optional): The architecture type of the system. threads (int): The number of threads on the system. Returns: If success, a dict containing (unit, run1, run2, run3, average, median). unit (str): Latency units. level1 (float): Latency for L1-Cache. level2 (float): Latency for L2-Cache. level3 (float): Latency for L3-Cache. Else, a dict containing (error). error (str): Error message. """ if arch is None: arch = "x86_64" if threads is None: threads = 1 thread = 0 stride = 1024 max_cache = 512 bin_loc = "{}/bin/{}-linux-gnu/lat_mem_rd".format( self.lmbench_dir, arch) results = {"unit": "ns"} if not os.path.isfile(bin_loc): text = 'Could not find LMbench binaries at "{}".'.format(bin_loc) prettify.error_message(text) logging.error(text) return {"error": text} logging.info( "Running LMbench using %d L1-Cache, %d L2-Cache, " '%d L3-Cache, and "%s" arch.', l1_cache, l2_cache, l3_cache, arch, ) os.makedirs(self.results_dir, exist_ok=True) if threads >= 3: thread = 2 run_command = "taskset -c {} {} {} {}".format(thread, bin_loc, max_cache, stride) self.commands.append("Run: " + run_command) result_file = self.results_dir + "/lmbench_output.txt" output = execute.output(run_command) file.write(result_file, output) l1_latency = self.__closest_cache_latency( float(l1_cache) / 1024.0 / 1024.0, output) if l2_cache: l2_latency = self.__closest_cache_latency( float(l2_cache) / 1024.0 / 1024.0, output) if l3_cache: l3_latency = self.__closest_cache_latency( float(l3_cache) / 1024.0 / 1024.0, output) if l1_latency: results["level1"] = float(l1_latency) if l2_latency: results["level2"] = float(l2_latency) if l3_latency: results["level3"] = float(l3_latency) logging.info("LMbench results: %s", str(results)) return results
def run(self, cores=None, cflags=None): """Runs Docker containers to compile the Linux kernel. Returns: If success, a dict containing (unit, times, average, median, variance, range). unit (str): Score units. times (list): All compile times for the kernel. average (float): Average of the times. median (float): Median of the times. variance (float): Variance of the times. range (float): Range of the times. Else, a dict containing (error). error (str): Error message. """ if cores is None: cores = 1 if cflags is None: cflags = "-march=native -mtune=native" if "-O" not in cflags: cflags += " -O3 " shell_env = os.environ.copy() shell_env["CFLAGS"] = cflags shell_env["PATH"] = self.docker_dir + ":" + shell_env["PATH"] pid_file = "/tmp/docker.pid" build_name = "compile_kernel" result_file = self.results_dir + "/times.txt" results = {"unit": "s"} times = [] procs = [] os.makedirs(self.results_dir, exist_ok=True) shutil.copyfile(self.docker_dir + "/Dockerfile", self.results_dir + "/Dockerfile") if not os.path.isfile(self.docker_dir + "/dockerd"): message = "Cannot build. Docker directory not found." prettify.error_message(message) return {"error": message} # Start Docker daemon subprocess.Popen( "{}/dockerd --pidfile {} --data-root {} &".format( self.docker_dir, pid_file, self.data_dir), cwd=self.docker_dir, shell=True, env=shell_env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) logging.info("Docker daemon is running.") time.sleep(20) if not self.__image_built(build_name, env=shell_env): if os.path.exists(pid_file): pid = file.read(pid_file).strip() execute.kill(pid) message = "Cannot build. Docker image not found." prettify.error_message(message) return {"error": message} logging.info("Docker is about to run.") # Remove all previously ran containers try: containers = execute.output( "{}/docker ps -a -q".format(self.docker_dir), working_dir=self.docker_dir, environment=shell_env, ) if containers: execute.output( "{0}/docker rm $({0}/docker ps -a -q)".format( self.docker_dir), working_dir=self.docker_dir, environment=shell_env, ) except subprocess.SubprocessError as err: logging.debug(err) optimize.prerun() time.sleep(10) for count in range(0, 100): test_name = build_name + "_test{}".format(count) # Note: We avoid using `-i -t` because it causes TTY issues # with SSH connections. run_command = ("{}/docker run --ulimit nofile=1048576:1048576 " '-e "cores={}" -e "cflags={}" --name {} {}'.format( self.docker_dir, cores, cflags, test_name, build_name)) if count == 0: self.commands.append("Run: " + run_command) proc = subprocess.Popen( run_command, shell=True, cwd=self.docker_dir, env=shell_env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, ) procs.append(proc) for proc in procs: stdout = proc.communicate()[0] if isinstance(stdout, bytes): stdout = stdout.decode() stdout = stdout.strip() try: stdout = float(stdout) file.write(result_file, "{}\n".format(stdout), append=True) times.append(stdout) except ValueError: logging.debug("Container failed to finish.") logging.debug(stdout) # Remove all previously ran containers try: containers = execute.output( "{}/docker ps -a -q".format(self.docker_dir), working_dir=self.docker_dir, environment=shell_env, ) if containers: execute.output( "{0}/docker stop $({0}/docker ps -a -q)".format( self.docker_dir), working_dir=self.docker_dir, environment=shell_env, ) execute.output( "{0}/docker rm $({0}/docker ps -a -q)".format( self.docker_dir), working_dir=self.docker_dir, environment=shell_env, ) except subprocess.SubprocessError as err: logging.debug(err) # Stop Docker daemon if os.path.exists(pid_file): logging.info("Docker daemon is turning off.") pid = file.read(pid_file).strip() execute.kill(pid) execute.kill(pid) time.sleep(5) if times: results["times"] = times results["median"] = statistics.median(times) results["average"] = statistics.mean(times) results["variance"] = statistics.variance(times) sorted_times = sorted(times) results["range"] = sorted_times[-1] - sorted_times[0] else: results["error"] = "No container times available." return results
def run(self, mpi_threads, threads, arch=None): """Run High-Performance Linpack three times. Args: mpi_threads (int): The number of MPI threads used by LINPACK. This number is usually the number of physical cores on the system. threads (int): The total number of logical threads on the system. arch (str, optional): The architecture type of the system. Returns: If success, a dict containing (unit, run1, run2, run3, average, median). unit (str): Score units. run1 (float): Score for the first run. run2 (float): Score for the second run. run3 (float): Score for the third run. average (float): Average of run1, run2, and run3. median (float): Median of run1, run2, and run3. Else, a dict containing (error). error (str): Error message. """ if arch is None: arch = "x86_64" shell_env = os.environ.copy() openmpi_dir = "{}/openmpi/build/bin".format(self.src_dir) bin_dir = "{}/bin/{}".format(self.hpl_dir, arch) bin_loc = bin_dir + "/xhpl" results = {"unit": "GFLOPS", "mathlib": self.mathlib} tmp_results = [] if not os.path.isfile(bin_loc): text = 'Could not find HPL binaries at "{}".'.format(bin_loc) prettify.error_message(text) logging.error(text) return {"error": text} if not os.path.isdir(openmpi_dir): text = 'Could not find OpenMPI directory at "{}".'.format( openmpi_dir) prettify.error_message(text) logging.error(text) return {"error": text} grid = self.__grid(mpi_threads) nb_size = self.__nb_size(threads) mpi_cmd = "{}/mpirun -n {} --allow-run-as-root --mca mpi_paffinity_alone 1".format( openmpi_dir, mpi_threads) if threads == mpi_threads: mpi_cmd = "{}/mpirun -n {} --allow-run-as-root".format( openmpi_dir, mpi_threads) logging.info('Running LINPACK using "%s" arch.', arch) os.makedirs(self.results_dir, exist_ok=True) shutil.copyfile(self.hpl_dir + "/Make." + arch, self.results_dir) shutil.copyfile(self.hpl_dir + "/bin/{}/HPL.dat".format(arch), self.results_dir) cmd = mpi_cmd + " ./xhpl" self.commands.append("Run: " + cmd) optimize.prerun() time.sleep(10) output = execute.output(cmd, working_dir=bin_dir, environment=shell_env) file.write(self.results_dir + "/linpack_output.txt", output) result = grep.text( output, r"\s+{}\s+{}\s+{}\s+".format(nb_size, grid.P, grid.Q)) for line in result: # 7th word tmp = float(line.split()[6]) tmp_results.append(tmp) if tmp_results: sorted_results = sorted(tmp_results) results["score"] = sorted_results[-1] logging.info("LINPACK results: %s", str(results)) return results