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

Add _resolve_ flag to instantiate. #2269

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

kpoeppel
Copy link

Motivation

See issue #2268. Passing the whole configuration (e.g. via eval) to an instantiated object is impossible as the resolution breaks due to different top-level of the configuration.
With this addition, special objects are not resolved a second time (of course one resolve has to be called beforehand).

Have you read the Contributing Guidelines on pull #requests?

Yes

Test Plan

A simple test was already added. The default behaviour doesn't change.

Related Issues and PRs

Issue #2268

Add _resolve_ flag to instantiate. This is useful for weakly recursive configurations (e.g. instantiate a logger with all the configuration or configuration yaml-string).
Update the documentation of instantiate for optionally disabling the OmegaConf resolution.
@facebook-github-bot
Copy link
Contributor

Hi @kpoeppel!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@Jasha10 Jasha10 linked an issue Jun 26, 2022 that may be closed by this pull request
Copy link
Collaborator

@Jasha10 Jasha10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR does not address the use-case outlined in this comment. The assertion in the following script should pass:

from hydra.utils import instantiate
from omegaconf import DictConfig, OmegaConf


def train(cfg: DictConfig, num: int):
    return num


cfg = OmegaConf.create(
    """
func:
    _target_: __main__.train
    num: 123
"""
)
x = instantiate(cfg.func, cfg=cfg, _resolve_=False)
assert x == 124

The script instead fails with a TypeError.

Comment on lines 354 to 356
is_resolve = (
(node.get("_resolve_", None) is None and resolve)
or node.get("_resolve_", True))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is tricky -- it would be good to have tests for some nested cases.

_target_: module.Outer
arg:
  _target_: module.Inner
  _resolve_: true
_resolve_: false
_target_: module.Outer
arg:
  _target_: module.Inner
  _resolve_: false
_resolve_: true
_target_: module.Outer
arg:
  _target_: module.Inner
  # _resolve_ true inherited
_resolve_: true
_target_: module.Outer
arg:
  _target_: module.Inner
  # _resolve_ false inherited
_resolve_: false

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply, as of the now pushed commit e586dc7 your code can work with _recursive_=False inside instantiate.

The problem is how to tackle recursion here, as things become self-referential potentially (-> infinite recursion). There are three options.

  1. Demanding _recursive_=False in this code (current state).
  2. Treat kwargs inside instantiate differently for the case _resolve_=False, such that these are excluded from the recursive instantiate. So here the implicit _recursive_=True would only apply to cfg.func and not to cfg.
  3. Introducing another step for resolution (like in the Issue 2268)

What do you think works best?

Copy link
Collaborator

@Jasha10 Jasha10 Nov 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I too should apologize for my late response.

The problem is how to tackle recursion here, as things become self-referential potentially (-> infinite recursion).

I am confused. Could you give me an example where infinite recursion would come up? Is this a new problem introduced by this PR, or would the infinite recursion happen even without this PR?

@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 5, 2022
@Jasha10
Copy link
Collaborator

Jasha10 commented Nov 6, 2022

I've just realized that this PR is quite similar to what is discussed in issue #1758, specifically Omry's suggestion from this comment.

@kpoeppel
Copy link
Author

kpoeppel commented Nov 6, 2022

Do you think this can be merged now from a software architecture point of view?
I still need to fix the failing tests, maybe also need some help because of their generic nested structure.

@Jasha10
Copy link
Collaborator

Jasha10 commented Nov 6, 2022

Do you think this can be merged now from a software architecture point of view?

Not sure. We might need to move the OmegaConf.resolve calls from the instantiate function into a more deeply nested function (such as instantiate_node).

This PR needs more tests before it can be merged: there's only one test for _resolve_ currently, which means edge-cases are not tested.

My advice is to use test-driven development:

  • start with a clean slate of tests that pass
  • add one failing test
  • modify instantiate until all the tests (including the new test) pass
  • add another failing test
  • modify instantiate until all the tests (including the new test) pass
  • ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
3 participants