Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional block cannot find variable in higher level blocks #10711

Closed
ktlichkid opened this issue May 16, 2018 · 2 comments
Closed

Conditional block cannot find variable in higher level blocks #10711

ktlichkid opened this issue May 16, 2018 · 2 comments
Assignees

Comments

@ktlichkid
Copy link

Conditional block will automatically try to find the variables in its parent blocks. However, if there are nested blocks, some variables may reside in its parent's parent block. In that case, the conditional block will not be able to find them and cause an error.

Here is a minimal environment to reproduce the issue:

import unittest
import contextlib

import paddle.fluid.core as core
import paddle.fluid.layers as layers
import paddle.fluid.framework as framework
from paddle.fluid.executor import Executor
from paddle.fluid.framework import default_startup_program

class TestHelper(object):
    def __init__(self):
        self._counter = layers.zeros(shape=[1], dtype='int64')
        self._max_len = layers.fill_constant(
            shape=[1], dtype='int64', value=10)
        self._cond = layers.less_than(
            x=self._counter,
            y=layers.fill_constant(
                shape=[1], dtype='int64', value=10))
        self._while_op = layers.While(self._cond)

    @contextlib.contextmanager
    def block(self):
        with self._while_op.block():
            yield
            # A nested block structure to reproduce the issue. 
            # Variable fill_constant cannot be found in parent block, 
            # but could be found in parent's parent block.
            # Conditional block cannot handle this and will raise an error.
            with layers.Switch() as switch:
                with switch.case(self._cond):
                    layers.increment(x=self._counter, value=1.0, in_place=True)
                    layers.less_than(
                        x=self._counter, y=self._max_len, cond=self._cond)


class TestNested(unittest.TestCase):
    def setUp(self):
        helper = TestHelper()
        var = layers.fill_constant(
                shape=[1], dtype='int64', value=7)
        with helper.block():
            layers.Print(var,
                message="The test is to print this var each step")

    def testNested(self):
        cpu = core.CPUPlace()
        exe = Executor(cpu)
        exe.run(default_startup_program())
        exe.run(framework.default_main_program())


if __name__ == '__main__':
    unittest.main()
@gongweibao gongweibao self-assigned this May 17, 2018
@pkuyym
Copy link
Contributor

pkuyym commented May 17, 2018

We have figured out where the problem is, in conditional block, currently we only look up vars in one upper level block which means parent block, however in the above example, some vars are defined in two upper level block which means parent block of parent block. Please refer to the following code: https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/fluid/layers/control_flow.py#L1099-L1102

@pkuyym
Copy link
Contributor

pkuyym commented May 17, 2018

A potential fix would be that we can look up the vars in recursive way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants