viff

changeset 1268:61ac5debba24

benchmark can be shortcut if needed_data are provided.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Fri, 09 Oct 2009 13:04:18 +0200
parents 8d213ad683c2
children f91b28a6cbbe
files apps/benchmark.py
diffstat 1 files changed, 53 insertions(+), 26 deletions(-) [+]
line diff
     1.1 --- a/apps/benchmark.py	Fri Oct 09 13:04:18 2009 +0200
     1.2 +++ b/apps/benchmark.py	Fri Oct 09 13:04:18 2009 +0200
     1.3 @@ -146,10 +146,15 @@
     1.4                    help="skip local computations using fake field elements")
     1.5  parser.add_option("--args", type="string",
     1.6                    help="additional arguments to the runtime, the format is a comma separated list of id=value pairs e.g. --args s=1,d=0,lambda=1")
     1.7 +parser.add_option("--needed_data", type="string",
     1.8 +                  help="name of a file containing already computed dictionary of needed_data. Useful for skipping generating the needed data, which usually elliminates half the execution time. Format of file: \"{('random_triple', (Zp,)): [(3, 1), (3, 4)]}\"")
     1.9 +parser.add_option("--pc", type="string",
    1.10 +                  help="The program counter to start from when using explicitly provided needed_data. Format: [3,0]")
    1.11  
    1.12  parser.set_defaults(modulus=2**65, threshold=1, count=10,
    1.13                      runtime=runtimes.keys()[0], mixins="", num_players=2, prss=True,
    1.14 -                    operation=operations.keys()[0], parallel=True, fake=False, args="")
    1.15 +                    operation=operations.keys()[0], parallel=True, fake=False, 
    1.16 +                    args="", needed_data="")
    1.17  
    1.18  print "*" * 60
    1.19  
    1.20 @@ -178,28 +183,44 @@
    1.21  count = options.count
    1.22  print "I am player %d, will %s %d numbers" % (id, options.operation, count)
    1.23  
    1.24 +
    1.25 +class BenchmarkStrategy:
    1.26 +
    1.27 +    def benchmark(self, *args):
    1.28 +        raise NotImplemented("Override this abstract method in subclasses")
    1.29 +
    1.30 +
    1.31 +class SelfcontainedBenchmarkStrategy(BenchmarkStrategy):
    1.32 +
    1.33 +    def benchmark(self, *args):
    1.34 +        sys.stdout.flush()
    1.35 +        sync = self.rt.synchronize()
    1.36 +        self.doTest(sync, lambda x: x)
    1.37 +        self.rt.schedule_callback(sync, self.preprocess)
    1.38 +        self.doTest(sync, lambda x: self.rt.shutdown())
    1.39 +
    1.40 +
    1.41 +class NeededDataBenchmarkStrategy(BenchmarkStrategy):
    1.42 +
    1.43 +    def benchmark(self, needed_data, pc, *args):
    1.44 +        self.pc = pc
    1.45 +        sys.stdout.flush()
    1.46 +        sync = self.rt.synchronize()
    1.47 +        self.rt.schedule_callback(sync, lambda x: needed_data)
    1.48 +        self.rt.schedule_callback(sync, self.preprocess)
    1.49 +        self.doTest(sync, lambda x: self.rt.shutdown())
    1.50 +
    1.51 +
    1.52  # Defining the protocol as a class makes it easier to write the
    1.53  # callbacks in the order they are called. This class is a base class
    1.54  # that executes the protocol by calling the run_test method.
    1.55  class Benchmark:
    1.56  
    1.57      def __init__(self, rt, operation):
    1.58 -        print "init"
    1.59          self.rt = rt
    1.60          self.operation = operation
    1.61          self.pc = None
    1.62 -        sys.stdout.flush()
    1.63 -        sync = self.rt.synchronize()
    1.64 -        self.doTest(sync, lambda x: x)
    1.65 -        self.rt.schedule_callback(sync, self.preprocess)
    1.66 -        self.doTest(sync, lambda x: self.rt.shutdown())
    1.67          
    1.68 -#     def sync_preprocess(self):
    1.69 -#         print "Synchronizing preprocessing"
    1.70 -#         sys.stdout.flush()
    1.71 -#         sync = self.rt.synchronize()
    1.72 -#         self.rt.schedule_callback(sync, self.preprocess)
    1.73 -
    1.74      def preprocess(self, needed_data):
    1.75          print "Preprocess", needed_data
    1.76          if needed_data:
    1.77 @@ -213,10 +234,8 @@
    1.78              return None
    1.79  
    1.80      def doTest(self, d, termination_function):
    1.81 -        print "doTest", self.rt.program_counter
    1.82          self.rt.schedule_callback(d, self.begin)
    1.83          self.rt.schedule_callback(d, self.sync_test)
    1.84 -#         self.rt.schedule_callback(d, self.countdown, 3)
    1.85          self.rt.schedule_callback(d, self.run_test)
    1.86          self.rt.schedule_callback(d, self.sync_test)
    1.87          self.rt.schedule_callback(d, self.finished, termination_function)
    1.88 @@ -246,16 +265,6 @@
    1.89          self.rt.schedule_callback(sync, lambda y: x)
    1.90          return sync
    1.91  
    1.92 -#     def countdown(self, _, seconds):
    1.93 -#         if seconds > 0:
    1.94 -#             print "Starting test in %d" % seconds
    1.95 -#             sys.stdout.flush()
    1.96 -#             reactor.callLater(1, self.countdown, None, seconds - 1)
    1.97 -#         else:
    1.98 -#             print "Starting test now"
    1.99 -#             sys.stdout.flush()
   1.100 -#             self.run_test(None)
   1.101 -
   1.102      def run_test(self, _):
   1.103          raise NotImplemented("Override this abstract method in a sub class.")
   1.104  
   1.105 @@ -286,6 +295,7 @@
   1.106              a = self.a_shares.pop()
   1.107              b = self.b_shares.pop()
   1.108              c_shares.append(self.operation(a, b))
   1.109 +            print "."
   1.110  
   1.111          done = gather_shares(c_shares)
   1.112          done.addCallback(record_stop, "parallel test")
   1.113 @@ -340,6 +350,20 @@
   1.114  else:
   1.115      benchmark = SequentialBenchmark
   1.116  
   1.117 +needed_data = ""
   1.118 +if options.needed_data != "":
   1.119 +    file = open(options.needed_data, 'r')
   1.120 +    for l in file:
   1.121 +        needed_data += l
   1.122 +    needed_data = eval(needed_data)
   1.123 +
   1.124 +if options.needed_data != "" and options.pc != "":
   1.125 +    bases = (benchmark,) + (NeededDataBenchmarkStrategy,) + (object,)
   1.126 +    options.pc = eval(options.pc)
   1.127 +else:
   1.128 +    bases = (benchmark,) + (SelfcontainedBenchmarkStrategy,) + (object,)
   1.129 +benchmark = type("ExtendedBenchmark", bases, {})
   1.130 +
   1.131  pre_runtime = create_runtime(id, players, options.threshold,
   1.132                               options, runtime_class)
   1.133  
   1.134 @@ -355,7 +379,10 @@
   1.135  
   1.136  pre_runtime.addCallback(update_args, options)
   1.137  
   1.138 -pre_runtime.addCallback(benchmark, operation)
   1.139 +def do_benchmark(runtime, operation, benchmark, *args):
   1.140 +    benchmark(runtime, operation).benchmark(*args)
   1.141 +
   1.142 +pre_runtime.addCallback(do_benchmark, operation, benchmark, needed_data, options.pc)
   1.143  
   1.144  print "#### Starting reactor ###"
   1.145  reactor.run()