コード例 #1
0
ファイル: sync_compiler.py プロジェクト: joshjennings98/fyp
def create_all_messages(ctxt: InvocationContext, builder: GraphTypeBuilder):
    read_globals = {}
    for (ai, arg) in ctxt.mutable_global_reads:
        # If global appears twice, then some keys may get overwritten with same type
        read_globals["global_{}".format(arg.global_.id)] = arg.data_type
    builder.create_message_type("{invocation}_begin", read_globals)

    write_globals = {}
    for (ai, arg) in ctxt.global_writes:
        # If global appears twice, then some keys may get overwritten with same type
        write_globals["global_{}".format(arg.global_.id)] = arg.data_type
    builder.create_message_type("{invocation}_end", write_globals)

    for (ai, arg) in ctxt.indirect_reads | ctxt.indirect_writes:
        dat = arg.dat
        with builder.subst(dat=dat.id, arity=-arg.index):
            builder.merge_message_type("dat_{dat}", {"value": dat.data_type})
            if arg.index < 0 and (ai, arg) in ctxt.indirect_writes:
                dt = DataType(dat.data_type.dtype,
                              (-arg.index, ) + dat.data_type.shape)
                builder.merge_message_type("dat_{dat}_x{arity}", {"value": dt})
コード例 #2
0
ファイル: sync_compiler.py プロジェクト: joshjennings98/fyp
def sync_compiler(spec: SystemSpecification, code: Statement):
    builder = GraphTypeBuilder("op2_inst")

    builder.add_shared_code_raw(r"""
    #include <cmath>
    #include <cstdio>
    #include <cstdarg>
    
    void fprintf_stderr(const char *msg, ...)
    {
        va_list v;
        va_start(v,msg);
        vfprintf(stderr, msg, v);
        fprintf(stderr, "\n");
        va_end(v);
    }
    
    template<class T,unsigned N>
    void copy_value(T (&x)[N], const T (&y)[N]){
        for(unsigned i=0; i<N; i++){
            x[i]=y[i];
        }
    }
    
    template<class T,unsigned N,unsigned M>
    void copy_value(T (&x)[N][M], const T (&y)[N][M]){
        for(unsigned i=0; i<N; i++){
            for(unsigned j=0; j<M; j++){
                x[i][j]=y[i][j];
            }
        }
    }
    
    /*template<class T>
    void copy_value(T &x, const T (&y)[1]){
        x[0]=y[0];
    }*/
    
    template<class T,unsigned N>
    void inc_value(T (&x)[N], const T (&y)[N]){
        for(unsigned i=0; i<N; i++){
            x[i]+=y[i];
        }
    }
    
    template<class T,unsigned N>
    void zero_value(T (&x)[N]){
        for(unsigned i=0; i<N; i++){
            x[i]=0;
        }
    }
    
    /* Mainly for debug. Used to roughly check that a calculated value is correct, based
        on "known-good" pre-calculated values. Leaves a lot to be desired... */
    template<class T,unsigned N>
    void check_value(T (&got)[N], T (&ref)[N] ){
        for(unsigned i=0; i<N; i++){
            auto diff=std::abs( got[i] - ref[i] );
            assert( diff < 1e-6 ); // Bleh...
        }
    }
    """)

    builder.create_message_type("executeMsgType", {})

    # Support two kinds of global. Only one can be wired into an instance.
    builder.create_device_type(
        "controller")  # This runs the actual program logic
    builder.create_device_type(
        "tester")  # This solely tests each invocation in turn
    builder.add_device_state("tester", "test_state",
                             DataType(shape=(), dtype=numpy.uint32))
    builder.add_device_state("tester", "end_received",
                             DataType(shape=(), dtype=numpy.uint32))
    builder.add_device_state("controller", "end_received",
                             DataType(shape=(), dtype=numpy.uint32))
    builder.add_device_state("controller", "invocation_index",
                             DataType(shape=(), dtype=numpy.uint32))
    for global_ in spec.globals.values():
        if isinstance(global_, MutableGlobal):
            builder.add_device_state("controller",
                                     "global_{}".format(global_.id),
                                     global_.data_type)
            builder.add_device_state("tester", "global_{}".format(global_.id),
                                     global_.data_type)
            builder.add_graph_property("init_global_{}".format(global_.id),
                                       global_.data_type)
        elif isinstance(global_, ConstGlobal):
            builder.add_graph_property("global_{}".format(global_.id),
                                       global_.data_type)

        else:
            raise RuntimeError("Unexpected global type : {}", type(global_))

    builder.merge_message_type("__init__", {})
    for s in spec.sets.values():
        with builder.subst(set="set_" + s.id):
            builder.create_device_type("{set}")
            init_handler = ""
            for dat in s.dats.values():
                with builder.subst(dat=dat.id):
                    builder.add_device_property("{set}", "init_dat_{dat}",
                                                dat.data_type)
                    builder.add_device_state("{set}", "dat_{dat}",
                                             dat.data_type)
                    init_handler += builder.s(
                        "       copy_value(deviceState->dat_{dat}, deviceProperties->init_dat_{dat});\n"
                    )
            builder.add_input_pin("{set}", "__init__", "__init__", None, None,
                                  init_handler)

    kernels = find_kernels_in_code(code)

    emitted_kernels = set()
    for (i, stat) in enumerate(kernels):
        ctxt = InvocationContext(spec, stat)
        with builder.subst(invocation=ctxt.invocation):
            compile_invocation(spec, builder, ctxt, emitted_kernels)
            create_invocation_tester(i, i + 1 == len(kernels), ctxt, builder)
            create_invocation_controller(ctxt, builder)

    compile_global_controller("controller", spec, builder, code)

    return builder