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 xbitinfo #20116

Merged
merged 8 commits into from
Aug 29, 2022
Merged

Add xbitinfo #20116

merged 8 commits into from
Aug 29, 2022

Conversation

rsignell-usgs
Copy link
Contributor

@rsignell-usgs rsignell-usgs commented Aug 19, 2022

Checklist

  • Title of this PR is meaningful: e.g. "Adding my_nifty_package", not "updated meta.yaml".
  • License file is packaged (see here for an example).
  • Source is from official source.
  • Package does not vendor other packages. (If a package uses the source of another package, they should be separate packages or the licenses of all packages need to be packaged).
  • If static libraries are linked in, the license of the static library is packaged.
  • Package does not ship static libraries. If static libraries are needed, follow CFEP-18.
  • Build number is 0.
  • A tarball (url) rather than a repo (e.g. git_url) is used in your recipe (see here for more details).
  • GitHub users listed in the maintainer section have posted a comment confirming they are willing to be listed there.
  • When in trouble, please check our knowledge base documentation before pinging a team.

@conda-forge-linter
Copy link

Hi! This is the friendly automated conda-forge-linting service.

I just wanted to let you know that I linted all conda-recipes in your PR (recipes/xbitinfo) and found it was in an excellent condition.

@rsignell-usgs
Copy link
Contributor Author

@observingClouds, I hope you are okay being a maintainer here!

@observingClouds
Copy link

Thank you so much @rsignell-usgs to put this together! I'm happy to be maintainer.

@ocefpaf
Copy link
Member

ocefpaf commented Aug 22, 2022

At the moment this is failing with:

import: 'xbitinfo'
    import xbitinfo
  File "/opt/conda/conda-bld/xbitinfo_1661171801494/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.10/site-packages/xbitinfo/__init__.py", line 4, in <module>
    from .bitround import jl_bitround, xr_bitround
  File "/opt/conda/conda-bld/xbitinfo_1661171801494/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.10/site-packages/xbitinfo/bitround.py", line 4, in <module>
    from .xbitinfo import _jl_bitround, get_keepbits
  File "/opt/conda/conda-bld/xbitinfo_1661171801494/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.10/site-packages/xbitinfo/xbitinfo.py", line 12, in <module>
    jl = Julia(compiled_modules=False, debug=False)
  File "/opt/conda/conda-bld/xbitinfo_1661171801494/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.10/site-packages/julia/core.py", line 513, in __init__
    self._call("const PyCall = Base.require({0})".format(PYCALL_PKGID))
  File "/opt/conda/conda-bld/xbitinfo_1661171801494/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.10/site-packages/julia/core.py", line 549, in _call
    self.check_exception(src)
  File "/opt/conda/conda-bld/xbitinfo_1661171801494/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.10/site-packages/julia/core.py", line 603, in check_exception
    raise JuliaError(u'Exception \'{}\' occurred while calling julia code:\n{}'
julia.core.JuliaError: Exception 'ArgumentError' occurred while calling julia code:
const PyCall = Base.require(Base.PkgId(Base.UUID("438e738f-606a-5dbb-bf0a-cddfbfd45ab0"), "PyCall"))
Tests failed for xbitinfo-0.0.2-py_0.tar.bz2 - moving package to /opt/conda/conda-bld/broken

I don't know enough Julia to debug this. @observingClouds do you have any idea of what may be happening here? A Julia versions mismatch maybe?

@ocefpaf
Copy link
Member

ocefpaf commented Aug 22, 2022

@ngam and @isuruf I'm quite lost when mixing Julia and Python. Do you have any advice here that I should follow?

@observingClouds
Copy link

@ocefpaf , it looks to me that we might not call the PostInstallCommand which ensures that the Julia package dependencies are getting installed. PyCall is one of the Julia packages that needs to be installed with the Julia package manager. Maybe there is a way to install those with conda as well?

@ocefpaf
Copy link
Member

ocefpaf commented Aug 22, 2022

Maybe there is a way to install those with conda as well?

I don't think we have pycall. The number of julia packages in conda-forge is quite small. Julia has been moving target for a while and we left it on ice. We should probably revisit this now that Julia is more stable.

The PySR package also wraps a Julia module and this is how they do it: https://github.com/MilesCranmer/PySR/blob/master/pysr/julia_helpers.py

It is the most successful way of packaging Python-Julia wrappers at the moment. Maybe it is worth taking a look on what they do and see if we can port it to xbitinfo.

@ngam
Copy link
Contributor

ngam commented Aug 22, 2022

So essentially, this package is requesting not only julia itself be available (which we have) but also julia packages be installed and available upon startup (hence pip check is failing). We cannot quite do that yet because of complications and we are not sure what the best way forward is anyway...

A potential solution for you is to add a step for the user to initiate the package with something like module.install() like the linked pysr. Otherwise, we will have to think more deeply about how we want to mix the two packaging ecosystems. It is not straightforward unfortunately...

@ngam
Copy link
Contributor

ngam commented Aug 22, 2022

This is why this is failing: https://github.com/observingClouds/xbitinfo/blob/02c22c39d8a630286c97f28c265b319a3c3744c7/setup.py#L11

You're essentially trying to install these julia packages as part of the setup (does postinstall get triggered right when someone imports the package?):

julia_install_command = "julia install_julia_packages.jl"


class PostDevelopCommand(develop):
    """Post-installation for development mode."""

    def run(self):
        develop.run(self)
        os.system(julia_install_command)


class PostInstallCommand(install):
    """Post-installation for installation mode."""

    def run(self):
        install.run(self)
        os.system(julia_install_command)

@ocefpaf
Copy link
Member

ocefpaf commented Aug 22, 2022

A potential solution for you is to add a step for the user to initiate the package with something like module.install() like the linked pysr.

I believe this is the best we can do. But I thought that the current setup should work regardless :-/

@ngam
Copy link
Contributor

ngam commented Aug 23, 2022

But I thought that the current setup should work regardless :-/

I thought the same actually! Until we hit that roadblock in pysr-feedstock in conda-forge/pysr-feedstock#41. I am not really sure why it fails exactly. I will try to look more into it. But mixing the two packaging systems is pretty difficult imo conda-forge/julia-feedstock#14

@ocefpaf
Copy link
Member

ocefpaf commented Aug 23, 2022

Until we hit that roadblock in pysr-feedstock in conda-forge/pysr-feedstock#41.

Thanks! Glad to know we are not the only ones suffering from this.

@observingClouds are you willing to try the pysr approach? We can do that as a patch here first, see if that works, and then sending upstream.

@rsignell-usgs
Copy link
Contributor Author

Or @aaronspring?

@observingClouds
Copy link

Thanks @rsignell-usgs and @ocefpaf for all the research and interest in making packaging of xbitinfo possible. The current pysr-approach reminds me of a draft we had in the first days of developing xbitinfo. It was way less sophisticated and was called with every import of the module. We switched to the PostInstallCommand because this is called automatically when using setuptools to install the package.

I can try implementing pysr-approach (thanks @ngam for figuring this out). It will take me some time though. I'm happy for any further contributions.

@mkitti
Copy link
Contributor

mkitti commented Aug 27, 2022

Umm, so why not do the obvious thing? Let's package the Julia packages within conda-forge.

@mkitti
Copy link
Contributor

mkitti commented Aug 27, 2022

Here's a strategy we could use to bootstrap this. We're going to create a fake local depot containing all the packages we need. Then we're going to copy the parts we are interested into xbitinfo_depot.

using Pkg

# Create a temporary directory and activate it as the current environment
tmpdir = mktempdir(; cleanup=false)
cd(tmpdir)

# Clear the depots, and create a fresh fake depot
empty!(DEPOT_PATH)
fakedepot = joinpath(tmpdir, "fakedepot")
push!(DEPOT_PATH, fakedepot)

# Create a depot we are going to package
mkdir("xbitinfo_depot")
xbitinfo_env = joinpath("xbitinfo_depot", "environments", "xbitinfo")
mkpath(xbitinfo_env)
Pkg.activate(xbitinfo_env)

# Add the packages of interest
Pkg.add("PyCall")
Pkg.add("BitInformation")
Pkg.add("StatsBase")

# Capture the packages and artifacts directory
mv(joinpath(fakedepot, "packages"), joinpath("xbitinfo_depot", "packages"))
 # Including the artifacts might make the package platform specific, otherwise someone would still need to do "Pkg.instantiate"
mv(joinpath(fakedepot, "artifacts"), joinpath("xbitinfo_depot", "artifacts"))

Now "xbitinfo_depot" should contain just the "packages", "environments" and maybe "artifacts" directory. Package the "xbitinfo_depot" directory into conda tarball.

In pre-link.sh or any of the scripts, append a line to startup.jl to add "xbitinfo_depot" to the list of depots.

$ mkdir -p $CONDA_PREFIX/share/julia/config
$ echo "push!(DEPOT_PATH, \"/path/to/xbitinfo_depot\")" >> $CONDA_PREFIX/share/julia/config/startup.jl

Alternatively, we could further modify $JULIA_DEPOT_PATH in activate.sh:

export JULIA_DEPOT_PATH="$JULIA_DEPOT_PATH:/path/to/xbitinfo_depot"

What should happen now is that Julia will look into xbitinfo_depot for packages. The following should then work.

julia> using Pkg

julia> Pkg.activate("xbitinfo"; shared=true) # pkg"activate @xbitinfo"
  Activating project at `/tmp/jl_FA0ezT/xbitinfo_depot/environments/xbitinfo`

julia> using PyCall, StatsBase, BitInformation
[ Info: Precompiling PyCall [438e738f-606a-5dbb-bf0a-cddfbfd45ab0]
[ Info: Precompiling StatsBase [2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91]
[ Info: Precompiling BitInformation [de688a37-743e-4ac2-a6f0-bd62414d1aa7]

julia> 

@ngam where should xbitinfo_depot go so that it will be packaged?
@MilesCranmer, you may be interested in trying this as well

- setuptools-scm
- setuptools_scm_git_archive
- pyjulia >=0.5.7
- julia
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- julia

(Already comes with pyjulia)

Copy link
Member

Choose a reason for hiding this comment

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

We need this so the conda-forge bot can apply the proper pinnings. In a way, Julia is a direct dependency and all direct dependencies must be specified.

run:
- python >=3.8
- xarray
- julia
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- julia


about:
home: https://github.com/observingClouds/xbitinfo
summary: Retrieve information content and compress accordingly.
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems way too generic a summary

Copy link
Member

Choose a reason for hiding this comment

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

Please raise an issue upstream about this: https://github.com/observingClouds/xbitinfo/blob/main/setup.py#L73

The package here only reflects upstream metadata.

commands:
- pip check
requires:
- pip
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably want to add a test that you can import and run your package, since PyJulia+conda can be a bit finicky.

@MilesCranmer
Copy link
Contributor

@observingClouds @ngam @mkitti if interested, maybe we could work together on a parent Python package that basically has the contents of this file: https://github.com/MilesCranmer/PySR/blob/master/pysr/julia_helpers.py, but for an arbitrary Julia dependency? Then both of our packages could depend on it, rather than PySR and your package hosting that helper code internally.

@mkitti
Copy link
Contributor

mkitti commented Aug 28, 2022

@MilesCranmer, we need to address the issue of how conda-forge will distribute Julia packages directly preferably without having the user manually call install(). The code I posted above gets us slightly closer to this.

That said, it would be good to abstract out the reusable parts of your code.

@ngam
Copy link
Contributor

ngam commented Aug 28, 2022

@ngam where should xbitinfo_depot go so that it will be packaged?

Anything in $PREFIX will be packaged, e.g. $PREFIX/bin, $PREFIX/share, $PRERIX/lib, etc. and my personal preference would be to tuck everything under the preassigned depot in share (the hierarchical approach you came up is powerful for this, I think).

@observingClouds @ngam @mkitti if interested, maybe we could work together on a parent Python package that basically has the contents of this file

Yes, this is a good idea!

The main two issues we need to think about are:

  1. We ought to have stronger pins if we are going to preinstall stuff into the user's env. This is relatively trivial and the user can obviously update/change it, but our priority is to build something that's known to work, pin it altogether, and then package it. Part of our thinking should be an easy mechanism to make this painless. This builds on the approach above where a specific set of packages is installed, and we just have to make that clearer and more transparent (i.e. not leave it up to Pkg to give us what it thinks is best)
  2. I am not too familiar with how Pkg actually packages stuff --- how similar are the artifacts to ones we produce at conda-forge? At a first glance, they look similar except with weird numeric hashes (e.g. ~/.julia/artifacts/6a1f4e0528d14a4dd762db3040e0d47755dae679/lib/libLLVMExtra-13.dylib, ~/.julia/packages/FiniteDiff/zdZSa/src/, ~/.julia/compiled/v1.8/Sundials/j8Ppj_N7P3f.ji etc.). Hence, we need to either alter how it behaves or we need to essentially figure out a place to tuck these things in an orderly manner in our packaging, praying they don't interfere with the regular conda-forge things in $CONDA_PREFIX/lib, etc.

@ngam
Copy link
Contributor

ngam commented Aug 28, 2022

Let's try something along #20116 (comment) in conda-forge/pysr-feedstock#41 or a new PR

@ngam
Copy link
Contributor

ngam commented Aug 28, 2022

Anything in $PREFIX will be packaged, e.g. $PREFIX/bin, $PREFIX/share, $PRERIX/lib, etc.

But it may make most sense to actually try to house the bits and pieces into their respective directories

@ngam
Copy link
Contributor

ngam commented Aug 28, 2022

What is really needed? For example, is stuff like this needed?


DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/Optim/ocQqB/test/general/types.jl.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/LLVMExtra_jll/RuRRc/src/wrappers/aarch64-linux-gnu-cxx11-llvm_version+14.asserts.jl.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/Parsers/34hDN/benchmarks/scratch.jl.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/SymbolicRegression/GUikw/example.jl.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/SymbolicUtils/qulQp/page/_layout/style.html.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/OrderedCollections/PRayh/License.md.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/PyCall/ygXW2/src/io.jl.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/StructArrays/w2GaP/docs/src/advanced.md.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/ThreadsX/7c2uJ/benchmark/bench_foreach_seq_double.jl.  Including it as-is.
DEBUG:conda_build.noarch_python:Don't know how to handle file: share/julia/packages/Adapt/LAQOx/src/wrappers.jl.  Including it as-is.
Fixing permissions
Packaged license file/s.
INFO :: Time taken to mark (prefix)
        0 replacements in 0 files was 5.27 seconds
Files containing CONDA_PREFIX
-----------------------------
share/julia/compiled/v1.8/AbstractFFTs/Di3HZ_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/AbstractTrees/tEX7J_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/Adapt/rUIgN_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ArgCheck/P66Js_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ArrayInterface/7bROb_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ArrayInterfaceCore/H3nJN_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ArrayInterfaceStaticArrays/J1uJU_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ArrayInterfaceStaticArraysCore/XnXZW_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/AutoHashEquals/DS6ss_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/BangBang/Ovsha_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/Baselet/J6WYP_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/Bijections/QtmEu_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/CEnum/0gyUJ_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ChainRules/AzGmQ_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ChainRulesCore/G6ax7_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ChangesOfVariables/wqbay_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/ClusterManagers/2gedf_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/Combinatorics/AwRuT_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/CommonSubexpressions/VMTKN_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/Compat/GSFWK_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/CompilerSupportLibraries_jll/iCwSB_Qjuwo.ji (binary): Patching
share/julia/compiled/v1.8/CompositionsBase/KqDTx_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/Conda/WZE3U_zgN8s.ji (binary): Patching
share/julia/compiled/v1.8/ConstructionBase/sBbW6_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DataAPI/3a8mN_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DataStructures/xKiwJ_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DataValueInterfaces/9Lpkp_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DefineSingletons/YTrQa_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DiffResults/vlfPe_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DiffRules/x2ZNk_XsOPX.ji (binary): Patching
share/julia/compiled/v1.8/DocStringExtens

follow more here conda-forge/pysr-feedstock#43

@mkitti
Copy link
Contributor

mkitti commented Aug 29, 2022

What is really needed? For example, is stuff like this needed?\n\n

packages and artifacts

@ngam
Copy link
Contributor

ngam commented Aug 29, 2022

What is really needed? For example, is stuff like this needed?\n\n

packages and artifacts

Okay, sounds good. Trying that in pysr. We can also implement this in a more systematic way, to have a nice utility that does that via something like {{ JULIA }} install or something, but let's see if we first get it to work. We are definitely packaging the stuff now, but it doesn't seem to be linked correctly to julia/pysr, so we will need some time to troubleshoot

recipes/xbitinfo/install_julia.patch Show resolved Hide resolved
+from ._version import __version__
+
+
+def install(julia_project=None, quiet=False): # pragma: no cover
Copy link
Member

Choose a reason for hiding this comment

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

@observingClouds the changes here are a copy from the pysr approach to install the juilia dependencies.

recipes/xbitinfo/install_julia.patch Outdated Show resolved Hide resolved
recipes/xbitinfo/install_julia.patch Outdated Show resolved Hide resolved
@ocefpaf
Copy link
Member

ocefpaf commented Aug 29, 2022

@observingClouds and @rsignell-usgs Linux is passing, Windows won't pass b/c we don't have Julia for that platform yet, and I have no idea how to fix macOS. Still, this is kind of a win b/c this PR installs a working xbitinfo!

@rsignell-usgs
Copy link
Contributor Author

rsignell-usgs commented Aug 29, 2022

I only care about Linux anyway -- the primary use case is JupyterHubs with conda-store!

@ocefpaf
Copy link
Member

ocefpaf commented Aug 29, 2022

OK. Let's bag what we have and watch the Julia+conda-forge space for future improvements. Thanks @ngam for all the pointers!

@ocefpaf ocefpaf merged commit ee85448 into conda-forge:main Aug 29, 2022
@ngam
Copy link
Contributor

ngam commented Aug 29, 2022

OK. Let's bag what we have and watch the Julia+conda-forge space for future improvements. Thanks @ngam for all the pointers!

Feel free to tag me in the feedstock and keep us updated on what you come up with.

@ocefpaf
Copy link
Member

ocefpaf commented Aug 30, 2022

Feel free to tag me in the feedstock and keep us updated on what you come up with.

Will do but we'll probably follow your lead on the 'depot' attempt.

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

Successfully merging this pull request may close these issues.

7 participants