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 ability to specify search path for SNOPT import with env var #338

Merged
merged 17 commits into from
May 1, 2023

Conversation

whophil
Copy link
Contributor

@whophil whophil commented Apr 26, 2023

Purpose

Addresses #337

I am totally open to suggestions on the name of this environment variable. For now it is explicit as possible.

Expected time until merged

Quickly - due to small scope of change, not urgency.

Type of change

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (non-backwards-compatible fix or feature)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no API changes)
  • Documentation update
  • Maintenance update
  • Other (please describe)

Testing

Checklist

  • I have run flake8 and black to make sure the Python code adheres to PEP-8 and is consistently formatted
  • I have formatted the Fortran code with fprettify or C/C++ code with clang-format as applicable
  • I have run unit and regression tests which pass locally with my changes
  • I have added new tests that prove my fix is effective or that my feature works
  • I have added necessary documentation

@whophil whophil requested a review from a team as a code owner April 26, 2023 17:20
@codecov
Copy link

codecov bot commented Apr 26, 2023

Codecov Report

Merging #338 (b408fb4) into main (98a7910) will decrease coverage by 11.53%.
The diff coverage is 95.00%.

@@             Coverage Diff             @@
##             main     #338       +/-   ##
===========================================
- Coverage   83.92%   72.40%   -11.53%     
===========================================
  Files          22       22               
  Lines        3347     3363       +16     
===========================================
- Hits         2809     2435      -374     
- Misses        538      928      +390     
Impacted Files Coverage Δ
pyoptsparse/pySNOPT/pySNOPT.py 16.61% <95.00%> (-73.30%) ⬇️

... and 7 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Contributor

@marcomangano marcomangano left a comment

Choose a reason for hiding this comment

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

Thanks for the PR Phil! I just have two quick comments:

  • I like using a self-explanatory name for the environmental variable, even if long. I am just not convinced about the _NONRELATIVE part, it might not be intuitive for users. What about something along the lines of PYOPTSPARSE_LOAD_COMPILED_SNOPT? Would that be ambiguous? I have no strong opinions on this name myself .
  • Could you update the docs here? Just clarifying the scenario in which this approach is recommended (as you did in Allow snopt module to be loaded non-relatively #337) and a snippet with the updated env variables is enough imho

@whophil
Copy link
Contributor Author

whophil commented Apr 26, 2023

@marcomangano I pushed a change renaming the variable to PYOPTSPARSE_IMPORT_SNOPT_ABSOLUTE, and also added info to docs.

@whophil whophil changed the title Add PYOPTSPARSE_LOAD_SNOPT_NONRELATIVE flag Add PYOPTSPARSE_IMPORT_SNOPT_ABSOLUTE flag Apr 27, 2023
doc/optimizers/SNOPT.rst Outdated Show resolved Hide resolved
doc/optimizers/SNOPT.rst Outdated Show resolved Hide resolved
@whophil
Copy link
Contributor Author

whophil commented Apr 27, 2023

The failing test seems to be related to NSGA segfaults (#340), otherwise this is ready.

@whophil whophil changed the title Add PYOPTSPARSE_IMPORT_SNOPT_ABSOLUTE flag Add ability to specify search path for SNOPT import with env var Apr 28, 2023
@whophil
Copy link
Contributor Author

whophil commented Apr 28, 2023

A clarification on how this behaves -

The original search order for snopt was:

  1. The directory relative to pySNOPT.py

With this change, if you specify a path with PYOPTSPARSE_SNOPT_PATH_PREPEND, the search order for snopt becomes:

  1. The path specified by PYOPTSPARSE_SNOPT_PATH_PREPEND
  2. Standard PYTHONPATH
  3. The directory relative to pySNOPT.py

The second item may be unexpected, so I wanted to point it out.

Copy link
Contributor

@marcomangano marcomangano left a comment

Choose a reason for hiding this comment

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

Thanks for the update. Aside the comment below, I feel your note on the search order should be included in the documentation.

I see how searching through the "original" PYTHONPATH is inevitable with this approach. I don't have anything against it, but I think we need some kind of note and/or warning. I can see how more or less intentionally a user could set an invalid env variable but still end up importing any snopt library already existing on the path. I don't think the logic should change though. Do you have other thoughts @eirikurj

pyoptsparse/pySNOPT/pySNOPT.py Outdated Show resolved Hide resolved
@whophil
Copy link
Contributor Author

whophil commented Apr 28, 2023

@marcomangano there is one other option, which has no hidden behavior. I will explain it in words and wait for your feedback before implementing.

  1. If the env var PYOPTSPARSE_LOAD_SNOPT_FROM exists, prepend PYTHONPATH with that path and import snopt.
  2. Check where snopt was imported from.
  3. If it wasn't imported from the specified path, don't use it! Set snopt = None

There is also the option to not attempt the relative import as a fallback if the absolute import fails. This feels a little more intuitive to me.

Personally, I would prefer an error to be raised if PYOPTSPARSE_LOAD_SNOPT_FROM is specified and snopt cannot be successfully loaded from that path, but that seems to be out of line with the snopt = None approach.

@marcomangano
Copy link
Contributor

1. If the env var `PYOPTSPARSE_LOAD_SNOPT_FROM` exists, prepend `PYTHONPATH` with that path and `import snopt`.

2. Check where `snopt` was imported from.

3. If it wasn't imported from the specified path, don't use it! Set `snopt = None`

I like this approach, it avoids the ambiguous scenarios I mentioned above.

There is also the option to not attempt the relative import as a fallback if the absolute import fails. This feels a little more intuitive to me.

I also agree with this. pyOptSparse is either importing the library specified in the path or dropping the import, no ambiguous fallbacks.

Personally, I would prefer an error to be raised if PYOPTSPARSE_LOAD_SNOPT_FROM is specified and snopt cannot be successfully loaded from that path, but that seems to be out of line with the snopt = None approach.

I think this might be redundant, as we indeed have a check on the correct import here. Maybe we can print a warning for this scenario, but if we end up implementing your latest suggestion I think there is no need for an additional error imho.

marcomangano
marcomangano previously approved these changes Apr 30, 2023
Copy link
Contributor

@marcomangano marcomangano left a comment

Choose a reason for hiding this comment

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

This looks good to me! Just fixed a minor inconsistency in the docs. Maybe @eirikurj has some final comments on this?

@whophil
Copy link
Contributor Author

whophil commented Apr 30, 2023

This looks good to me! Just fixed a minor inconsistency in the docs. Maybe @eirikurj has some final comments on this?

Thanks @marcomangano !

I just pushed one other basic test for _import_snopt_from_path. It doesn't complete the test coverage, but it's better than nothing.

Copy link
Contributor

@eirikurj eirikurj left a comment

Choose a reason for hiding this comment

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

Thanks for your effort on this and the tests. I just have few very minor questions/comments, otherwise it looks good.

doc/optimizers/SNOPT.rst Outdated Show resolved Hide resolved
tests/test_other.py Outdated Show resolved Hide resolved
tests/test_other.py Outdated Show resolved Hide resolved
Copy link
Contributor

@eirikurj eirikurj left a comment

Choose a reason for hiding this comment

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

Changes look good. Not sure, but the U22 image failed a couple of times installing the build deps. The current failure is the #340 issue, which is unrelated, so I am approving.

@eirikurj eirikurj merged commit bf254b9 into mdolab:main May 1, 2023
9 of 12 checks passed
@whophil whophil deleted the feature/snopt-module-load-options branch May 1, 2023 17:45
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

Successfully merging this pull request may close these issues.

None yet

3 participants