Skip to content

Commit

Permalink
let's try pysr's approach
Browse files Browse the repository at this point in the history
  • Loading branch information
ocefpaf committed Aug 24, 2022
1 parent 368daf7 commit 930c9f7
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 1 deletion.
243 changes: 243 additions & 0 deletions recipes/xbitinfo/install_julia.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
diff --color -Naur xbitinfo-0.0.2.orig/setup.py xbitinfo-0.0.2/setup.py
--- xbitinfo-0.0.2.orig/setup.py 2022-07-11 17:37:19.000000000 -0300
+++ xbitinfo-0.0.2/setup.py 2022-08-24 16:19:18.403080813 -0300
@@ -5,27 +5,6 @@
import os

from setuptools import find_packages, setup
-from setuptools.command.develop import develop
-from setuptools.command.install import install
-
-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)
-

with open("README.md") as readme_file:
readme = readme_file.read()
@@ -66,10 +45,6 @@
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
- cmdclass={
- "develop": PostDevelopCommand,
- "install": PostInstallCommand,
- },
description="Retrieve information content and compress accordingly.",
install_requires=requirements,
license="MIT license",
diff --color -Naur xbitinfo-0.0.2.orig/xbitinfo/__init__.py xbitinfo-0.0.2/xbitinfo/__init__.py
--- xbitinfo-0.0.2.orig/xbitinfo/__init__.py 2022-07-11 17:37:19.000000000 -0300
+++ xbitinfo-0.0.2/xbitinfo/__init__.py 2022-08-24 18:17:34.837784315 -0300
@@ -1,7 +1,9 @@
"""Top-level package for xbitinfo."""

from ._version import __version__
-from .bitround import jl_bitround, xr_bitround
-from .graphics import plot_bitinformation, plot_distribution
+from .julia_helpers import install
+
+# from .bitround import jl_bitround, xr_bitround
+# from .graphics import plot_bitinformation, plot_distribution
from .save_compressed import get_compress_encoding_nc, get_compress_encoding_zarr
-from .xbitinfo import get_bitinformation, get_keepbits, get_prefect_flow
+# from .xbitinfo import get_bitinformation, get_keepbits, get_prefect_flow
diff --color -Naur xbitinfo-0.0.2.orig/xbitinfo/julia_helpers.py xbitinfo-0.0.2/xbitinfo/julia_helpers.py
--- xbitinfo-0.0.2.orig/xbitinfo/julia_helpers.py 1969-12-31 21:00:00.000000000 -0300
+++ xbitinfo-0.0.2/xbitinfo/julia_helpers.py 2022-08-24 16:54:22.218317956 -0300
@@ -0,0 +1,123 @@
+"""Functions for initializing the Julia environment and installing deps."""
+import os
+import warnings
+from pathlib import Path
+from ._version import __version__
+
+def install(julia_project=None, quiet=False): # pragma: no cover
+ """
+ Install PyCall.jl and all required dependencies for BitInformation.jl.
+
+ Also updates the local Julia registry.
+ """
+ import julia
+
+ julia.install(quiet=quiet)
+
+ julia_project, is_shared = _get_julia_project(julia_project)
+
+ Main = init_julia()
+ Main.eval("using Pkg")
+
+ io = "devnull" if quiet else "stderr"
+ io_arg = f"io={io}" if is_julia_version_greater_eq(Main, "1.6") else ""
+
+ # Can't pass IO to Julia call as it evaluates to PyObject, so just directly
+ # use Main.eval:
+ Main.eval(
+ f'Pkg.activate("{_escape_filename(julia_project)}", shared = Bool({int(is_shared)}), {io_arg})'
+ )
+ if is_shared:
+ _add_deps_to_julia_project(Main, io_arg)
+
+ Main.eval(f"Pkg.instantiate({io_arg})")
+ Main.eval(f"Pkg.precompile({io_arg})")
+ if not quiet:
+ warnings.warn(
+ "It is recommended to restart Python after installing xbitinfo's dependencies,"
+ " so that the Julia environment is properly initialized."
+ )
+
+
+def import_error_string(julia_project=None):
+ s = """
+ Required dependencies are not installed or built. Run the following code in the Python REPL:
+
+ >>> import xbitinfo
+ >>> xbitinfo.install()
+ """
+
+ if julia_project is not None:
+ s += f"""
+ Tried to activate project {julia_project} but failed."""
+
+ return s
+
+
+def _get_julia_project(julia_project):
+ if julia_project is None:
+ is_shared = True
+ julia_project = f"xbitinfo-{__version__}"
+ else:
+ is_shared = False
+ julia_project = Path(julia_project)
+ return julia_project, is_shared
+
+
+def is_julia_version_greater_eq(Main, version="1.6"):
+ """Check if Julia version is greater than specified version."""
+ return Main.eval(f'VERSION >= v"{version}"')
+
+
+def init_julia():
+ """Initialize julia binary, turning off compiled modules if needed."""
+ from julia.core import JuliaInfo, UnsupportedPythonError
+
+ try:
+ info = JuliaInfo.load(julia="julia")
+ except FileNotFoundError:
+ env_path = os.environ["PATH"]
+ raise FileNotFoundError(
+ f"Julia is not installed in your PATH. Please install Julia and add it to your PATH.\n\nCurrent PATH: {env_path}",
+ )
+
+ if not info.is_pycall_built():
+ raise ImportError(import_error_string())
+
+ Main = None
+ try:
+ from julia import Main as _Main
+
+ Main = _Main
+ except UnsupportedPythonError:
+ # Static python binary, so we turn off pre-compiled modules.
+ from julia.core import Julia
+
+ jl = Julia(compiled_modules=False)
+ from julia import Main as _Main
+
+ Main = _Main
+
+ return Main
+
+
+def _add_deps_to_julia_project(Main, io_arg):
+ Main.spec = Main.PackageSpec(
+ name="BitInformation",
+ url="https://github.com/milankl/BitInformation.jl",
+ rev="v0.6.0",
+ )
+ Main.eval(f"Pkg.add(spec, {io_arg})")
+ Main.clustermanagers_spec = Main.PackageSpec(
+ name="StatsBase",
+ url="https://github.com/JuliaStats/StatsBase.jl",
+ rev="v0.33.21",
+ )
+ Main.eval(f"Pkg.add(clustermanagers_spec, {io_arg})")
+
+
+def _escape_filename(filename):
+ """Turns a file into a string representation with correctly escaped backslashes"""
+ str_repr = str(filename)
+ str_repr = str_repr.replace("\\", "\\\\")
+ return str_repr
diff --color -Naur xbitinfo-0.0.2.orig/xbitinfo/xbitinfo.py xbitinfo-0.0.2/xbitinfo/xbitinfo.py
--- xbitinfo-0.0.2.orig/xbitinfo/xbitinfo.py 2022-07-11 17:37:19.000000000 -0300
+++ xbitinfo-0.0.2/xbitinfo/xbitinfo.py 2022-08-24 18:08:26.244894000 -0300
@@ -4,21 +4,21 @@

import numpy as np
import xarray as xr
-from julia.api import Julia
from tqdm.auto import tqdm

from . import __version__

-jl = Julia(compiled_modules=False, debug=False)
-from julia import Main # noqa: E402
+from .julia_helpers import init_julia
+
+Main = init_julia()

path_to_julia_functions = os.path.join(
os.path.dirname(__file__), "bitinformation_wrapper.jl"
)
Main.path = path_to_julia_functions
-jl.using("BitInformation")
-jl.using("Pkg")
-jl.eval("include(Main.path)")
+Main.eval("using BitInformation")
+Main.eval("using Pkg")
+Main.eval("include(Main.path)")


NMBITS = {64: 12, 32: 9, 16: 6} # number of non mantissa bits for given dtype
@@ -207,7 +207,7 @@
kwargs_str = _get_bitinformation_kwargs_handler(ds[var], kwargs)
logging.debug(f"get_bitinformation(X, dim={dim}, {kwargs_str})")
info_per_bit[var] = {}
- info_per_bit[var]["bitinfo"] = jl.eval(
+ info_per_bit[var]["bitinfo"] = Main.eval(
f"get_bitinformation(X, dim={axis_jl}, {kwargs_str})"
)
info_per_bit[var]["dim"] = dim
@@ -369,7 +369,7 @@
"""Wrap `BitInformation.jl.round <https://github.com/milankl/BitInformation.jl/blob/main/src/round_nearest.jl>`__. Used in :py:func:`xbitinfo.bitround.jl_bitround`."""
Main.X = X
Main.keepbits = keepbits
- return jl.eval("round!(X, keepbits)")
+ return Main.eval("round!(X, keepbits)")


def get_prefect_flow(paths=[]):
@@ -579,7 +579,7 @@

def get_julia_package_version(package):
"""Get version information of julia package"""
- version = jl.eval(
+ version = Main.eval(
f'Pkg.TOML.parsefile(joinpath(pkgdir({package}), "Project.toml"))["version"]'
)
return version
19 changes: 18 additions & 1 deletion recipes/xbitinfo/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,24 @@ package:
source:
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/xbitinfo-{{ version }}.tar.gz
sha256: 4f44f1a09221aceadb8f09bcd2ec9397be74da4158e6e39893df47b27b53ac69
patches:
- install_julia.patch

build:
# It will fail on Windows due to the lack of Julia
# but this should remain noarch.
# Users can install Julia from other sources and still use this package on Windows.
noarch: python
script: {{ PYTHON }} -m pip install . -vv
script:
- {{ PYTHON }} -m pip install . -vv && {{ PYTHON }} -c 'import xbitinfo; xbitinfo.install()'
number: 0

requirements:
build:
- python
- pip
- pyjulia >=0.5.7
- julia >=1.6.0,<1.8.0
host:
- python >=3.8,<3.9
- pip
Expand All @@ -26,6 +34,10 @@ requirements:
- setuptools_scm_git_archive
- pyjulia >=0.5.7
- julia >=1.6.0,<1.8.0
# imports itself so we need all the run deps here too.
- numcodecs >=0.10.0
- tqdm
- xarray
run:
- python >=3.8,<3.9
- pyjulia >=0.5.7
Expand All @@ -46,6 +58,11 @@ test:
- pip check
requires:
- pip
- pytest
- pytest-lazy-fixture
- pooch
- netcdf4
- dask

about:
home: https://github.com/observingClouds/xbitinfo
Expand Down
3 changes: 3 additions & 0 deletions recipes/xbitinfo/run_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from xbitinfo.bitround import jl_bitround, xr_bitround
from xbitinfo.graphics import plot_bitinformation, plot_distribution
from xbitinfo.xbitinfo import get_bitinformation, get_keepbits, get_prefect_flow

0 comments on commit 930c9f7

Please sign in to comment.