main_autogen.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import modelverse_kernel.primitives as primitive_functions
  2. import modelverse_kernel.compiled as compiled_functions
  3. from collections import defaultdict
  4. import sys
  5. import time
  6. class ModelverseKernel(object):
  7. def __init__(self, root):
  8. self.root = root
  9. self.primitives = {}
  10. self.returnvalue = None
  11. self.success = True
  12. self.generators = {}
  13. def execute_yields(self, taskname, operation, params, reply):
  14. try:
  15. self.success = True
  16. self.taskname = taskname
  17. if taskname not in self.generators:
  18. self.generators[taskname] = {}
  19. if operation not in self.generators[taskname]:
  20. # Create the generator for the function to execute
  21. self.generators[taskname][operation] = getattr(self, operation)(taskname, *params)
  22. if reply is not None:
  23. return self.generators[taskname][operation].send(reply)
  24. else:
  25. return self.generators[taskname][operation].next()
  26. except StopIteration:
  27. # Done, so remove the generator
  28. del self.generators[taskname][operation]
  29. return None
  30. except:
  31. raise
  32. ##########################
  33. ### Process primitives ###
  34. ##########################
  35. def load_primitives(self, taskname):
  36. hierarchy, = yield [("RD", [self.root, "__hierarchy"])]
  37. primitives, = yield [("RD", [hierarchy, "primitives"])]
  38. keys, = yield [("RDK", [primitives])]
  39. function_names = yield [("RV", [f]) for f in keys]
  40. signatures = yield [("RDN", [primitives, f]) for f in keys]
  41. bodies = yield [("RD", [f, "body"]) for f in signatures]
  42. for i in range(len(keys)):
  43. self.primitives[bodies[i]] = getattr(primitive_functions, function_names[i])
  44. def execute_primitive(self, task_root, inst, taskname):
  45. # execute_primitive
  46. task_frame, = yield [("RD", [task_root, "frame"])]
  47. symbols, = yield [("RD", [task_frame, "symbols"])]
  48. all_links, = yield [("RO", [symbols])]
  49. containers = yield [("RE", [v]) for v in all_links]
  50. outgoings = yield [("RO", [v]) for v in all_links]
  51. dict_values = yield [("RD", [v[1], "value"]) for v in containers]
  52. formals_1 = yield [("RE", [v[0]]) for v in outgoings]
  53. dict_keys_ref = yield [("RD", [v[1], "name"]) for v in formals_1]
  54. dict_keys = yield [("RV", [v]) for v in dict_keys_ref]
  55. parameters = dict(zip(dict_keys, dict_values))
  56. parameters["root"] = self.root
  57. parameters["task_root"] = task_root
  58. parameters["taskname"] = taskname
  59. parameters["mvk"] = self
  60. # prim is a generator itself!
  61. try:
  62. # Forward the message we get to this generator
  63. # Sometimes it might not even be a generator, in which case this should already be in the except block (i.e., for the Read Root operation)
  64. prim = self.primitives[inst](**parameters)
  65. inp = None
  66. while 1:
  67. inp = yield prim.send(inp)
  68. except StopIteration:
  69. # Execution has ended without return value, so we have no idea what to do
  70. raise Exception("Primitive finished without returning a value!")
  71. except primitive_functions.PrimitiveFinished as e:
  72. # Execution has ended with a returnvalue, so read it out from the exception being thrown
  73. result = e.result
  74. #if result is None:
  75. # raise Exception("Primitive raised exception: value of None for operation %s with parameters %s" % (self.compiled[inst], str(parameters)))
  76. # Clean up the current stack, as if a return happened
  77. old_frame, = yield [("RD", [task_frame, "prev"])]
  78. lnk, = yield [("RDE", [old_frame, "returnvalue"])]
  79. _, _, _, _ = yield [("CD", [old_frame, "returnvalue", result]),
  80. ("CD", [task_root, "frame", old_frame]),
  81. ("DE", [lnk]),
  82. ("DN", [task_frame]),
  83. ]
  84. ########################################
  85. ### Execute input and output methods ###
  86. ########################################
  87. def get_output(self, taskname):
  88. task_root, = yield [("RD", [self.root, taskname])]
  89. first_output, = yield [("RD", [task_root, "output"])]
  90. next_output, rv = yield [("RD", [first_output, "next"]),
  91. ("RD", [first_output, "value"]),
  92. ]
  93. if next_output is None:
  94. self.success = False
  95. self.returnvalue = None
  96. else:
  97. rv_value, = yield [("RV", [rv])]
  98. _, _ = yield [("CD", [task_root, "output", next_output]),
  99. ("DN", [first_output]),
  100. ]
  101. self.returnvalue = rv_value
  102. def set_input(self, taskname, value):
  103. task_root, = yield [("RD", [self.root, taskname])]
  104. old_input, link = yield [("RD", [task_root, "last_input"]),
  105. ("RDE", [task_root, "last_input"]),
  106. ]
  107. new_input, = yield [("CN", [])]
  108. _, _ = yield [("CD", [task_root, "last_input", new_input]),
  109. ("CD", [old_input, "next", new_input]),
  110. ]
  111. new_value, = yield [("CNV", [value])]
  112. _, _ = yield [("CD", [old_input, "value", new_value]),
  113. ("DE", [link])
  114. ]
  115. self.returnvalue = {"id": 100, "value": "success"}
  116. ### Generated rules
  117. def execute_rule(self, taskname):