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

[WIP] Use store_true for bool args #1646

Closed
wants to merge 1 commit into from
Closed

[WIP] Use store_true for bool args #1646

wants to merge 1 commit into from

Conversation

nateraw
Copy link
Contributor

@nateraw nateraw commented Apr 28, 2020

Before submitting

  • Was this discussed/approved via a Github issue? (no need for typos and docs improvements)
  • Did you read the contributor guideline, Pull Request section?
  • Did you make sure to update the docs?
  • Did you write any new necessary tests?
  • If you made a notable change (that affects users), did you update the CHANGELOG?

What does this PR do?

Overview
Fixes #1168

This PR edits pl.Trainer.add_argparse_args to allow users to pass flags instead of key value pairs for bool type arguments with a default of False.

For example, instead of:

python trainer_main.py --fast_dev_run True

You can now do:

python trainer_main.py --fast_dev_run

Notes

  • Could write this up a bit differently to where we only make a single parser.add_argument call, but I felt it started to look messy when I did that.
  • Docs not updated. Please point me in right direction and I'll cover that too.
  • I am completely lost as to why there is a nested function called allowed_type(x) within the loop that gathers the flags. (CC: @alexeykarnachev from git blame)

PR review

Anyone in the community is free to review the PR once the tests have passed.
If we didn't discuss your PR in Github issues there's a high chance it will not be merged.

Did you have fun?

Make sure you had fun coding 🙃

@mergify mergify bot requested a review from a team April 28, 2020 00:19
@alexeykarnachev
Copy link
Contributor

alexeykarnachev commented Apr 28, 2020

I am completely lost as to why there is a nested function called allowed_type(x) within the loop that gathers the flags.

@nateraw I'll try to clarify this point.

We want to automatically assign an appropriate type for the argument (parser.add_argument). So, we check the type hint of a specific Trainer argument and in the simplest case we just pass this type to the parser. Then, when we pass the argument value through the command-line interface, it'll be automatically converted to the thing we need.
And now, imagine, that we have some argument, which has a bool type, but it can be passed to the command-line interface like a string: "True", "true", "false", "no", "yes", and so on. So, in such a case, we can't just put bool type for this argument in parser.add_argument method, because in casting time every string will be converted to True, because bool("False") equals True. It means that our argument type is not really a bool, it is a tricky type that casts "True" to True and "False" to False. That's why the argparser can receive not just primitive types, but functions which determine the casting logic. And that's how the allowed_type(x) has appeared. I would say, that allowed_type(x) is not a function, it's a type.

@@ -613,6 +613,16 @@ def add_argparse_args(cls, parent_parser: ArgumentParser) -> ArgumentParser:
def allowed_type(x):
return bool(parsing.strtobool(x))

# Bool args with default of True parsed as flags not key value pair
Copy link
Contributor

Choose a reason for hiding this comment

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

But don't we add the argument twice to the parser in such a case? One time here, and another one there:
https://github.com/PyTorchLightning/pytorch-lightning/blob/8614074dc3d97ec5b9b3296b297010f60e36e2cb/pytorch_lightning/trainer/trainer.py#L630-L635

I think it could be handled like so:

(the code is non-working sketch)

if arg_types == (bool,) and arg_default is False:
    action = 'store_true'
    default = None
    arg_type = None
else:
   action = None
   default = arg_default
   arg_type = allowed_type
...
parser.add_argument(
    f'--{arg}',
    default=default,
    type=arg_type,
    dest=arg,
    action=action,
    type = type
    help='autogenerated by pl.Trainer'
)
...

So, I think, it could be generalized a little

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice, this is the way I did it originally but ended up just goin with the one I pushed. I'll change it back to something like this. Thank you!

Copy link
Contributor

@williamFalcon williamFalcon Apr 28, 2020

Choose a reason for hiding this comment

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

i removed parsing.strtobool(x) on purpose... this fails on some python versions.

If we're going to use strtobool please keep the implementation i added (which is copy paste from strtobool but that works on any python version

@Borda Borda added the feature Is an improvement or enhancement label Apr 29, 2020
@williamFalcon
Copy link
Contributor

Finishing in #1822

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

Successfully merging this pull request may close these issues.

store_true for bools in the trainer's argparse parser
4 participants