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

Improve version checking #999

Closed

Conversation

ProGamerGov
Copy link
Contributor

@ProGamerGov ProGamerGov commented Jul 27, 2022

Without the packaging library, statements like: "1.8.0" > "1.10.0" will be equal to True, despite v1.10 being a later version that v1.8.0.

The packaging library will in some cases not be already installed on a user's device, so I've also added it the setup.py file. It's one of the core libraries from the Python Packaging Authority, but it's not included with the base Python installation: https://packaging.python.org/en/latest/key_projects/#pypa-projects

This wasn't an issue in #940 as one the libraries in dev install has packaging as a dependency. So, there's no error when the tests are using the packaging library.

@NarineK
Copy link
Contributor

NarineK commented Jul 28, 2022

@ProGamerGov if you rebase from master #1000 will hopefully fix failing conda issue

@ProGamerGov
Copy link
Contributor Author

ProGamerGov commented Jul 28, 2022

@NarineK It worked on this PR, but I tried it on #985 and it's still running after 3 and half hours.

Edit: It finally passed after just under 4 hours.

@NarineK
Copy link
Contributor

NarineK commented Aug 2, 2022

@ProGamerGov, would it be possible to use something like this:

def versiontuple(v):
    return tuple(map(int, (v.split("."))))

Especially because pytorch's versioning is non-complicated and follows the same pattern.
We usually avoid adding new dependancies to Captum if there is another possible solution without additional dependancies. I understand the advantage of package over tuple comparison but in this case pytorch's versioning is pretty straightforward and non-complex.

https://stackoverflow.com/questions/11887762/how-do-i-compare-version-numbers-in-python

@ProGamerGov
Copy link
Contributor Author

ProGamerGov commented Aug 2, 2022

@NarineK That solution fails for nightly builds:

def versiontuple(v):
    return tuple(map(int, (v.split("."))))

output = versiontuple("1.12.0.dev20201109")
print(output)
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

[<ipython-input-2-32fcc066bf69>](https://localhost:8080/#) in <module>()
      4 
      5 
----> 6 output = versiontuple("1.12.0.dev20201109")
      7 print(output)

[<ipython-input-2-32fcc066bf69>](https://localhost:8080/#) in versiontuple(v)
      1 def versiontuple(v):
----> 2     return tuple(map(int, (v.split("."))))
      3 
      4 
      5 

ValueError: invalid literal for int() with base 10: 'dev20201109'

Though I suppose we could find a way to make it work. Are the other PyTorch libraries like Torchtext using the same versioning pattern?

The packaging library is also already essentially a package dependency of Captum as it is installed as a dependency during the dev install, which is why I'm suggesting it.

Edit:

This might work for PyTorch versions (and hopefully other PyTorch library versions as well):

from typing import Tuple

def parse_version(v: str) -> Tuple[int, int, int]:
    """
    Parse version strings into tuples for comparison.
    """
    v = v.split(".")
    v = [n for n in v if n.isdigit()]
    v += ([0] * (3 - len(v)))
    assert len(v) == 3
    return tuple(map(int, v))

output = parse_version("1.12.0.dev20201109")
print(output)

@ProGamerGov
Copy link
Contributor Author

ProGamerGov commented Aug 2, 2022

@NarineK Is captum/_utils/common.py where we'd add the version parsing function?

from typing import Tuple, Optional

def _parse_version(v: str, length: Optional[int] = 3) -> Tuple[int, int, int]:
    """
    Parse version strings into tuples for comparison.
    
    Versions should be in the form of "<major>.<minor>.<patch>", "<major>.<minor>",
    or "<major>". The "dev", "post" and other letter portions of the given version will
    be ignored.
    
    Args:

        v (str): A version string.
        length (int, optional): The expected length of the output tuple. If the output
            is less than the expected length, then it will be padded with 0 values. Set
            to None for no padding or length checks.
            Default: 3

    Returns:
        version_tuple (tuple of int): A tuple of 3 integer values to use for version
            comparison.
    """
    v = [n for n in v.split(".") if n.isdigit()]
    if length is not None:
        v += ([0] * (length - len(v)))
        assert len(v) == length
    return tuple(map(int, v))

@ProGamerGov
Copy link
Contributor Author

@NarineK I've implemented the _parse_version function and supporting tests.

@NarineK
Copy link
Contributor

NarineK commented Aug 14, 2022

@ProGamerGov, thank you for making the changes. I was looking into the dependency graph of the libs and I noticed that mathplotlib already depends on packaging if that's the right packaging library that I'm looking into.

Is there need to add it here ? We already have the dependency in the non-dev setting as well ?

install_requires=["matplotlib", "numpy", "packaging", "torch>=1.6"],

Screen Shot 2022-08-13 at 11 56 30 PM

https://github.com/matplotlib/matplotlib/blob/bfec1db0d595ccd1e14cccc0473a50a90ce26a8a/lib/matplotlib/testing/decorators.py#L12

@ProGamerGov
Copy link
Contributor Author

@NarineK I just tested installing Captum & Matplotlib, and neither installed the packaging library. Its listed in Matplotlib's setup.py, but not their setupext.py (which I think is used for the general user version of the package). They also use it for testing and some of the optional modules it looks like: https://github.com/matplotlib/matplotlib/search?p=1&q=packaging

captum/_utils/common.py Outdated Show resolved Hide resolved
@NarineK
Copy link
Contributor

NarineK commented Aug 15, 2022

@NarineK I just tested installing Captum & Matplotlib, and neither installed the packaging library. Its listed in Matplotlib's setup.py, but not their setupext.py (which I think is used for the general user version of the package). They also use it for testing and some of the optional modules it looks like: https://github.com/matplotlib/matplotlib/search?p=1&q=packaging

Thank you for checking @ProGamerGov, makes sense! I added a question related to the _parse_version function ?

@ProGamerGov
Copy link
Contributor Author

ProGamerGov commented Aug 15, 2022

@NarineK I've answered your question! The packaging library is downloaded as a dependency in the Captum dev install, but I'm not sure which package uses it as a dependency. So, we only need the _parse_version function for non test related code

Copy link
Contributor

@NarineK NarineK left a comment

Choose a reason for hiding this comment

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

Thank you very much for working on this PR, @ProGamerGov!

@facebook-github-bot
Copy link
Contributor

@NarineK has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

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

Successfully merging this pull request may close these issues.

None yet

3 participants