Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ updates:
prefix: "pip prod"
prefix-development: "pip dev"
include: "scope"
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
# Add assignees
assignees:
- "mloubout"
commit-message:
prefix: "gh"
prefix-development: "gh dev"
include: "scope"
16 changes: 8 additions & 8 deletions .github/workflows/pytest-core-nompi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
os: ubuntu-22.04
arch: "gcc-11"
language: "CXX"
sympy: "1.11"
sympy: "1.14"

- name: pytest-ubuntu-py312-gcc12-cxxomp
python-version: '3.12'
Expand All @@ -61,14 +61,14 @@ jobs:
os: ubuntu-24.04
arch: "gcc-14"
language: "openmp"
sympy: "1.9"
sympy: "1.12"

- name: pytest-ubuntu-py310-gcc10-noomp
python-version: '3.10'
os: ubuntu-22.04
arch: "gcc-10"
language: "C"
sympy: "1.11"
sympy: "1.14"

- name: pytest-ubuntu-py312-gcc13-omp
python-version: '3.12'
Expand All @@ -82,28 +82,28 @@ jobs:
os: ubuntu-22.04
arch: "custom"
language: "openmp"
sympy: "1.10"
sympy: "1.12"

- name: pytest-osx-py312-clang-omp
python-version: '3.12'
os: macos-latest
arch: "clang"
language: "openmp"
sympy: "1.13"
sympy: "1.12"

- name: pytest-docker-py39-gcc-omp
python-version: '3.9'
os: ubuntu-latest
arch: "gcc"
language: "openmp"
sympy: "1.12"
sympy: "1.13"

- name: pytest-docker-py39-icx-omp
python-version: '3.9'
os: ubuntu-latest
arch: "icx"
language: "openmp"
sympy: "1.12"
sympy: "1.13"

- set: base
test-set: 'not adjoint'
Expand Down Expand Up @@ -163,8 +163,8 @@ jobs:
if: "!contains(matrix.name, 'docker')"
run: |
python3 -m pip install ${{ env.PIPFLAGS }} --upgrade pip
python3 -m pip install ${{ env.PIPFLAGS }} sympy==${{matrix.sympy}}
python3 -m pip install ${{ env.PIPFLAGS }} -e .[tests,extras]
python3 -m pip install ${{ env.PIPFLAGS }} sympy==${{matrix.sympy}}

- name: Check configuration
run: |
Expand Down
8 changes: 6 additions & 2 deletions devito/types/caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,13 @@ def clear(cls, force=True):

# Wipe out the hidden module-private SymPy caches
sympy.polys.rootoftools.ComplexRootOf.clear_cache()
sympy.polys.rings._ring_cache.clear()
sympy.polys.fields._field_cache.clear()
sympy.polys.domains.modularinteger._modular_integer_cache.clear()
try:
sympy.polys.rings._ring_cache.clear()
sympy.polys.fields._field_cache.clear()
except AttributeError:
# SymPy 1.14 and later

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

since I'm paranoid, could you try a git grep _cache in SymPy 1.14 to be sure they haven't added any other random caches?

pass

# Take a copy of the dictionary so we can safely iterate over it
# even if another thread is making changes
Expand Down
6 changes: 5 additions & 1 deletion devito/types/tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
from functools import cached_property

import numpy as np
from sympy.matrices.matrixbase import MatrixBase
try:
from sympy.matrices.matrixbase import MatrixBase
except ImportError:
# Before 1.13
from sympy.matrices.matrices import MatrixBase
from sympy.core.sympify import converter as sympify_converter

from devito.finite_differences import Differentiable
Expand Down
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pip>=9.0.1
numpy>1.16,<2.3
sympy>=1.9,<1.14
numpy>=2,<2.2.6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why the max numpy downgrade?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's not a downgrade. numpy is currently at 2.2.5 and making minor releases so the dependabot is not catching those because they always satisfy the current major release bound. It's just refining it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are there any systems that we know about where Devito is running and numpy is a system dependency (ie: air-gapped systems) where this might cause an issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think Colab was yes, but I think they updated recently. Handling the sympy-numpy versions is quite a pain if we allow numpy <2 but will see if can find a way.

sympy>=1.12.1,<1.14; python_version < '3.10'
sympy>=1.12.1,<1.15; python_version >= '3.10'
psutil>=5.1.0,<8.0
py-cpuinfo<10
cgen>=2020.1,<2021
Expand Down
95 changes: 13 additions & 82 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,29 @@
import versioneer

import os
try:
import importlib.metadata as metadata
get_version = lambda x: metadata.version(x)
PkgNotFound = metadata.PackageNotFoundError
parse_version = lambda x: metadata.version(x)
except ImportError:
import pkg_resources
get_version = lambda x: pkg_resources.get_distribution(x).version
PkgNotFound = pkg_resources.DistributionNotFound
parse_version = lambda x: pkg_resources.parse_version(x)

from setuptools import setup, find_packages
import versioneer


def min_max(pkgs, pkg_name):
pkg = [p for p in pkgs if pkg_name in p][0]
minsign = '>=' if '>=' in pkg else '>'
maxsign = '<=' if '<=' in pkg else '<'
vmin = pkg.split(minsign)[1].split(',')[0]
vmax = pkg.split(maxsign)[-1]
return vmin, vmax


def numpy_compat(required):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note: Ok so basically this was not doing anything because pip runs the build in isolation so sympy is never found and it always default to the PkgNotFound case.

new_reqs = [r for r in required if "numpy" not in r and "sympy" not in r]
sympy_lb, sympy_ub = min_max(required, "sympy")
numpy_lb, numpy_ub = min_max(required, "numpy")

# Due to api changes in numpy 2.0, it requires sympy 1.12.1 at the minimum
# Check if sympy is installed and enforce numpy version accordingly.
# If sympy isn't installed, enforce sympy>=1.12.1 and numpy>=2.0
try:
sympy_version = get_version("sympy")
min_ver2 = parse_version("1.12.1")
if parse_version(sympy_version) < min_ver2:
new_reqs.extend([f"numpy>{numpy_lb},<2.0", f"sympy=={sympy_version}"])
else:
new_reqs.extend([f"numpy>=2.0,<{numpy_ub}", f"sympy=={sympy_version}"])
except PkgNotFound:
new_reqs.extend([f"sympy>=1.12.1,<{sympy_ub}", f"numpy>=2.0,<{numpy_ub}"])

return new_reqs


with open('requirements.txt') as f:
required = f.read().splitlines()
required = numpy_compat(required)

with open('requirements-optional.txt') as f:
optionals = f.read().splitlines()

with open('requirements-testing.txt') as f:
testing = f.read().splitlines()

with open('requirements-mpi.txt') as f:
mpis = f.read().splitlines()

with open('requirements-nvidia.txt') as f:
nvidias = f.read().splitlines()
def load_requirements(filename):
with open(filename) as f:
lines = f.read().splitlines()
return lines

reqs = []
for ir in required:
if ir[0:3] == 'git':
name = ir.split('/')[-1]
reqs += ['%s @ %s@main' % (name, ir)]
else:
reqs += [ir]

extras_require = {}
for mreqs, mode in (zip([optionals, mpis, nvidias, testing],
['extras', 'mpi', 'nvidia', 'tests'])):
opt_reqs = []
for ir in mreqs:
# For conditionals like pytest=2.1; python == 3.6
if ';' in ir:
entries = ir.split(';')
extras_require[entries[1]] = entries[0]
# Git repos, install main
if ir[0:3] == 'git':
name = ir.split('/')[-1]
opt_reqs += ['%s @ %s@main' % (name, ir)]
else:
opt_reqs += [ir]
extras_require[mode] = opt_reqs
reqs = load_requirements('requirements.txt')
extras_require = {
'mpi': load_requirements('requirements-mpi.txt'),
'nvidia': load_requirements('requirements-nvidia.txt'),
'tests': load_requirements('requirements-testing.txt'),
'extras': load_requirements('requirements-optional.txt'),
}

# If interested in benchmarking devito, we need the `examples` too
exclude = ['docs', 'tests']
try:
if not bool(int(os.environ.get('DEVITO_BENCHMARKS', 0))):
exclude += ['examples']
else:
required += testing
reqs += extras_require['tests']
except (TypeError, ValueError):
exclude += ['examples']

Expand Down