Пример #1
0
def create_invocation_end(ctxt: InvocationContext, builder: GraphTypeBuilder):
    for set in ctxt.get_all_involved_sets():
        with builder.subst(set=set.id):
            handler = """
            assert(deviceState->{invocation}_in_progress);
            assert( deviceState->{invocation}_read_send_mask == 0 );
            assert( deviceState->{invocation}_write_send_mask == 0 );
            assert( deviceState->{invocation}_read_recv_count == 0 );
            assert( deviceState->{invocation}_write_recv_count == deviceProperties->{invocation}_write_recv_total );
            
            deviceState->{invocation}_in_progress=0;
            deviceState->{invocation}_read_recv_count=0;
            deviceState->{invocation}_write_recv_count=0;
            """
            if set == ctxt.stat.iter_set:
                for (ai, arg) in ctxt.global_writes:
                    handler += """
                    copy_value(message->global_{}, deviceState->global_{});
                    """.format(arg.global_.id, arg.global_.id)
            else:
                for (ai, arg) in ctxt.global_writes:
                    handler += """
                    zero_value(message->global_{});
                    """.format(arg.global_.id)
            builder.add_output_pin("set_{set}", "{invocation}_end",
                                   "{invocation}_end", handler)
Пример #2
0
def create_indirect_read_sends(ctxt: InvocationContext,
                               builder: GraphTypeBuilder):
    for dat in ctxt.get_indirect_read_dats():
        with builder.subst(dat=dat.id, set=dat.set.id):
            builder.add_output_pin(
                "set_{set}", "{invocation}_dat_{dat}_read_send", "dat_{dat}",
                """
                assert(deviceState->{invocation}_read_send_mask & RTS_FLAG_{invocation}_dat_{dat}_read_send);
                copy_value(message->value, deviceState->dat_{dat});
                deviceState->{invocation}_read_send_mask &= ~RTS_FLAG_{invocation}_dat_{dat}_read_send;
                """)
Пример #3
0
def create_invocation_execute(ctxt: InvocationContext,
                              builder: GraphTypeBuilder):
    for set in ctxt.get_all_involved_sets():

        with builder.subst(set=set.id, kernel=ctxt.stat.name):
            handler = """
            assert( deviceState->{invocation}_in_progress );
            assert( deviceState->{invocation}_read_recv_count == {invocation}_{set}_read_recv_total );
            
            deviceState->{invocation}_read_recv_count=0; // Allows us to tell that execute has happened
            deviceState->{invocation}_write_recv_count++; // The increment for this "virtual" receive
            deviceState->{invocation}_write_send_mask = {invocation}_{set}_write_send_mask_all; // In device-local shared code
            """

            if set == ctxt.stat.iter_set:
                handler += "kernel_{kernel}(\n"
                for (ai, arg) in enumerate(ctxt.stat.arguments):
                    if isinstance(arg, GlobalArgument):
                        if (
                                ai, arg
                        ) in ctxt.mutable_global_reads | ctxt.global_writes:
                            handler += builder.s("  deviceState->global_{id}",
                                                 id=arg.global_.id)
                        else:
                            handler += builder.s(
                                "  (double*)graphProperties->global_{id}",
                                id=arg.global_.id)
                    elif isinstance(arg, DirectDatArgument):
                        handler += builder.s("  deviceState->dat_{dat}",
                                             dat=arg.dat.id)
                    elif isinstance(arg, IndirectDatArgument):
                        handler += builder.s(
                            "  deviceState->{invocation}_arg{index}_buffer",
                            index=ai)
                    else:
                        raise RuntimeError("Unexpected arg type.")
                    if ai + 1 < len(ctxt.stat.arguments):
                        handler += ","
                    handler += "\n"
                handler += ");\n"

            builder.add_output_pin("set_{set}", "{invocation}_execute",
                                   "executeMsgType", handler)
Пример #4
0
def create_invocation_controller(ctxt: InvocationContext,
                                 builder: GraphTypeBuilder):
    handler = """
        assert(deviceState->end_received==0);
        assert(deviceState->invocation_index==RTS_INDEX_controller_{invocation}_begin);
        deviceState->end_received=0;
        deviceState->rts=0;
        """
    for (ai, arg) in ctxt.mutable_global_reads:
        handler += builder.s("""
        copy_value(message->global_{name}, deviceState->global_{name});
        """,
                             name=arg.global_.id)

    builder.add_output_pin("controller", "{invocation}_begin",
                           "{invocation}_begin", handler)

    handler = """
        assert(deviceState->invocation_index==RTS_INDEX_controller_{invocation}_begin);
        assert(deviceState->end_received < graphProperties->{invocation}_total_responding_devices);
        deviceState->end_received++;
    """
    # Collect any inc's to global values
    for (ai, arg) in ctxt.global_writes:
        assert arg.access_mode == AccessMode.INC
        handler += builder.s("""
        inc_value(deviceState->global_{name}, message->global_{name});
        """,
                             name=arg.global_.id)
    # Check whether we have finished
    handler += """
        if(deviceState->end_received == graphProperties->{invocation}_total_responding_devices){{
    """

    handler += """
            deviceState->invocation_index=-1;
            deviceState->end_received=0;
            deviceState->rts=RTS_FLAG_controller_control;
        }}
    """
    builder.add_input_pin("controller", "{invocation}_end", "{invocation}_end",
                          None, None, handler)
Пример #5
0
def create_indirect_write_sends(ctxt: InvocationContext,
                                builder: GraphTypeBuilder):
    for (ai, arg) in ctxt.indirect_writes:
        with builder.subst(index=ai,
                           set=arg.iter_set.id,
                           dat=arg.dat.id,
                           arity=-arg.index):
            if arg.index >= 0:
                builder.add_output_pin(
                    "set_{set}", "{invocation}_arg{index}_write_send",
                    "dat_{dat}", """
                    assert(deviceState->{invocation}_write_send_mask & RTS_FLAG_{invocation}_arg{index}_write_send);
                    copy_value(message->value, deviceState->{invocation}_arg{index}_buffer);
                    deviceState->{invocation}_write_send_mask &= ~RTS_FLAG_{invocation}_arg{index}_write_send;
                    """)
            else:
                builder.add_output_pin(
                    "set_{set}", "{invocation}_arg{index}_write_send",
                    "dat_{dat}_x{arity}", """
                    assert(deviceState->{invocation}_write_send_mask & RTS_FLAG_{invocation}_arg{index}_write_send);
                    copy_value(message->value, deviceState->{invocation}_arg{index}_buffer);
                    deviceState->{invocation}_write_send_mask &= ~RTS_FLAG_{invocation}_arg{index}_write_send;
                    """)
Пример #6
0
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))
Пример #7
0
def create_invocation_tester(testIndex: int, isLast: bool,
                             ctxt: InvocationContext,
                             builder: GraphTypeBuilder):
    with builder.subst(testIndex=testIndex, isLast=int(isLast)):
        handler = """
            assert(deviceState->end_received==0);
            assert(deviceState->test_state==2*{testIndex});
            deviceState->test_state++; // Odd value means we are waiting for the return
            deviceState->end_received=0;
            """
        #for (ai,arg) in ctxt.mutable_global_reads:
        #    handler+=builder.s("""
        #    copy_value(message->global_{name}, graphProperties->test_{invocation}_{name}_in);
        #    """,name=arg.global_.id)

        builder.add_output_pin("tester", "{invocation}_begin",
                               "{invocation}_begin", handler)

        handler = """
            assert(deviceState->test_state==2*{testIndex}+1);
            assert(deviceState->end_received < graphProperties->{invocation}_total_responding_devices);
            deviceState->end_received++;
        """
        # Collect any inc's to global values
        for (ai, arg) in ctxt.global_writes:
            assert arg.access_mode == AccessMode.INC
            handler += builder.s("""
            inc_value(deviceState->global_{name}, message->global_{name});
            """,
                                 name=arg.global_.id)
        # Check whether we have finished
        handler += """
            if(deviceState->end_received == graphProperties->{invocation}_total_responding_devices){{
        """
        # Remove for now - not clear how to do this.
        if False:
            # ... and if so, try to check the results are "right"
            for (ai, arg) in ctxt.global_writes:
                handler += builder.s("""
                    check_value(deviceState->global_{name}, graphProperties->test_{invocation}_{name}_out);
                """,
                                     name=arg.global_.id)

        handler += """
                if( {isLast} ){{
                    handler_exit(0);
                }}else{{
                    deviceState->test_state++; // start the next invocation
                    deviceState->end_received=0;
                }}
            }}
        """
        builder.add_input_pin("tester", "{invocation}_end", "{invocation}_end",
                              None, None, handler)

        builder.add_rts_clause(
            "tester", """
        if(deviceState->test_state==2*{testIndex}){{
            *readyToSend = RTS_FLAG_{invocation}_begin;
        }}
        """)