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

Overhaul RMG-RMS Python-Julia dependencies & Add tests for many testless Arkane network algorithms #2640

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

Conversation

hwpang
Copy link
Contributor

@hwpang hwpang commented Mar 22, 2024

Motivation or Problem

PythonCall.jl, CondaPkg.jl, and PythonPlot.jl supersede PyCall.jl, Conda.jl, and PyPlot.jl packages. The latter have caused many troubles during RMS installation.

Some key differences between PythonCall and PyCall

  • PythonCall has a compatible JuliaCall package that provide symmetric interface going from Julia to Python and Python to Julia
  • "PythonCall by default never copies mutable objects when converting, but instead directly wraps the mutable object. This means that modifying the converted object modifies the original, and conversion is faster" (See here)

I put together a RMG-RMS twin PR at ReactionMechanismGenerator/ReactionMechanismSimulator.jl#256 to switch to use PythonCall.jl, CondaPkg.jl, and PythonPlot.jl from their old versions PyCall.jl, Conda.jl, and PyPlot.jl.

This PR makes necessary changes on the RMG end to keep the RMG-RMS compatibility.

Moreover, during working on this, I found that many new network algorithms in Arkane are not tested. I have added additional tests for them.

Description of Changes

Some major changes include

  • Use pyjuliacall instead of pyjulia to call Julia modules from Python.
  • Use juliaup to install Julia instead of using the julia binary from conda-forge. I have found that user the latter can cause many issues on the RMG end as it doesn't check package depedencies appropriately. juliaup is Julia's official version manager.
  • Get rid of unnecessary dependencies on pyrms and diffeqpy. We use diffeqpy to get CVODE_BDF and solve but that is unnecessary. Now we get CVODE_BDF from Sundials and solve from SciMLBase. This helps RMG to reduce package dependencies even more.

Testing

A clear and concise description of testing that you've done or plan to do.

Reviewer Tips

Suggestions for verifying that this PR works or other notes for the reviewer.

rmgpy/rmg/reactors.py Outdated Show resolved Hide resolved
@hwpang hwpang changed the title Testing PythonCall compatibility with RMG Overhaul RMG's Julia dependencies Apr 2, 2024
@hwpang hwpang changed the title Overhaul RMG's Julia dependencies Overhaul RMG-RMS Python-Julia dependencies Apr 2, 2024
@hwpang hwpang changed the title Overhaul RMG-RMS Python-Julia dependencies Overhaul RMG-RMS Python-Julia dependencies & Add tests for many testless Arkane explorer algorithms Apr 3, 2024
@hwpang hwpang changed the title Overhaul RMG-RMS Python-Julia dependencies & Add tests for many testless Arkane explorer algorithms Overhaul RMG-RMS Python-Julia dependencies & Add tests for many testless Arkane network algorithms Apr 3, 2024
@JacksonBurns
Copy link
Contributor

@hwpang also consider editing the Dockerfile:

ENV JULIA_CPU_TARGET="x86-64,haswell,skylake,broadwell,znver1,znver2,znver3,cascadelake,icelake-client,cooperlake,generic"

@hwpang
Copy link
Contributor Author

hwpang commented Apr 3, 2024

@hwpang also consider editing the Dockerfile:

ENV JULIA_CPU_TARGET="x86-64,haswell,skylake,broadwell,znver1,znver2,znver3,cascadelake,icelake-client,cooperlake,generic"

It doesn't seem that this can be removed by this PR. From here, it sees that is used to avoid compilation overhead

Copy link

codecov bot commented Apr 5, 2024

Codecov Report

Attention: Patch coverage is 54.54545% with 25 lines in your changes are missing coverage. Please review.

Project coverage is 55.45%. Comparing base (7519944) to head (4bec89e).
Report is 7 commits behind head on main.

❗ Current head 4bec89e differs from pull request most recent head a8b42d1. Consider uploading reports for the commit a8b42d1 to get more accurate results

Files Patch % Lines
rmgpy/pdep/sls.py 22.22% 14 Missing ⚠️
rmgpy/rmg/reactors.py 70.27% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2640      +/-   ##
==========================================
+ Coverage   54.88%   55.45%   +0.57%     
==========================================
  Files         125      125              
  Lines       37025    37057      +32     
==========================================
+ Hits        20321    20551     +230     
+ Misses      16704    16506     -198     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hwpang
Copy link
Contributor Author

hwpang commented Apr 5, 2024

All tests have passed 🥳🥳🥳 @mjohnson541 Could you review before I clean up the commits? @JacksonBurns Let's work out a plan on the merge sequence with your other PRs

Copy link
Contributor

@mjohnson541 mjohnson541 left a comment

Choose a reason for hiding this comment

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

Heroic effort!

Sorry, about the missing pdep algorithm tests, that's my bad.

I have a few questions about how these changes work, but it looks pretty good.

@@ -49,8 +49,8 @@ dependencies:
- conda-forge::rdkit >=2022.09.1

# general-purpose external software tools
- conda-forge::julia=1.9.1
- conda-forge::pyjulia >=0.6
- conda-forge::juliaup
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes sense. What does this mean as far as how we think about julia version?

Copy link
Contributor

Choose a reason for hiding this comment

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

Chiming in with some notes from offline conversation, just to make sure I'm on the same page as well. From my understanding, juliaup installs a Julia binary in the conda environment, but 'hides' it from conda so that that juliaup can manage the version. I think this results in the Julia version being whatever the default provided by juliaup is, which I think is just the latest minor release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can also explicitly manage julia version through commands such as juliaup add 1.9.0. I incline to let the Julia version update whenever we could and avoid sticking to an old version.

path_rms = dirname(dirname(dirname(abspath(__file__))))
from julia.api import Julia

jl = Julia(sysimage=join(path_rms, "rms.so")) if exists(join(path_rms, "rms.so")) else Julia(compiled_modules=False)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we breaking workflows for people that use system images to avoid compilation?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also curious about this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean by using a (global) Julia binary instead of the one come with the conda environment?

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this tool: https://github.com/MichaelHatherly/SystemImageLoader.jl allows adding of system images to juliaup.

This implies we could imagine later using some of these new tools like: https://julialang.github.io/PackageCompiler.jl/dev/index.html to generate a system image with RMS already precompiled and use the other tool to add it to juliaup during installation. The caveat being if you ever want to modify RMS you have to remove that image. However, the process doesn't look particularly difficult anymore. PackageCompiler looks pretty straightforward. Not as sure about the other package.

Copy link
Contributor

@JacksonBurns JacksonBurns left a comment

Choose a reason for hiding this comment

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

You're a wizard! Thanks for taking this on. A number of small-ish comments throughout.

Overall comment - I did a quick search all for python-jl and found nothing, so I think you totally caught them all (thanks!).

@@ -151,8 +151,9 @@ jobs:
- name: Install and link Julia dependencies
timeout-minutes: 120 # this usually takes 20-45 minutes (or hangs for 6+ hours).
run: |
python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()"
julia -e 'using Pkg; Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main")); using ReactionMechanismSimulator'
which julia
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a reminder that we can remove this before merging

Copy link
Contributor Author

@hwpang hwpang Apr 25, 2024

Choose a reason for hiding this comment

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

How do you feel about running juliaup status here in the CI instead to print out the Julia version we are using? Just to make it easier for us to keep track of things.

.github/workflows/CI.yml Show resolved Hide resolved
julia -e 'using Pkg; Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main")); using ReactionMechanismSimulator'
which julia
export JULIA_CONDAPKG_EXE=$CONDA/condabin/mamba
julia -e 'ENV["JULIA_CONDAPKG_BACKEND"] = "Current"; using Pkg; Pkg.add("SciMLBase"); Pkg.add("Sundials"); Pkg.add(Pkg.PackageSpec(name="ReactionMechanismSimulator", url="https://github.com/hwpang/ReactionMechanismSimulator.jl.git", rev="fix_installation")); using ReactionMechanismSimulator'
Copy link
Contributor

Choose a reason for hiding this comment

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

Does RMS not require sundials or SciMLBase on its own? Why do we have to specify them separately?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

RMS does require sundials and SciMLBase. I think it's better to install them to help distinguish the RMS dependency (used in reactors.py) and the general Julia dependency (used in network.py). If I don't install them explicitly here, I can still access them under RMS's dependency, but it makes network.py seem like it depends on RMS, which can be misleading. What do you think?

Dockerfile Outdated Show resolved Hide resolved
documentation/source/users/rmg/releaseNotes.rst Outdated Show resolved Hide resolved
rmgpy/rmg/reactors.py Show resolved Hide resolved
rmgpy/rmg/reactors.py Outdated Show resolved Hide resolved
rmgpy/rmg/reactors.py Outdated Show resolved Hide resolved
rmgpy/rmg/reactors.py Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

An overall comment/question. How can we differentiate to_julia and to_rms in our heads? Having some difficulty understanding from just the code which is required where.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

to_julia handles general types in Julia (think about dict, arrays), and to_rms handles custom types defined by RMS

@hwpang
Copy link
Contributor Author

hwpang commented Apr 25, 2024

@JacksonBurns @mjohnson541 I've addressed most of the comments and have a couple of clarifying questions

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