Example #1
0
    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)
Example #2
0
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
Example #3
0
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)