def create_read_send_masks(ctxt: InvocationContext, builder: GraphTypeBuilder): read_sends = {s: set() for s in ctxt.get_all_involved_sets()} for (ai, arg) in ctxt.indirect_reads: read_sends[arg.to_set].add(arg.dat) for (set_, dats) in read_sends.items(): read_send_set = ["0"] + [ builder.s("RTS_FLAG_{invocation}_dat_{dat}_read_send", dat=dat.id) for dat in dats ] read_send_set = "(" + "|".join(read_send_set) + ")" with builder.subst(set=set_.id, read_send_set=read_send_set): builder.add_device_shared_code( "set_{set}", """ const uint32_t {invocation}_{set}_read_send_mask_all = {read_send_set}; """)
def create_read_recv_counts(ctxt: InvocationContext, builder: GraphTypeBuilder): # Start off at 1, as that represents {invocation}_begin read_recvs = {s: 1 for s in ctxt.get_all_involved_sets()} for (ai, arg) in ctxt.indirect_reads: if arg.index < 0: read_recvs[ arg. iter_set] += -arg.index # We'll receive multiple values on this pin else: read_recvs[arg.iter_set] += 1 # Only get a single value for (set_, dats) in read_recvs.items(): with builder.subst(set=set_.id, read_recv_count=read_recvs[set_]): builder.add_device_shared_code( "set_{set}", """ const uint32_t {invocation}_{set}_read_recv_total = {read_recv_count}; """)
def create_write_send_masks(ctxt: InvocationContext, builder: GraphTypeBuilder): """ Creates a mask called {invocation}_{set}_write_send_mask_all for each involved set.""" write_sends = {s: set() for s in ctxt.get_all_involved_sets()} for (ai, arg) in ctxt.indirect_writes: write_sends[arg.iter_set].add((ai, arg)) for (s, args) in write_sends.items(): for (ai, arg) in args: logging.info( "write send mask set=%s, arg=%s, to_set=%s, iter_set=%s", s.id, arg, arg.to_set.id, arg.iter_set.id) write_send_set = ["0"] + [ builder.s("RTS_FLAG_{invocation}_arg{index}_write_send", index=ai) for (ai, arg) in args ] write_send_set = "(" + "|".join(write_send_set) + ")" with builder.subst(set=s.id, write_send_set=write_send_set): builder.add_device_shared_code( "set_{set}", """ const uint32_t {invocation}_{set}_write_send_mask_all = {write_send_set}; """)
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))