def render_controller_statement_repeat_for_count(s: RepeatForCount, next_state: int): children = list(s.children()) assert len(children) > 0 init_state = get_statement_state(s) top_state = make_state() body_state = get_statement_state(children[0]) return_state = make_state() var = s.variable # type:MutableGlobal count = s.count # type:int handler = raw(""" case {this_state}: // For. Init handler_log(4, "While {this_state}, evaluate."); deviceState->global_{var}[0]=0; // Fall through to loop condition case {top_state}: // For. Loop top if(deviceState->global_{var}[0] >= {count}){{ deviceState->state={next_state}; break; }} // Fall through to first statement in loop body """.format(this_state=init_state, top_state=top_state, next_state=next_state, var=var.id, count=count)) for (i, c) in enumerate(children): if i + 1 == len(children): local_next_state = return_state else: local_next_state = get_statement_state(children[i + 1]) bit = render_controller_statement(c, local_next_state) logging.info("bit = %s", bit) assert isinstance(bit, raw) handler += bit handler += raw(""" case {return_state}: // For. End deviceState->global_{var}[0]++; // Go back to condition deviceState->state={top_state}; break; """.format(return_state=return_state, var=var.id, top_state=top_state)) return handler
def render_controller_statement_check_state(s: CheckState, next_state: int): handler = raw(""" case {this_state}: // CheckState {{ """.format(this_state=get_statement_state(s))) if False: #handler+=" // TODO : CheckState, pattern='{}'".format(s.pattern) handler += """ handler_checkpoint(true, "global:""" args = [] pat_todo = s.pattern while True: ib = pat_todo.find("{") if ib == -1: handler += pat_todo break ie = pat_todo.find("}", ib + 1) assert ie != -1 name = pat_todo[ib + 1:ie] pat_todo = pat_todo[ie + 1:] handler += "%d" handler += """ }} deviceState->state={next_state}; break; """.format(next_state=next_state) return handler
def render_controller_statement_user(s: UserCode, next_state: int): handler = raw(""" case {this_state}: // UserCode {{ handler_log(4, "User code {user_code_id} begin."); kernel_{user_code_id}( """.format(this_state=get_statement_state(s), user_code_id=s.id)) args = list(s.arguments) for (i, arg) in enumerate(args): if isinstance(arg.global_, MutableGlobal): handler += " deviceState->global_{}".format(arg.global_.id) elif isinstance(arg.global_, ConstGlobal): handler += " graphProperties->global_{}".format( arg.global_.id) else: raise RuntimeError("Unknown arg type {}.".format(type(arg))) if i + 1 != len(args): handler += "," handler += "\n" handler += """ ); handler_log(4, "User code {user_code_id} end."); }} deviceState->state={next_state}; break; """.format(next_state=next_state, user_code_id=s.id) return handler
def render_controller_statement_while(s: While, next_state: int): children = list(s.children()) assert len(children) > 0 cond_state = get_statement_state(s) body_state = get_statement_state(children[0]) tail_state = make_state() handler = raw(""" case {this_state}: // While. Condition state. handler_log(4, "While {this_state}, evaluate."); kernel_{user_code_id}( """.format(this_state=get_statement_state(s), user_code_id=s.id)) args = list(s.arguments) for (i, arg) in enumerate(args): if isinstance(arg.global_, MutableGlobal): handler += " deviceState->global_{}".format(arg.global_.id) elif isinstance(arg.global_, ConstGlobal): handler += " graphProperties->global_{}".format( arg.global_.id) else: raise RuntimeError("Unknown arg type {}.".format(type(arg))) if i + 1 != len(args): handler += "," handler += "\n" handler += """ ); handler_log(4, "While {this_state}, condition = %d.", deviceState->global__cond_[0]); if(deviceState->global__cond_[0]){{ deviceState->state={body_state}; }}else{{ deviceState->state={next_state}; }} break; """.format(this_state=cond_state, body_state=body_state, next_state=next_state) for (i, c) in enumerate(children): if i + 1 == len(children): local_next_state = tail_state else: local_next_state = get_statement_state(children[i + 1]) bit = render_controller_statement(c, local_next_state) logging.info("bit = %s", bit) assert isinstance(bit, raw) handler += bit handler += """ case {tail_state}: deviceState->state={cond_state}; break; """.format(tail_state=tail_state, cond_state=cond_state) return handler
def render_controller_statement_par_for(s: ParFor, next_state: int): return raw(""" case {this_state}: // ParFor {{ deviceState->rts=RTS_FLAG_{invocation}_begin; deviceState->state={next_state}; deviceState->invocation_index=RTS_INDEX_controller_{invocation}_begin; }} break; """.format(invocation=s.id, next_state=next_state, this_state=get_statement_state(s)))
def render_controller_statement_seq(s: Seq, next_state: int): children = list(s.children()) assert len(children) > 0 handler = raw(""" case {this_state}: // Seq. fall-through to first statement handler_log(4, "Seq {this_state} begin."); """.format(this_state=get_statement_state(s), first_child_state=get_statement_state(children[0]))) for (i, c) in enumerate(children): if i + 1 == len(children): local_next_state = next_state else: local_next_state = get_statement_state(children[i + 1]) bit = render_controller_statement(c, local_next_state) logging.info("bit = %s", bit) assert isinstance(bit, raw) handler += bit return handler
def compile_global_controller(gi: str, spec: SystemSpecification, builder: GraphTypeBuilder, code: Statement): create_controller_states( code) # Make sure every statement has an entry state builder.add_device_state(gi, "rts", scalar_uint32) builder.add_device_state(gi, "state", scalar_uint32) # This will be used as a hidden global, and captures the value # of the condition for If and While assert "_cond_" in spec.globals start_state = get_statement_state(code) finish_state = make_state() builder.add_rts_clause(gi, "*readyToSend = deviceState->rts;\n") with builder.subst(start_state=start_state): handler = """ deviceState->rts=RTS_FLAG_control; deviceState->state={start_state}; handler_log(4, "rts=%x, state=%d", deviceState->rts, deviceState->state); """ for mg in spec.globals.values(): if isinstance(mg, MutableGlobal): handler += """ copy_value(deviceState->global_{global_}, graphProperties->init_global_{global_}); """.format(global_=mg.id) builder.add_input_pin(gi, "__init__", "__init__", None, None, handler) handler = raw(""" handler_log(4, "rts=%x, state=%d", deviceState->rts, deviceState->state); *doSend=0; // disable this send... deviceState->rts=RTS_FLAG_control; // ... but say that we want to send again (by default) switch(deviceState->state){ """) handler += render_controller_statement(code, finish_state) handler += """ case {finish_state}: handler_log(4, "Hit finish state."); handler_exit(0); break; default: handler_log(3, "Unknown state id %d.", deviceState->state); assert(0); }} """.format(finish_state=finish_state) builder.create_message_type("control", {}) builder.add_output_pin(gi, "control", "control", handler) for user_code in find_scalars_in_code(code): name = user_code.id assert user_code.ast src = mini_op2.framework.kernel_translator.scalar_to_c( user_code.ast, name) builder.add_device_shared_code("controller", raw(src)) for k in code.all_statements(): if isinstance(k, While): name = k.id src = mini_op2.framework.kernel_translator.scalar_to_c( k.expr_ast, name) builder.add_device_shared_code("controller", raw(src))