Browse Source

Experiment scripts

Sajin 1 year ago
parent
commit
dc8c4239c6
3 changed files with 269 additions and 0 deletions
  1. 71 0
      gen_enclave_config.py
  2. 83 0
      gen_manifest.py
  3. 115 0
      run_experiments.py

+ 71 - 0
gen_enclave_config.py

@@ -0,0 +1,71 @@
+#!/usr/bin/python3
+
+import math
+import sys
+
+###############################################################################
+
+# CONFIGS TO SET:
+
+CONFIG_FILE = "Enclave/Enclave.config.xml"
+
+###############################################################################
+
+'''
+  Generate a manifest file with:
+    N: number of clients
+    M: number of servers
+    T: number of threads for each server
+    B: msg_size
+'''
+def generate_config(N, M, T, B):
+
+    cf = open(CONFIG_FILE, 'w+')
+    clients_per_server = math.ceil(N/M)
+
+    # Base heap of 2 MB per thread
+    heap_size = 2000000 * T
+    # Note: This assumes priv_out = 1 , i.e. only 1 token per client in an epoch
+    # Storage and Ingestion data stored per_client = 52 bytes
+    heap_size += clients_per_server * (B + 60)
+    # 4 Buffers of clients_per_server items of B size each
+    heap_size += (clients_per_server * B * 5)
+    # 3 x WN
+    heap_size += (3 * T * (clients_per_server * math.ceil(math.log(clients_per_server,2)) * 8))
+    # 60 MB
+    #heap_size += 60000000
+    heap_size_page_aligned = math.ceil(heap_size/4096) * 4096
+    hex_heap_size = hex(heap_size_page_aligned)
+
+    enclave_config = '''<!-- Please refer to User's Guide for the explanation of each field -->
+<EnclaveConfiguration>
+  <ProdID>0</ProdID>
+  <ISVSVN>0</ISVSVN>
+  <StackMaxSize>0x40000</StackMaxSize>
+  <HeapMaxSize>{H}</HeapMaxSize>
+  <TCSNum>32</TCSNum>
+  <TCSPolicy>1</TCSPolicy>
+  <DisableDebug>0</DisableDebug>
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
+    '''.format(H = str(hex_heap_size))
+
+    #print (enclave_config)
+    cf.write(enclave_config)
+
+    cf.close()
+
+if __name__ == "__main__":
+
+    if(len(sys.argv)!=5):
+        print("Incorrect usage!\n")
+        print("./gen_enclave_config.py expects 4 parameters.")
+        print("Usage: ./gen_enclave_config.py <N = number of clients> <M = number of servers> <T = number of threads> <B = message_size>")
+        exit()
+
+    n = int(sys.argv[1])
+    m = int(sys.argv[2])
+    t = int(sys.argv[3])
+    b = int(sys.argv[4])
+    generate_config(n, m, t, b)

+ 83 - 0
gen_manifest.py

@@ -0,0 +1,83 @@
+#!/usr/bin/python3
+
+import subprocess
+import os
+import sys
+import math
+
+# CONFIGS TO SET:
+
+MANIFEST_FILE = "App/manifest.yaml"
+
+'''
+  Generate a manifest file with:
+    N: number of clients
+    M: number of servers
+    T: number of threads for each server
+    B: msg_size
+'''
+def generate_manifest(N, M, T, B):
+
+    mf = open(MANIFEST_FILE, 'w+')
+    manifest_params = '''params:
+  # The total max number of users
+  user_count: {N}
+  # The size of a message in bytes
+  msg_size: {B}
+  # The number of private messages each user can send per epoch
+  priv_out: 1
+  # The number of private messages each user can receive per epoch
+  priv_in: 1
+  # The number of public messages each user can send per epoch
+  pub_out: 2
+  # The number of public messages each user can receive per epoch
+  pub_in: 2
+  # A hardcoded master secret for generating keys to bootstrap
+  # client -> server communications
+  master_secret: \"AHardCodedAESKey\"\n'''.format(N = str(N), B = str(B))
+
+    # print (manifest_params)
+    mf.write(manifest_params)
+
+    server_params = '''\ns{i}:
+  sprvfile: keys/priv.seal.s{i}
+  pubfile: keys/pub.s{i}
+  weight: 1
+  listen: 127.0.0.{i}:12500
+  clisten: 127.0.0.{i}:13000
+  slisten: 127.0.0.{i}:13001
+  launchprefix: numactl {nstring}
+  args: -t {T}
+  roles: 7\n'''
+
+    # Assign server threads starting at 0
+    numa_base = 0
+    # Do not assign servers threads that are across the processors
+    numa_limit = 36
+    numa_start = numa_base
+
+    for s in range(1, M+1):
+        numa_end = numa_start + T -1
+        if(numa_start < numa_limit and numa_end > numa_limit):
+            numa_start = 40
+            numa_end = numa_start + T
+        numa_string = "-C{s}-{e}".format(s = str(numa_start), e = str(numa_end))
+        numa_start = numa_end + 1
+        curr_params = server_params.format(i = str(s), nstring = numa_string, T = str(T))
+        # print(curr_params)
+        mf.write(curr_params)
+
+
+    mf.close()
+
+if __name__ == "__main__":
+
+    if(len(sys.argv)!=5):
+        print("Incorrect usage!\n Expects 4 parameters. n,m,t,b")
+        exit()
+
+    n = int(sys.argv[1])
+    m = int(sys.argv[2])
+    t = int(sys.argv[3])
+    b = int(sys.argv[4])
+    generate_manifest(n, m, t, b)

+ 115 - 0
run_experiments.py

@@ -0,0 +1,115 @@
+#!/usr/bin/python3
+
+'''
+  NOTE: This script is tailored for sizzle!
+  Hence it does server thread allocation assuming 2 40-core processors.
+  Currently assumes 8 threads (C72-79)  are set aside for client simulator
+
+  Run generate manifest with the maximum number of servers you are going to use
+  and generate the keys for this before running experiments
+  (Run ./App/getpubkeys to generate keys for the servers)
+'''
+
+import subprocess
+import os
+import sys
+import math
+from gen_manifest import generate_manifest
+from gen_enclave_config import generate_config
+
+###############################################################################
+
+# CONFIGS TO SET:
+
+MANIFEST_FILE = "App/manifest.yaml"
+#MANIFESTS_FOLDER = "Manifests/"
+LOG_FOLDER = "Experiments_Plot/"
+RESULT_FOLDER = "Experiment_results/"
+
+
+# N = number of clients
+N = [1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21]
+# M = number of servers
+M = [3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24, 26, 28, 32, 36, 40, 48, 56, 64, 72]
+# T = threads per server instance
+T = [2, 4, 8, 16]
+# Max servers depending on number of threads
+M_MAX = {
+    1:72, # 24 in M
+    2:36, # 19 in M
+    4:18, # 13 in M
+    8:9,  # 8 in M
+    16:4  # 4 in M
+}
+# B = msg_size (-u)
+B = 256
+
+###############################################################################
+
+def epoch_time(n, m, t, b):
+    # Base epoch time is 5 sec
+    etime_base = 5
+    clients_per_server = math.ceil(n/m)
+    # Using 1 sec for ~50K clients in compute time
+    etime_compute = math.ceil(clients_per_server/50000)
+    etime_inc = math.ceil(clients_per_server/25000)
+    etime_client = ((math.ceil(2/t))**2) * etime_inc
+    etime = etime_base + etime_compute + etime_client
+    return etime
+
+if __name__ == "__main__":
+
+    if not os.path.exists(LOG_FOLDER):
+        os.mkdir(LOG_FOLDER)
+
+    for t in T:
+        b = B
+        m_start = 1
+        # Set M_MAX depending on t
+        m_end = M_MAX[t]
+        for m in M:
+            if(m < m_end):
+                for n in N:
+                    print("\n\n Running Experiment t = %d, m = %d, n = %d \n\n" % (t, m, n))
+                    generate_manifest(n, m, t, b)
+                    generate_config(n, m, t, b)
+                    epoch_interval = epoch_time(n, m, t, b)
+                    print("Epoch_interval = %d" % epoch_interval)
+
+                    log_subfolder = str(n) + "_" + str(m) + "_" + str(t) + "_" + str(b) + "/"
+                    log_subfolder = LOG_FOLDER + log_subfolder
+                    if not os.path.exists(log_subfolder):
+                        os.mkdir(log_subfolder)
+                    # 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("-e")
+                    slaunch.append(str(epoch_interval))
+
+                    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)
+                    server_process = subprocess.run(slaunch)
+
+                    claunch = []
+                    claunch.append("./clientlaunch")
+                    claunch.append("-t")
+                    claunch.append("8")
+                    claunch.append("-l")
+                    claunch.append(log_subfolder+"clients.log")
+                    os.chdir("./../Client/")
+                    client_process = subprocess.call(claunch)
+
+                    os.chdir("./../")