You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.9 KiB

  1. import os
  2. import os.path
  3. import subprocess
  4. import re
  5. import time
  6. import argparse
  7. STORM_PATH= "/Users/mvolk/develop/dft-storm/build/src/storm-dft"
  8. EXAMPLE_DIR= "/Users/mvolk/develop/dft-storm/examples/dft/"
  9. benchmarks = [
  10. ("and", False, [3, 1]),
  11. ("and_param", True, ["(4*x^2+2*x+1)/((x) * (2*x+1))", "1"]),
  12. ("cardiac", False, [11378, 1]),
  13. ("cas", False, [0.859736, 1]),
  14. ("cm2", False, [0.256272, 1]),
  15. #("cm4", False, [0, 1]),
  16. ("cps", False, ["inf", 0.333333]),
  17. ("deathegg", False, [46.667, 1]),
  18. ("fdep", False, [0.666667, 1]),
  19. ("fdep2", False, [2, 1]),
  20. ("fdep3", False, [2.5, 1]),
  21. #("ftpp_complex", False, [0, 1]), # Compute
  22. #("ftpp_large", False, [0, 1]), # Compute
  23. #("ftpp_standard", False, [0, 1]), # Compute
  24. ("mdcs", False, [2.85414, 1]),
  25. ("mdcs2", False, [2.85414, 1]),
  26. ("mp", False, [1.66667, 1]),
  27. ("or", False, [1, 1]),
  28. ("pand", False, ["inf", 0.666667]),
  29. ("pand_param", True, ["-1", "(x)/(y+x)"]),
  30. ("pdep", False, [0, 1]), #Compute
  31. ("pdep2", False, [0, 1]), #Compute
  32. ("spare", False, [3.53846, 1]),
  33. ("spare2", False, [1.86957, 1]),
  34. ("spare3", False, [1.27273, 1]),
  35. ("spare4", False, [4.8459, 1]),
  36. ("spare5", False, [2.66667, 1]), # We discard the result 2.16667 from DFTCalc
  37. ("spare6", False, [1.4, 1]),
  38. ("spare7", False, [3.67333, 1]),
  39. ("symmetry", False, [4.16667, 1]),
  40. ("symmetry2", False, [3.06111, 1]),
  41. ("tripple_and1", False, [4.16667, 1]),
  42. ("tripple_and2", False, [3.66667, 1]),
  43. ("tripple_and2_c", False, [3.6667, 1]),
  44. ("tripple_and_c", False, [4.16667, 1]),
  45. ("tripple_or", False, [0.5, 1]),
  46. ("tripple_or2", False, [0.666667, 1]),
  47. ("tripple_or2_c", False, [0.66667, 1]),
  48. ("tripple_or_c", False, [0.5, 1]),
  49. ("tripple_pand", False, ["inf", 0.0416667]),
  50. ("tripple_pand2", False, ["inf", 0.166667]),
  51. ("tripple_pand2_c", False, ["inf", 0.166667]),
  52. ("tripple_pand_c", False, ["inf", 0.0416667]),
  53. ("voting", False, [1.66667, 1]),
  54. ("voting2", False, [0.588235, 1])
  55. ]
  56. def run_storm_dft(filename, prop, parametric, quiet):
  57. # Run storm-dft on filename and return result
  58. dft_file = os.path.join(EXAMPLE_DIR, filename + ".dft")
  59. args = [STORM_PATH,
  60. dft_file,
  61. prop]
  62. if parametric:
  63. args.append('--parametric')
  64. output = run_tool(args, quiet)
  65. # Get result
  66. match = re.search(r'Result: \[(.*)\]', output)
  67. if not match:
  68. return None
  69. result = match.group(1)
  70. return result
  71. def run_tool(args, quiet=False):
  72. """
  73. Executes a process,
  74. :returns: the `stdout`
  75. """
  76. pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  77. result = "";
  78. for line in iter(pipe.stdout.readline, ""):
  79. if not line and pipe.poll() is not None:
  80. break
  81. output = line.decode(encoding='UTF-8').rstrip()
  82. if output != "":
  83. if not quiet:
  84. print("\t * " + output)
  85. result = output
  86. return result
  87. def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
  88. if a == b:
  89. return True
  90. return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
  91. if __name__ == "__main__":
  92. parser = argparse.ArgumentParser(description='Benchmarking DFTs via Storm')
  93. parser.add_argument('--debuglevel', type=int, default=0, help='the debug level (0=silent, 1=print benchmarks, 2=print output from storm')
  94. args = parser.parse_args()
  95. count = 0
  96. correct = 0
  97. properties = ['--expectedtime', '--probability']
  98. start = time.time()
  99. for index, prop in enumerate(properties):
  100. for (benchmark, parametric, result_original) in benchmarks:
  101. expected_result = result_original[index]
  102. # Run benchmark and check result
  103. count += 1;
  104. if args.debuglevel > 0:
  105. print("Running '{}' with property '{}'".format(benchmark, prop))
  106. result = run_storm_dft(benchmark, prop, parametric, args.debuglevel<2)
  107. if result is None:
  108. print("Error occurred on example '{}' with property '{}'".format(benchmark, prop))
  109. continue
  110. if not parametric:
  111. # Float
  112. result = float(result)
  113. if not isclose(result, float(expected_result), rel_tol=1e-05):
  114. print("Wrong result on example '{}' with property '{}': result: {}, Expected: {}".format(benchmark, prop, result, expected_result))
  115. else:
  116. correct += 1
  117. else:
  118. # Parametric
  119. if result != expected_result:
  120. print("Wrong result on example '{}' with property '{}': result: {}, Expected: {}".format(benchmark, prop, result, expected_result))
  121. else:
  122. correct += 1
  123. end = time.time()
  124. print("Correct results for {} of {} DFT checks in {}s".format(correct, count, end-start))