def callMethod(self, obj, name, *args): # Shortcut for executing a simple task if name == "execute_task": _, subargs = args return self.execute_task(subargs) elif name == "run": # Convert arguments back to dace_state, deserializing the SDFG from diode.DaceState import DaceState dace_state = DaceState(args[0][0], args[0][1], args[0][2], SDFG.from_json(args[0][3]), args[0][4]) args = (dace_state, *args[1:]) return getattr(obj, name)(*args)
def create_DaceState(code, sdfg_dict, errors): dace_state = None try: dace_state = DaceState(code, "fake.py", remote=remote_execution) for x in dace_state.sdfgs: name, sdfg = x sdfg_dict[name] = sdfg return dace_state except SyntaxError as se: # Syntax error errors.append({ 'type': "SyntaxError", 'line': se.lineno, 'offset': se.offset, 'text': se.text, 'msg': se.msg }) except ValueError as ve: # DACE-Specific error tb = traceback.format_exc() errors.append({ 'type': "ValueError", 'stringified': str(ve), 'traceback': tb }) except Exception as ge: # Generic exception tb = traceback.format_exc() errors.append({ 'type': ge.__class__.__name__, 'stringified': str(ge), 'traceback': tb }) return dace_state
def compileProgram(request, language, perfopts=None): if not request.json or (('code' not in request.json) and ('sdfg' not in request.json)): print("[Error] No input code provided, cannot continue") abort(400) errors = [] try: optpath = request.json['optpath'] except: optpath = None try: sdfg_props = request.json['sdfg_props'] except: sdfg_props = None if perfopts is None: try: perf_mode = request.json['perf_mode'] except: perf_mode = None else: #print("Perfopts: " + str(perfopts)) perf_mode = perfopts client_id = request.json['client_id'] sdfg_dict = {} sdfg_eval_order = [] with config_lock: # Lock the config - the config may be modified while holding this lock, but the config MUST be restored. from dace.config import Config config_path = "./client_configs/" + client_id + ".conf" if os.path.isfile(config_path): Config.load(config_path) else: Config.load() dace_state = None in_sdfg = None if "sdfg" in request.json: in_sdfg = request.json['sdfg'] if isinstance(in_sdfg, list): if len(in_sdfg) > 1: # TODO: Allow multiple sdfg inputs raise NotImplementedError("More than 1 SDFG provided") in_sdfg = in_sdfg[0] if isinstance(in_sdfg, str): in_sdfg = json.loads(in_sdfg) if isinstance(in_sdfg, dict): # Generate callbacks (needed for elements referencing others) def loader_callback(name: str): # Check if already available and if yes, return it if name in sdfg_dict: return sdfg_dict[name] # Else: This function has to recreate the given sdfg sdfg_dict[name] = dace.SDFG.from_json( in_sdfg[name], { 'sdfg': None, 'callback': loader_callback }) sdfg_eval_order.append(name) return sdfg_dict[name] for k, v in in_sdfg.items(): # Leave it be if the sdfg was already created # (this might happen with SDFG references) if k in sdfg_dict: continue if isinstance(v, str): v = json.loads(v) sdfg_dict[k] = dace.SDFG.from_json( v, { 'sdfg': None, 'callback': loader_callback }) sdfg_eval_order.append(k) else: in_sdfg = dace.SDFG.from_json(in_sdfg) sdfg_dict[in_sdfg.name] = in_sdfg else: print("Using code to compile") code = request.json['code'] if (isinstance(code, list)): if len(code) > 1: print("More than 1 code file provided!") abort(400) code = code[0] if language == "octave": statements = octave_frontend.parse(code, debug=False) statements.provide_parents() statements.specialize() sdfg = statements.generate_code() sdfg.set_sourcecode(code, "matlab") elif language == "dace": dace_state = create_DaceState(code, sdfg_dict, errors) # The DaceState uses the variable names in the dace code. This is not useful enough for us, so we translate copied_dict = {} for k, v in sdfg_dict.items(): copied_dict[v.name] = v sdfg_dict = copied_dict if len(errors) == 0: if optpath is not None: for sdfg_name, op in optpath.items(): try: sp = sdfg_props[sdfg_name] except: # In any error case, just ignore the properties sp = None print("Applying opts for " + sdfg_name) print("Dict: " + str(sdfg_dict.keys())) sdfg_dict[sdfg_name] = applyOptPath(sdfg_dict[sdfg_name], op, sdfg_props=sp) code_tuple_dict = {} # Deep-copy the SDFG (codegen may change the SDFG it operates on) codegen_sdfgs = copy.deepcopy(sdfg_dict) codegen_sdfgs_dace_state = copy.deepcopy(sdfg_dict) if len(errors) == 0: if sdfg_eval_order: sdfg_eval = [(n, codegen_sdfgs[n]) for n in reversed(sdfg_eval_order)] else: sdfg_eval = codegen_sdfgs.items() for n, s in sdfg_eval: try: if Config.get_bool('diode', 'general', 'library_autoexpand'): s.expand_library_nodes() code_tuple_dict[n] = codegen.generate_code(s) except dace.sdfg.NodeNotExpandedError as ex: code_tuple_dict[n] = [str(ex)] except Exception: # Forward exception to output code code_tuple_dict[n] = [ 'Code generation failed:\n' + traceback.format_exc() ] if dace_state is None: if "code" in request.json: in_code = request.json['code'] else: in_code = "" dace_state = DaceState(in_code, "tmp.py", remote=remote_execution) dace_state.set_sdfg( list(codegen_sdfgs_dace_state.values())[0], list(codegen_sdfgs_dace_state.keys())[0]) if len(dace_state.errors) > 0: print("ERRORS: " + str(dace_state.errors)) errors.extend(dace_state.errors) # The config won't save back on its own, and we don't want it to - these changes are transient if len(errors) > 0: return errors # Only return top-level SDFG return ({k: v for k, v in sdfg_dict.items() if v.parent is None}, code_tuple_dict, dace_state)