run_experiments.py 7.5 KB

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