Пример #1
0
    def test_same_recipe(self, tmpdir):

        exp = Experiment(directory=tmpdir, state_class=EmptyState)

        exp_args = {"a": 10.0, "B": "notused"}
        root = exp.spawn_new_tree(**exp_args)

        op = OpRecipe(mul, 0.4, stochastic=False)

        new_state_a = op(root)
        new_state_b = op(root)
        new_state_c = op(root)

        # make sure this creates three new dask delayed states
        assert len(exp.leaves) == 3
        for leafID, leaf in exp.leaves.items():
            assert type(leaf) == Delayed

        # Since this is the same op on the root, these three ops would result
        # in 3 identical states. Check, therefore, that only one state is
        # created
        exp.run()
        exp = Experiment.restore(directory=tmpdir, state_class=EmptyState)
        assert len(exp.graph.node_map) == 2  # root + new state

        # Test actual restoring from cache by hand by replicating what
        # happens in `run_recipe`
        exp1 = Experiment(directory=tmpdir, state_class=EmptyState)
        root1 = exp1.spawn_new_tree(**exp_args)
        assert root1.get().from_cache  # same root
        new_state1 = root1.get().new_state(op)
        assert new_state1.restore()
Пример #2
0
    def test_cache_works(self, tmpdir):

        exp = Experiment(directory=tmpdir, state_class=EmptyState)

        exp_args = {"a": 10.0, "B": "notused"}
        root = exp.spawn_new_tree(**exp_args)

        # In the stochastic version of this, the output of the Op will change
        # if `run` is called again. To make sure we're using the cached nodes,
        # we check to make sure multiple runs yield the same output.
        op = OpRecipe(mul, 0.4, stochastic=True)
        result = op(root)
        out = result.get()
        assert out.restore()

        value = out.c

        # Get the value a second time by re-running through the graph, assert
        # the same
        result2 = op(root)
        out2 = result2.get()
        assert out2.restore()

        assert value == out2.c

        # Remove all cached states, rebuild the experiment, and assert the
        # value changes.
        for f in glob.glob(str(tmpdir / "*")):
            os.remove(f)

        # Now recreate
        exp = Experiment(directory=tmpdir, state_class=EmptyState)

        exp_args = {"a": 10.0, "B": "notused"}
        root = exp.spawn_new_tree(**exp_args)

        result3 = op(root)
        out3 = result3.get()
        assert out3.restore()

        assert value != out3.c
Пример #3
0
    def test_bad_recipe(self, tmpdir):
        # This should fail because run does not return a state!
        class Bad(Recipe):

            def run(self, s):
                return None

        exp = Experiment(directory=tmpdir, state_class=EmptyState)
        exp_args = {"a": 10.0, "B": "notused"}
        root = exp.spawn_new_tree(**exp_args)
        with pytest.raises(RuntimeError):
            Bad()(root).get()
Пример #4
0
    def test_function_exception(self, tmpdir):
        """Test that when the function fails, the relative error gets raised
        upon running the graph (not at graph definition time).
        """
        exp = Experiment(directory=tmpdir, state_class=EmptyState)
        exp_args = {"a": 1, "B": 2}
        root = exp.spawn_new_tree(**exp_args)

        function = Function(lambda s: print("d = {}".format(s.d)))

        s = function(root)
        with pytest.raises(AttributeError):
            exp.run()
Пример #5
0
    def test_spawn_new_tree(self, tmpdir):
        """
        """
        exp = Experiment(directory=tmpdir, state_class=EmptyState)

        # The argument 'c' should be ignored, as it is not set from thew
        # constructor in spawn_new_tree
        exp_args = {"a": "first", "B": "second", "c": "shouldnotpropagate"}
        root = exp.spawn_new_tree(**exp_args)

        assert type(root) == ExperimentStatePromise

        root_state = root.get()
        assert exp.root is root_state
        assert isinstance(root_state, EmptyState)
        assert root_state.a == exp_args["a"]
        assert root_state.B == exp_args["B"]
        assert root_state.c is None
Пример #6
0
    def test_function_safe_op(self, tmpdir):
        """Regardless of whether the op in the function fails or succeeds,
        the state it acts on gets deflated.
        """
        exp = Experiment(directory=tmpdir, state_class=EmptyState)
        exp_args = {"a": 1, "B": 2}
        root = exp.spawn_new_tree(**exp_args)
        exp.run()
        exp = Experiment.restore(directory=tmpdir, state_class=EmptyState)

        assert exp.root.slim_loaded

        badfunction = Function(lambda s: print("d = {}".format(s.d)))
        with pytest.raises(AttributeError):
            s = badfunction._safe_op(exp.root)
        assert exp.root.slim_loaded

        goodfunction = Function(lambda s: print("a = {}".format(s.a)))
        s = goodfunction._safe_op(exp.root)
        assert exp.root.slim_loaded
Пример #7
0
    def test_function(self, tmpdir):
        exp = Experiment(directory=tmpdir, state_class=EmptyState)
        exp_args = {"a": 1, "B": 2}
        root = exp.spawn_new_tree(**exp_args)
        op = OpRecipe(mul, 0.4)
        state1 = op(root)

        assert len(exp.leaves) == 1
        leaf1 = list(exp.leaves.items())[0]

        function = Function(lambda s: print("c = {}".format(s.c)))

        state2 = function(state1)

        # The state should not be modified by the function because functions
        # are non state mutating operations
        assert state2 == state1

        # check that the previous leaf has been replaced by the new leaf
        assert len(exp.leaves) == 1
        leaf2 = list(exp.leaves.items())[0]
        assert leaf2 != leaf1
Пример #8
0
    def test_spawn_new_tree_recipe(self, tmpdir):

        exp = Experiment(directory=tmpdir, state_class=EmptyState)
        exp_args = {"a": 10.0, "B": "notused"}
        root = exp.spawn_new_tree(**exp_args)

        # This recipe sets the non-hashed attribute `c`, so we check that we
        # do state.c = 10 * 1.5
        op = OpRecipe(mul, 1.5)

        result = op(root)

        out = result.get()

        # When we `get` the result, it will be slim-loaded, verify that and
        # restore the output.
        assert out.slim_loaded
        assert out.restore()
        assert not out.slim_loaded

        # Very the Op was applied
        assert out.c == 15.0
Пример #9
0
    def test_tag_filtering(self, tmpdir):
        exp = Experiment(directory=tmpdir, state_class=EmptyState)
        exp_args = {"a": 1.0, "B": 2.0, "c": 3.0}
        root = exp.spawn_new_tree(**exp_args)
        op_add = OpRecipe(add, 1.2)
        with exp.tag("ops"):
            with exp.tag("phase:mul"):
                x1 = OpRecipe(mul, 0.4)(root)
                x2 = OpRecipe(mul, 0.5)(root)
            with exp.tag("phase:add"):
                y1 = op_add(x1)
                y2 = op_add(x2)
        exp.run()
        exp = Experiment.restore(directory=tmpdir, state_class=EmptyState)
        assert len(exp.graph.nodes.filter("op*")) == 4
        assert (
            len(
                exp.graph.nodes.filter("phase:mul")
                | exp.graph.nodes.filter("phase:add")
            )
            == 4
        )
        assert len(exp.graph.nodes.filter("!phase:mul")) == 3
        assert (
            len(
                exp.graph.nodes.filter("ops")
                & exp.graph.nodes.filter("!phase:add")
            )
            == 2
        )

        # Cannot compose other objects with a nodeset
        with pytest.raises(TypeError):
            exp.graph.nodes.filter("phase:mul") | "hi"
        with pytest.raises(TypeError):
            exp.graph.nodes.filter("phase:*") & "!hi"
Пример #10
0
 def test_spawn_new_tree_error(self, tmpdir):
     exp = Experiment(directory=tmpdir, state_class=EmptyState)
     exp_args = {}
     with pytest.raises(KeyError):
         exp.spawn_new_tree(**exp_args)