run_experiments.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/python3
  2. '''
  3. NOTE: This script is tailored for a machine with 2 40-core processors.
  4. Currently assumes 8 threads (C36-39,76-79) are set aside for client
  5. simulator; change this by setting "prefix" in Client/clientlaunch and
  6. the -t option to clientlaunch below.
  7. Similarly, the use of cores C0-35,40-75 for the TEEMS servers can be
  8. changed in the gen_manifest.py program.
  9. If you have a different number of cores available for servers, also
  10. change M_MAX below.
  11. '''
  12. import subprocess
  13. import os
  14. import sys
  15. import math
  16. import time
  17. from gen_manifest import generate_manifest
  18. from gen_enclave_config import generate_config
  19. from logs_to_csv import parse_output_logs
  20. ###############################################################################
  21. # CONFIGS TO SET:
  22. MANIFEST_FILE = "App/manifest.yaml"
  23. LOG_FOLDER = "190824_Fig8/"
  24. NUM_EPOCHS = 5
  25. PRIVATE_ROUTE = False
  26. PRIV_OUT = 1
  27. PRIV_IN = 1
  28. PUB_OUT = 1
  29. PUB_IN = 1
  30. # N = number of clients
  31. # M = number of servers
  32. # T = threads per server instance
  33. ## A large grid of many combinations
  34. # N = [1<<16, 1<<17, 1<<18, 1<<19, 1<<20]
  35. # M = [72, 64, 48, 36, 32, 24, 16, 8, 4, 2, 1]
  36. # T = [16, 8, 4, 2, 1]
  37. ## Figure 7
  38. #N = [1<<15, 1<<16, 1<<17, 1<<18, 1<<19, 1<<20]
  39. #M = [4]
  40. #T = [4]
  41. ## Figure 8
  42. N = [1<<20]
  43. M = [72, 64, 48, 36, 32, 24, 16, 8, 4, 2, 1]
  44. T = [1]
  45. # Max servers depending on number of threads (assuming 72 available
  46. # cores for servers)
  47. M_MAX = {
  48. 1:72,
  49. 2:36,
  50. 4:18,
  51. 8:9,
  52. 16:4
  53. }
  54. # B = message size (bytes)
  55. B = 256
  56. NUM_DIAGNOSTIC_EPOCHS = 4
  57. ###############################################################################
  58. def epoch_time_estimate(n, m, t, b):
  59. # Base epoch time is 5 sec
  60. etime_base = 5
  61. clients_per_server = math.ceil(n/m)
  62. # Using 8 sec for 2^20 clients in route_compute time as the base for calculations below
  63. etime_route_compute = 0.8 * math.ceil(clients_per_server/100000)
  64. etime_precompute = 1 * math.ceil(clients_per_server/100000)
  65. # Costs for Waksman network precompute
  66. # Public routing needs 7 WN, private routing needs 3 WNs
  67. etime_precompute *=5
  68. # Client time:
  69. # Takes about 30 sec for handling 2^20 clients
  70. etime_client = 3 * math.ceil(clients_per_server/100000)
  71. etime = etime_base + etime_precompute + etime_route_compute + etime_client
  72. return int(etime)
  73. if __name__ == "__main__":
  74. if not os.path.exists(LOG_FOLDER):
  75. os.mkdir(LOG_FOLDER)
  76. DIAGNOSTIC_FOLDER = LOG_FOLDER + "diagnostic/"
  77. if not os.path.exists(DIAGNOSTIC_FOLDER):
  78. os.mkdir(DIAGNOSTIC_FOLDER)
  79. for t in T:
  80. b = B
  81. m_start = 1
  82. # Set M_MAX depending on t
  83. m_end = M_MAX[t]
  84. for m in M:
  85. if(m <= m_end):
  86. for n in N:
  87. #for run in ["diagnostic", "experiment"]:
  88. for run in ["experiment"]:
  89. num_WN_to_precompute = 0
  90. if(PRIVATE_ROUTE):
  91. num_WN_to_precompute = 2 * 3
  92. else:
  93. num_WN_to_precompute = 2 * 8
  94. # Make the correct output folder for diagnostic/experiment
  95. experiment_name = str(n) + "_" + str(m) + "_" + str(t) + "_" + str(b) + "/"
  96. if(run == "diagnostic"):
  97. log_subfolder = DIAGNOSTIC_FOLDER
  98. elif(run == "experiment"):
  99. log_subfolder = LOG_FOLDER
  100. log_subfolder = log_subfolder + experiment_name
  101. if not os.path.exists(log_subfolder):
  102. os.mkdir(log_subfolder)
  103. if(run == "diagnostic"):
  104. print("\n\n Running DIAGNOSTIC t = %d, m = %d, n = %d \n\n" % (t, m, n))
  105. # Manifest generated by diagnostic can be reused by the actual experiment
  106. generate_manifest(n, m, t, b, PRIVATE_ROUTE, PRIV_OUT, PRIV_IN, PUB_OUT, PUB_IN)
  107. generate_config(n, m, t, b, PRIVATE_ROUTE, PRIV_OUT, PRIV_IN, PUB_OUT, PUB_IN, num_WN_to_precompute)
  108. epoch_param = epoch_time_estimate(n, m, t, b)
  109. elif(run == "experiment"):
  110. #print("Waiting for 2 mins to reset sockets")
  111. #time.sleep(120)
  112. #num_sizes, pwn_max, epoch_max, scm_max = parse_output_logs(DIAGNOSTIC_FOLDER, experiment_name)
  113. #print("From logs_to_csv: num_sizes = %d, pwn_max = %f, epoch_max = %f, scm_max = %f"
  114. #% (num_sizes, pwn_max, epoch_max, scm_max))
  115. print("\n\n Running EXPERIMENT t = %d, m = %d, n = %d \n\n" % (t, m, n))
  116. #num_WN_to_precompute = math.ceil((num_sizes * pwn_max)/epoch_max)
  117. #print("num_WN_to_precompute = %d" %(num_WN_to_precompute))
  118. #if(num_WN_to_precompute < 2 * num_sizes):
  119. # num_WN_to_precompute = 2 * num_sizes
  120. #print("num_WN_to_precompute (pushed up to min 2 sets) = %d" %(num_WN_to_precompute))
  121. #epoch_param = math.ceil(epoch_max + 10 * m * scm_max)
  122. generate_manifest(n, m, t, b, PRIVATE_ROUTE, PRIV_OUT, PRIV_IN, PUB_OUT, PUB_IN)
  123. epoch_param = epoch_time_estimate(n, m, t, b)
  124. generate_config(n, m, t, b, PRIVATE_ROUTE, PRIV_IN, PUB_OUT, PUB_IN, num_WN_to_precompute)
  125. # Either estimate from epoch_time_estimate for diagnostic
  126. # or the one we got from diagnostic run
  127. epoch_duration = math.ceil(epoch_param)
  128. print("Epoch_duration = %d" % epoch_duration)
  129. # Since launch is invoked from App/ ; we add a ../ to subfolder before
  130. # passing it to slaunch
  131. log_subfolder = "../" + log_subfolder
  132. slaunch = []
  133. slaunch.append("./launch")
  134. slaunch.append("route_clients")
  135. slaunch.append("-l")
  136. slaunch.append(log_subfolder)
  137. slaunch.append("-n")
  138. nodes_to_include = ["-n"]
  139. for i in range(1, m+1):
  140. nodes_to_include.append("s"+str(i))
  141. slaunch.append("s"+str(i))
  142. slaunch.append("-d")
  143. slaunch.append(str(epoch_duration))
  144. slaunch.append("-e")
  145. if(run == "experiment"):
  146. slaunch.append(str(NUM_EPOCHS))
  147. else:
  148. slaunch.append(str(NUM_DIAGNOSTIC_EPOCHS))
  149. if(run == "experiment"):
  150. slaunch.append("-w")
  151. slaunch.append(str(num_WN_to_precompute))
  152. os.chdir("./App")
  153. # Server outputs are captured by log files provided to each of the server
  154. # launch calls made by App/launch
  155. make = subprocess.call(["make", "-C", "..", "-j"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
  156. try:
  157. os.mkdir("keys")
  158. except:
  159. # It's OK if it already exists
  160. pass
  161. pubkeys = subprocess.call(["./getpubkeys"])
  162. server_process = subprocess.run(slaunch)
  163. claunch = []
  164. claunch.append("./clientlaunch")
  165. claunch.append("-t")
  166. claunch.append("8")
  167. claunch.append("-l")
  168. claunch.append(log_subfolder+"clients.log")
  169. os.chdir("./../Client/")
  170. client_process = subprocess.call(claunch)
  171. os.chdir("./../")