def create_all_state_and_properties(ctxt: InvocationContext, builder: GraphTypeBuilder): builder.add_graph_property("{invocation}_total_responding_devices", scalar_uint32) create_state_tracking_variables(ctxt, builder) create_indirect_landing_pads(ctxt, builder) create_global_landing_pads(ctxt, builder)
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