예제 #1
0
def test_svd(python_method_impl):
    with CodeBuilder(name="primary") as cb:
        cb("n", 3)
        cb("nodes", "`<builtin>array`(n)")
        cb("vdm", "`<builtin>array`(n*n)")
        cb("identity", "`<builtin>array`(n*n)")

        cb("nodes[i]", "i/n", loops=[("i", 0, "n")])

        cb("vdm[j*n + i]", "nodes[i]**j", loops=[("i", 0, "n"), ("j", 0, "n")])

        cb("vdm_u, vdm_sigma, vdm_vt", "`<builtin>svd`(vdm, n)")
        cb("vdm_usigma", "`<builtin>array`(n*n)")
        cb("vdm_v", "`<builtin>array`(n*n)")
        cb("vdm_usigma[i + j*n]",
           "vdm_u[i + j*n] * vdm_sigma[j]",
           loops=[("i", 0, "n"), ("j", 0, "n")])
        cb("vdm_v[i + j*n]",
           "vdm_vt[j + i*n]",
           loops=[("i", 0, "n"), ("j", 0, "n")])

        cb("vdm_2", "`<builtin>matmul`(vdm_usigma, vdm_vt, n, n)")
        cb("diff", "vdm-vdm_2")

        cb((), "`<builtin>print`(diff)")

        cb.yield_state("diff", "result", 0, "final")

    from utils import execute_and_return_single_result

    code = create_DAGCode_with_steady_phase(cb.statements)
    result = execute_and_return_single_result(python_method_impl, code)

    assert la.norm(result) < 1e-10
예제 #2
0
def test_class_preamble():
    from dagrt.language import CodeBuilder

    with CodeBuilder(name="primary") as cb:
        cb.assign("<t>", "<t> + <dt>")
        cb.yield_state("f()", "f", 0, "final")

    code = create_DAGCode_with_steady_phase(cb.statements)

    from dagrt.codegen import PythonCodeGenerator
    import dagrt.function_registry as freg

    preamble = """
            @staticmethod
            def f():
                return 1
    """

    f = freg.Function(identifier="f",
                      language_to_codegen={"python": lambda *args: "self.f()"})

    generator = PythonCodeGenerator(
        "PythonMethod",
        class_preamble=preamble,
        function_registry=freg.base_function_registry.register(f))

    class_ = generator.get_class(code)

    method = class_(function_map={})
    method.set_up(t_start=0, dt_start=1, context={})

    events = list(method.run(t_end=1))
    assert events
    assert isinstance(events[0], class_.StateComputed)
    assert events[0].state_component == 1
예제 #3
0
def test_create_ast():
    x = var("<cond>x")

    class ComparableNop(Statement):
        """
        Works around the fact that __hash__ and comparison isn't defined for
        statements, but is necessary for comparison purposes when embedded
        in an expression.
        """
        def _state(self):
            return (self.condition, self.id, self.depends_on)

        def __eq__(self, other):
            return (self.__class__ == other.__class__
                    and self._state() == other._state())

        def __ne__(self, other):
            return not self.__eq__(other)

        def __hash__(self):
            return hash(self._state())

    nop = ComparableNop(condition=x, id="nop", depends_on=())
    code = create_DAGCode_with_steady_phase([nop])
    ast = create_ast_from_phase(code, "main")
    assert ast == IfThen(x, StatementWrapper(nop.copy(condition=True)))
예제 #4
0
def test_arrays_and_linalg(python_method_impl):
    with CodeBuilder(name="primary") as cb:
        cb("n", "4")
        cb("nodes", "`<builtin>array`(n)")
        cb("vdm", "`<builtin>array`(n*n)")
        cb("identity", "`<builtin>array`(n*n)")

        cb("nodes[i]", "i/n", loops=[("i", 0, "n")])
        cb("identity[i]", "0", loops=[("i", 0, "n*n")])

        cb("identity[i*n + i]", "1", loops=[("i", 0, "n")])
        cb("vdm[j*n + i]", "nodes[i]**j", loops=[("i", 0, "n"), ("j", 0, "n")])

        cb("vdm_inverse", "`<builtin>linear_solve`(vdm, identity, n, n)")
        cb("myarray", "`<builtin>matmul`(vdm, vdm_inverse, n, n)")

        cb((), "`<builtin>print`(myarray)")

        cb.yield_state("myarray", "result", 0, "final")

    from utils import execute_and_return_single_result

    code = create_DAGCode_with_steady_phase(cb.statements)
    result = execute_and_return_single_result(python_method_impl, code)

    result = result.reshape(4, 4, order="F")

    assert la.norm(result - np.eye(4)) < 1e-10
예제 #5
0
def test_CodeBuilder_assign(python_method_impl):
    with CodeBuilder("phase") as builder:
        builder(var("x"), 1)
        builder.yield_state(var("x"), "x", 0, "final")
    code = create_DAGCode_with_steady_phase(builder.statements)
    result = execute_and_return_single_result(python_method_impl, code)
    assert result == 1
예제 #6
0
def test_missing_state_detection():
    """Check that the code generator detects there is a missing state."""
    from dagrt.language import CodeBuilder

    with CodeBuilder(name="state_1") as cb:
        cb.switch_phase("state_2")

    code = create_DAGCode_with_steady_phase(statements=cb.statements)
    with pytest.raises(CodeGenerationError):
        verify_code(code)
예제 #7
0
def test_arrays_and_looping(python_method_impl):
    with CodeBuilder(name="primary") as cb:
        cb("myarray", "`<builtin>array`(20)")
        cb("myarray[i]", "i", loops=[("i", 0, 20)])
        cb.yield_state("myarray[15]", "result", 0, "final")

    from utils import execute_and_return_single_result

    code = create_DAGCode_with_steady_phase(cb.statements)
    result = execute_and_return_single_result(python_method_impl, code)
    assert result == 15
예제 #8
0
def test_CodeBuilder_condition_with_else_not_taken(python_method_impl):
    with CodeBuilder("phase") as builder:
        builder(var("x"), 1)
        with builder.if_(var("x"), "==", 1):
            builder(var("x"), 2)
        with builder.else_():
            builder(var("x"), 3)
        builder.yield_state(var("x"), "x", 0, "final")
    code = create_DAGCode_with_steady_phase(builder.statements)
    result = execute_and_return_single_result(python_method_impl, code)
    assert result == 2
예제 #9
0
def test_isnan(python_method_impl, value):
    cbuild = RawCodeBuilder()
    cbuild.add_and_get_ids(
        Assign(id="assign_1", assignee="x", assignee_subscript=(),
                         expression=var("<builtin>isnan")(value)),
        YieldState(id="return", time=0, time_id="final",
                   expression=var("x"), component_id="<state>",
                   depends_on=["assign_1"]))
    cbuild.commit()
    code = create_DAGCode_with_steady_phase(cbuild.statements)

    result = execute_and_return_single_result(python_method_impl, code)
    assert result == np.isnan(value)
예제 #10
0
def test_elementwise_abs():
    with CodeBuilder(name="primary") as cb:
        cb("i", "<builtin>array(20)")
        cb("i[j]", "-j", loops=(("j", 0, 20), ))
        # Test new builtin on an array type.
        cb("k", "<builtin>elementwise_abs(i)")
        with cb.if_("k[20] > 19"):
            cb.raise_(AbsFailure)
        with cb.if_("k[20] < 19"):
            cb.raise_(AbsFailure)
        # Test new builtin on a scalar.
        cb("l", "<builtin>elementwise_abs(-20)")
        with cb.if_("l > 20"):
            cb.raise_(AbsFailure)
        with cb.if_("l < 20"):
            cb.raise_(AbsFailure)
        cb("y", "<func>f(0, <state>ytype)")
        cb("<state>ytype", "y")
        # Test new builtin on a usertype.
        cb("<state>ytype", "<builtin>elementwise_abs(<state>ytype)")
        # (We check this in the outer test code)

    code = create_DAGCode_with_steady_phase(cb.statements)

    rhs_function = "<func>f"

    from dagrt.function_registry import (base_function_registry,
                                         register_ode_rhs)
    freg = register_ode_rhs(base_function_registry,
                            "ytype",
                            identifier=rhs_function,
                            input_names=("y", ))
    freg = freg.register_codegen(
        rhs_function, "fortran",
        f.CallCode("""
                ${result} = -2*${y}
                """))

    codegen = f.CodeGenerator(
        "element_abs_test",
        function_registry=freg,
        user_type_map={"ytype": f.ArrayType((100, ), f.BuiltinType("real*8"))},
        timing_function="second")

    code_str = codegen(code)

    run_fortran([
        ("element_abs.f90", code_str),
        ("test_element_abs.f90", read_file("test_element_abs.f90")),
    ],
                fortran_libraries=["lapack", "blas"])
예제 #11
0
def test_arrays_and_linalg():
    from dagrt.function_registry import base_function_registry as freg

    with CodeBuilder(name="primary") as cb:
        cb("n", "4")
        cb("nodes", "`<builtin>array`(n)")
        cb("vdm", "`<builtin>array`(n*n)")
        cb("identity", "`<builtin>array`(n*n)")

        cb("nodes[i]", "i/n", loops=[("i", 0, "n")])
        cb("identity[i]", "0", loops=[("i", 0, "n*n")])

        cb("identity[i*n + i]", "1", loops=[("i", 0, "n")])
        cb("vdm[j*n + i]", "nodes[i]**j", loops=[("i", 0, "n"), ("j", 0, "n")])

        cb("vdm_inverse", "`<builtin>linear_solve`(vdm, identity, n, n)")
        cb("myarray", "`<builtin>matmul`(vdm, vdm_inverse, n, n)")

        cb("myzero", "myarray - identity")
        cb((), "`<builtin>print`(myzero)")
        with cb.if_("`<builtin>norm_2`(myzero) > 10**(-8)"):
            cb.raise_(MatrixInversionFailure)

    code = create_DAGCode_with_steady_phase(cb.statements)

    codegen = f.CodeGenerator("arrays",
                              function_registry=freg,
                              user_type_map={},
                              emit_instrumentation=True,
                              timing_function="second")

    code_str = codegen(code)
    if 0:
        with open("arrays.f90", "wt") as outf:
            outf.write(code_str)

    run_fortran([
        ("arrays.f90", code_str),
        ("test_arrays_and_linalg.f90",
         read_file("test_arrays_and_linalg.f90")),
    ],
                fortran_libraries=["lapack", "blas"])
예제 #12
0
def get_IfThenElse_test_code_and_expected_result():
    from dagrt.expression import IfThenElse

    with CodeBuilder(name="primary") as cb:
        cb(var("c1"), IfThenElse(True, 0, 1))
        cb(var("c2"), IfThenElse(False, 0, 1))
        cb(var("c3"), IfThenElse(IfThenElse(True, True, False), 0, 1))
        cb(var("c4"), IfThenElse(IfThenElse(False, True, False), 0, 1))
        cb(var("c5"), IfThenElse(True, IfThenElse(True, 0, 1), 2))
        cb(var("c6"), IfThenElse(True, IfThenElse(False, 0, 1), 2))
        cb(var("c7"), IfThenElse(False, 0, IfThenElse(True, 1, 2)))
        cb(var("c8"), IfThenElse(False, 0, IfThenElse(False, 1, 2)))
        cb(var("c9"), 1 + IfThenElse(True, 0, 1))
        cb(var("c10"), 1 + IfThenElse(False, 0, 1))
        cb.yield_state(tuple(var("c" + str(i)) for i in range(1, 11)),
                       "result", 0, "final")

    code = create_DAGCode_with_steady_phase(cb.statements)

    return (code, (0, 1, 0, 1, 0, 1, 1, 2, 1, 2))
예제 #13
0
def test_basic_codegen():
    """Test whether the code generator returns a working method. The
    generated method always returns 0."""
    cbuild = RawCodeBuilder()
    cbuild.add_and_get_ids(
        YieldState(id="return",
                   time=0,
                   time_id="final",
                   expression=0,
                   component_id="state",
                   depends_on=[]))
    cbuild.commit()
    code = create_DAGCode_with_steady_phase(cbuild.statements)
    codegen = f.CodeGenerator("simple",
                              user_type_map={
                                  "state":
                                  f.ArrayType(
                                      (200, ),
                                      f.BuiltinType("real (kind=8)"),
                                  )
                              })
    print(codegen(code))
예제 #14
0
def test_norm(python_method_impl, order, norm_suffix, test_vector):

    def true_norm(x):
        if np.isscalar(x):
            return abs(x)
        return np.linalg.norm(x, ord=order)

    cbuild = RawCodeBuilder()
    cbuild.add_and_get_ids(
        Assign(id="assign_1", assignee="x", assignee_subscript=(),
                         expression=test_vector),
        Assign(id="assign_2", assignee="n", assignee_subscript=(),
                         expression=(
                             var("<builtin>norm_%s" % norm_suffix)(var("x"))),
                         depends_on=["assign_1"]),
        YieldState(id="return", time=0, time_id="final",
                   expression=var("n"), component_id="<state>",
                   depends_on=["assign_2"]))
    cbuild.commit()
    code = create_DAGCode_with_steady_phase(cbuild.statements)

    result = execute_and_return_single_result(python_method_impl, code)
    assert np.allclose(result, true_norm(test_vector))
예제 #15
0
def test_self_dep_in_loop():
    with CodeBuilder(name="primary") as cb:
        cb("y", "<state>y")
        cb("y",
           "<func>f(0, 2*i*<func>f(0, y if i > 2 else 2*y))",
           loops=(("i", 0, 5), ))
        cb("<state>y", "y")

    code = create_DAGCode_with_steady_phase(cb.statements)

    rhs_function = "<func>f"

    from dagrt.function_registry import (base_function_registry,
                                         register_ode_rhs)
    freg = register_ode_rhs(base_function_registry,
                            "ytype",
                            identifier=rhs_function,
                            input_names=("y", ))
    freg = freg.register_codegen(
        rhs_function, "fortran",
        f.CallCode("""
                ${result} = -2*${y}
                """))

    codegen = f.CodeGenerator(
        "selfdep",
        function_registry=freg,
        user_type_map={"ytype": f.ArrayType((100, ), f.BuiltinType("real*8"))},
        timing_function="second")

    code_str = codegen(code)
    run_fortran([
        ("selfdep.f90", code_str),
        ("test_selfdep.f90", read_file("test_selfdep.f90")),
    ],
                fortran_libraries=["lapack", "blas"])