#!/usr/bin/python3 import subprocess import os import sys import math import time from gen_manifest import generate_manifest from gen_enclave_config import generate_config from logs_to_csv import parse_output_logs from core_allocator import core_allocation ############################################################################### # CONFIGS TO SET: # NUM_DIAGNOSTIC_EPOCHS = 4 ############################################################################### def epoch_time_estimate(n, m, t, b): # Base epoch time is 5 sec etime_base = 5 clients_per_server = math.ceil(n/m) # Using 8 sec for 2^20 clients in route_compute time as the base for calculations below etime_route_compute = 0.8 * math.ceil(clients_per_server/100000) etime_precompute = 1 * math.ceil(clients_per_server/100000) # Costs for Waksman network precompute # ID channels needs 6 WN, token channel needs 3 WNs etime_precompute *=5 # Client time: # Takes about 30 sec for handling 2^20 clients etime_client = 3 * math.ceil(clients_per_server/50000) if m==2 or m==3: etime_client += 60 etime = etime_base + etime_precompute + etime_route_compute + etime_client return int(etime) def run_exp(LOG_FOLDER, TOKEN_CHANNEL, NUM_EPOCHS, N, M, T, B, TOKEN_OUT, TOKEN_IN, ID_OUT, ID_IN): if not os.path.exists(LOG_FOLDER): os.mkdir(LOG_FOLDER) if TOKEN_CHANNEL: LOG_FOLDER = LOG_FOLDER + "Token/" else: LOG_FOLDER = LOG_FOLDER + "ID/" if not os.path.exists(LOG_FOLDER): os.mkdir(LOG_FOLDER) #DIAGNOSTIC_FOLDER = LOG_FOLDER + "diagnostic/" #if not os.path.exists(DIAGNOSTIC_FOLDER): # os.mkdir(DIAGNOSTIC_FOLDER) for t in T: b = B for m in M: for n in N: #for run in ["diagnostic", "experiment"]: for run in ["experiment"]: (servers_allocation, client_allocation) = \ core_allocation(m,t) if servers_allocation is None or \ client_allocation is None: print(""" *** *** Not enough physical cores available to run *** M = %d servers with T = %d cores each, plus *** at least one core for clients. *** *** Consider setting the env var OVERLOAD_CORES=1 *** (which will severely impact the performance) *** or run experiments of reduced size. *** """ % (m,t)) continue num_WN_to_precompute = 0 if TOKEN_CHANNEL: num_WN_to_precompute = 2 * 3 else: num_WN_to_precompute = 2 * 6 # Make the correct output folder for diagnostic/experiment experiment_name = str(n) + "_" + str(m) + "_" + str(t) + "_" + str(b) + "/" if run == "diagnostic": log_subfolder = DIAGNOSTIC_FOLDER elif run == "experiment": log_subfolder = LOG_FOLDER log_subfolder = log_subfolder + experiment_name if not os.path.exists(log_subfolder): os.mkdir(log_subfolder) if run == "diagnostic": print("\n\n Running %s diagnostic t = %d, m = %d, n = %d \n\n" % ("token channel" if TOKEN_CHANNEL else "ID channel", t, m, n)) # Manifest generated by diagnostic can be reused by the actual experiment generate_manifest(n, m, t, b, TOKEN_CHANNEL, TOKEN_OUT, TOKEN_IN, ID_OUT, ID_IN) generate_config(n, m, t, b, TOKEN_CHANNEL, TOKEN_OUT, TOKEN_IN, ID_OUT, ID_IN, num_WN_to_precompute) epoch_param = epoch_time_estimate(n, m, t, b) elif run == "experiment": #print("Waiting for 2 mins to reset sockets") #time.sleep(120) #num_sizes, pwn_max, epoch_max, scm_max = parse_output_logs(DIAGNOSTIC_FOLDER, experiment_name) #print("From logs_to_csv: num_sizes = %d, pwn_max = %f, epoch_max = %f, scm_max = %f" #% (num_sizes, pwn_max, epoch_max, scm_max)) print("\n\n Running %s experiment t = %d, m = %d, n = %d \n\n" % ("token channel" if TOKEN_CHANNEL else "ID channel", t, m, n)) #num_WN_to_precompute = math.ceil((num_sizes * pwn_max)/epoch_max) #print("num_WN_to_precompute = %d" %(num_WN_to_precompute)) #if num_WN_to_precompute < 2 * num_sizes: # num_WN_to_precompute = 2 * num_sizes #print("num_WN_to_precompute (pushed up to min 2 sets) = %d" %(num_WN_to_precompute)) #epoch_param = math.ceil(epoch_max + 10 * m * scm_max) generate_manifest(n, m, t, b, TOKEN_CHANNEL, TOKEN_OUT, TOKEN_IN, ID_OUT, ID_IN) epoch_param = epoch_time_estimate(n, m, t, b) generate_config(n, m, t, b, TOKEN_CHANNEL, TOKEN_OUT, TOKEN_IN, ID_OUT, ID_IN, num_WN_to_precompute) # Either estimate from epoch_time_estimate for diagnostic # or the one we got from diagnostic run epoch_wait_time = math.ceil(epoch_param) print("Epoch_wait_time = %d" % epoch_wait_time) # Since launch is invoked from App/ we add a ../ to subfolder before # passing it to slaunch log_subfolder = "../" + log_subfolder slaunch = [] slaunch.append("./launch") slaunch.append("route_clients") slaunch.append("-l") slaunch.append(log_subfolder) slaunch.append("-n") nodes_to_include = ["-n"] for i in range(1, m+1): nodes_to_include.append("s"+str(i)) slaunch.append("s"+str(i)) slaunch.append("-d") slaunch.append(str(epoch_wait_time)) slaunch.append("-e") if run == "experiment": slaunch.append(str(NUM_EPOCHS)) else: slaunch.append(str(NUM_DIAGNOSTIC_EPOCHS)) if run == "experiment": slaunch.append("-w") slaunch.append(str(num_WN_to_precompute)) os.chdir("./App") # Server outputs are captured by log files provided to each of the server # launch calls made by App/launch make = subprocess.call(["make", "-C", "..", "-j"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) try: os.mkdir("keys") except: # It's OK if it already exists pass pubkeys = subprocess.call(["./getpubkeys"]) server_process = subprocess.run(slaunch) claunch = [] claunch.append("./clientlaunch") claunch.append("-t") claunch.append(str(len(client_allocation))) claunch.append("-l") claunch.append(log_subfolder+"clients.log") claunch.append("-T") claunch.append(",".join(map(str, client_allocation))) os.chdir("./../Client/") client_process = subprocess.call(claunch) os.chdir("./../")