Skip to content

Commit

Permalink
Merge branch 'master' into issue997-incompatible_with_Python_3_12
Browse files Browse the repository at this point in the history
  • Loading branch information
guyer committed Feb 22, 2024
2 parents 1f3cf3c + 6236076 commit 4bb7b84
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 130 deletions.
20 changes: 15 additions & 5 deletions .github/workflows/nix.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: nix
name: Test Nix
on: [push, pull_request]
jobs:
test:
Expand All @@ -11,12 +11,22 @@ jobs:
run:
working-directory: ./
steps:
- uses: actions/checkout@v2.3.4
- uses: cachix/install-nix-action@v14.1
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
with:
nix_path: nixpkgs=channel:nixos-unstable
name: fipy
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
extraPullNames: nix-community
- run: nix-shell --pure --command "python setup.py test"
- run: nix-shell --pure --command "py.test --nbval --sanitize-with examples/sanitize.cfg examples/index.ipynb"
- run: echo "UID=${UID}" >> $GITHUB_ENV
- uses: actions/cache/restore@v3
with:
path: /run/user/${{ env.UID }}/http_cache.sqlite
key: ${{ runner.os }}-http_cache.sqlite
- run: nix develop --command bash -c "python setup.py test"
- run: nix develop --command bash -c "py.test --nbval --nbval-sanitize-with examples/sanitize.cfg examples/index.ipynb"
- uses: actions/cache/save@v3
if: always()
with:
path: /run/user/${{ env.UID }}/http_cache.sqlite
key: ${{ runner.os }}-http_cache.sqlite
51 changes: 7 additions & 44 deletions docs/source/NIX-README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,27 @@ Nix Installation
:term:`FiPy` now has a `Nix`_ expression for installing :term:`FiPy`
using `Nix`_. `Nix`_ is a powerful package manager for Linux and other
Unix systems that makes package management reliable and
reproducible. The recipe works on both Linux and Mac OS X.

Getting Started with Nix
------------------------

There are a number of tutorials on getting started with `Nix`_. The
page that I used when getting started is on the Blog of the HPC team
of GRICAD,

https://gricad.github.io/calcul/nix/tuto/2017/07/04/nix-tutorial.html

I also made my own notes,

https://github.com/wd15/nixes/blob/master/NIX-NOTES.md

which are a succinct steps that I use when setting up a new system with
Nix.
reproducible. The recipe works on both Linux and Mac OS X. Go to
`nix.dev`_ to get started with Nix.

Installing
----------

Once you have a working Nix installation use::

$ nix-shell --pure
$ nix develop

in the base :term:`FiPy` directory to install :term:`FiPy` with Python
3 by default. Modify the `shell.nix` file to use another version of
Python. ``nix-shell`` drops the user into a shell with a working
3 by default. ``nix develop`` drops the user into a shell with a working
version of :term:`FiPy`. To test your installation use::

$ nix-shell --pure --command "python setup.py test"
$ nix develop --command bash -c "python setup.py test"

.. note::

:term:`Trilinos` is currently not available as part of the Nix
:term:`FiPy` installation.


Additional Packages
-------------------

To install additional packages available from Nixpkgs_ include them in
the `nativeBuildInputs` list in `shell.nix`.


Using Pip
---------

Packages unavailable from Nix can be installed using :term:`Pip`. In
this case, the installation has been set up so that the Nix shell
knows about a ``.local`` directory in the base :term:`FiPy` directory
used by :term:`Pip` for installation. So, for example, to install the
``toolz`` package from within the Nix shell use::

$ python -m pip install --user toolz
The SciPy solvers are the only available solvers currently.

The ``.local`` directory will persist after the Nix shell has been
closed.

.. _Nix: https://nixos.org/nix/
.. _Nixpkgs: https://nixos.org/nixpkgs/
.. _nix.dev: https://nix.dev
18 changes: 12 additions & 6 deletions examples/diffusion/mesh1D.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,24 +720,30 @@
and solve the steady-state problem
>>> DiffusionTerm(coeff=D).solve(var=phi) #doctest: +PYSPARSE_SOLVER
>>> try:
... DiffusionTerm(coeff=D).solve(var=phi)
... except:
... pass
>>> if __name__ == '__main__':
... viewer.plot()
>>> from fipy import input
>>> if __name__ == '__main__':
... input("No-flux - stead-state failure. \
... input("No-flux - steady-state failure. \
... Press <return> to proceed...")
>>> print(numerix.allclose(phi, 0.0)) #doctest: +PYSPARSE_SOLVER
True
>>> print(numerix.allclose(phi, 0.2, atol=1e-5)) # doctest: +NOT_TRILINOS_SOLVER
False
.. image:: /figures/examples/diffusion/mesh1D-noflux_steady_fail.*
:width: 90%
:align: center
:alt: (failed) steady-state solution for no-flux boundary conditions
we find that the value is uniformly zero! What happened to our no-flux boundary
conditions?
Depending on the solver, we find that the value may be uniformly zero,
infinity, or NaN, or the solver may just fail!
What happened to our no-flux boundary conditions?
Trilinos actually manages to get the correct solution, but this should not
be relied on; this problem has an infinite number of solutions.
The problem is that in the implicit discretization of :math:`\nabla\cdot(D\nabla\phi) = 0`,
Expand Down
25 changes: 17 additions & 8 deletions examples/index.ipynb

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion examples/sanitize.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[regex]
[regex1]
regex: <Figure size [0-9]{3,4}x[0-9]{3,4}(?:.[0-9])? with [0-9]{1,3} Axes>
replace: <Figure size>

[regex2]
regex: <fipy.viewers.matplotlibViewer.matplotlib2DGridViewer.Matplotlib2DGridViewer at .{1,}>
replace: <fipy.viewers.matplotlibViewer.matplotlib2DGridViewer.Matplotlib2DGridViewer>
9 changes: 7 additions & 2 deletions fipy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,17 @@ def _excepthook(*args):

if _log.isEnabledFor(logging.DEBUG):
try:
_fipy_environment["conda"] = environment.conda_info()
_fipy_environment.update(environment.conda_info())
except:
pass

try:
_fipy_environment["pip"] = environment.pip_info()
_fipy_environment.update(environment.pip_info())
except:
pass

try:
_fipy_environment.update(environment.nix_info())
except:
pass

Expand Down
6 changes: 6 additions & 0 deletions fipy/solvers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ def _import_mesh_matrices(suite):
test=lambda: solver_suite != 'pyamgx',
why="the PyAMGX solver is being used.",
skipWarning=True)

register_skipper(flag='NOT_TRILINOS_SOLVER',
test=lambda: solver_suite not in ['trilinos', 'no-pysparse'],
why="the Trilinos solvers are being used.",
skipWarning=True)

del register_skipper

_log.info("Solver suite is %s", solver_suite)
Expand Down
39 changes: 37 additions & 2 deletions fipy/tools/logging/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import subprocess
import sys

__all__ = ["conda_info", "pip_info", "package_info", "platform_info"]
__all__ = ["conda_info", "pip_info", "package_info", "platform_info", "nix_info"]

def conda_info(conda="conda"):
"""Collect information about conda environment.
Expand All @@ -25,6 +25,7 @@ def conda_info(conda="conda"):
stdout = stdout.decode('ascii')

info["conda_info"] = json.loads(stdout)

p = subprocess.Popen([conda, "env", "export",
"--name", info["conda_info"]["active_prefix_name"],
"--json"],
Expand Down Expand Up @@ -53,7 +54,41 @@ def pip_info(python="python"):
stdout, _ = p.communicate()
stdout = stdout.decode('ascii')

return json.loads(stdout)
info["pip"] = json.loads(stdout)

return info

def nix_info():
"""Collect information about nix environment.
Returns
-------
dict
Result of `nix derivation show .#fipy `.
"""
info = {}

# Better output would be from
#
# $ nix-store -q --tree $(nix-store --realize $(nix eval --raw .#fipy.drvPath))
#
# However, this is difficult to execute and can require another build.
# Also doesn't return json.

p = subprocess.Popen(
[
"nix",
"derivation",
"show",
".#fipy"
], stdout=subprocess.PIPE)

stdout, _ = p.communicate()
stdout = stdout.decode('ascii')

info["nix"] = json.loads(stdout)

return info

def package_info():
"""Collect information about installed packages FiPy uses.
Expand Down
7 changes: 6 additions & 1 deletion fipy/variables/operatorVariable.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def _py3kInstructions(self, op, style, argDict, id, freshen):
# Removed in Python 3
stack.append("`" + stack.pop() + "`")
elif ins.opname == 'BINARY_SUBSCR':
stack.append(stack.pop(-2) + "[" + stack.pop() + "]")
stack.append(stack.pop(-2) + "[" + str(stack.pop()) + "]")
elif ins.opname == 'RETURN_VALUE':
s = stack.pop()
if style == 'C':
Expand Down Expand Up @@ -371,6 +371,11 @@ def _testBinOp(self):
>>> ttns((v1 / v2 - v3 * v4 + v1 * v4)._getRepresentation(style='C', id=""))
'(((var000[i] / var001[i]) - (var010[i] * var011[i])) + (var10[i] * var11[i]))'
Test that the representation of indexing works correctly
>>> ttns(v1[1]._getRepresentation()) # doctest: +ELLIPSIS
'Variable(value=array([1, 2, 3, 4]))[...]'
Check that unit works for a `binOp`
>>> (Variable(value="1 m") * Variable(value="1 s")).unit == Variable(value="1 s*m").unit
Expand Down
61 changes: 61 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
description = "Python environment for fipy";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, utils}: (utils.lib.eachSystem ["x86_64-linux" "x86_64-darwin" ] (system:
let
pkgs = nixpkgs.legacyPackages.${system};
pypkgs = pkgs.python310Packages;

env = (pypkgs.fipy.overridePythonAttrs (old: rec {

src = pkgs.lib.cleanSource ./.;

nativeBuildInputs = with pypkgs; [
pip
pkgs.openssh
nbval
ipython
ipykernel
jupyterlab
traitlets
notebook
] ++ propagatedBuildInputs;

propagatedBuildInputs = old.propagatedBuildInputs;

postShellHook = ''
SOURCE_DATE_EPOCH=$(date +%s)
export PYTHONUSERBASE=$PWD/.local
export USER_SITE=`python -c "import site; print(site.USER_SITE)"`
export PYTHONPATH=$PYTHONPATH:$USER_SITE:$(pwd)
export PATH=$PATH:$PYTHONUSERBASE/bin
export OMPI_MCA_plm_rsh_agent=${pkgs.openssh}/bin/ssh
'';
}));
in
rec {
packages.fipy = env;
packages.default = self.packages.${system}.fipy;
devShells.default = env;
}
));
}

0 comments on commit 4bb7b84

Please sign in to comment.