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):