Skip to content

Commit 35fff01

Browse files
authored
Merge pull request #379 from jcapriot/numpy2.0_updates
Numpy2.0 updates
2 parents e3b5f01 + 2e209fc commit 35fff01

11 files changed

Lines changed: 112 additions & 164 deletions

File tree

.ci/azure/deploy.yml

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
jobs:
22
- job:
3-
displayName: "Deploy Docs and source"
3+
displayName: "Deploy Docs"
44
pool:
55
vmImage: ubuntu-latest
66

@@ -14,27 +14,13 @@ jobs:
1414
echo $BRANCH_NAME
1515
displayName: Report branch parameters
1616
17-
# Just download all of the items already built
18-
- task: DownloadPipelineArtifact@2
19-
inputs:
20-
buildType: 'current'
21-
artifactName: 'wheels'
22-
targetPath: 'dist'
23-
24-
- task: DownloadPipelineArtifact@2
25-
inputs:
26-
buildType: 'current'
27-
artifactName: 'source_dist'
28-
targetPath: 'dist'
29-
3017
- task: DownloadPipelineArtifact@2
3118
inputs:
3219
buildType: 'current'
3320
artifactName: 'html_docs'
3421
targetPath: 'html'
3522

3623
- bash: |
37-
ls -l dist
3824
ls -l html
3925
displayName: Report downloaded cache contents.
4026
@@ -47,14 +33,6 @@ jobs:
4733
GH_NAME: $(gh.name)
4834
GH_EMAIL: $(gh.email)
4935
50-
- bash: |
51-
twine upload --skip-existing dist/*
52-
displayName: Deploy source and wheels
53-
condition: eq(variables.IS_TAG, true)
54-
env:
55-
TWINE_USERNAME: $(twine.username)
56-
TWINE_PASSWORD: $(twine.password)
57-
5836
# upload documentation to discretize-docs gh-pages on tags
5937
- bash: |
6038
git clone -q --branch gh-pages --depth 1 https://${GH_TOKEN}@github.com/simpeg/discretize-docs.git

.ci/azure/wheels.yml

Lines changed: 0 additions & 63 deletions
This file was deleted.

azure-pipelines.yml

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,11 @@ stages:
3636
jobs:
3737
- template: .ci/azure/docs.yml
3838

39-
- stage: BuildWheels
40-
dependsOn:
41-
- Testing
42-
- DocBuild
43-
displayName: "Build Wheels"
44-
jobs:
45-
- template: .ci/azure/wheels.yml
46-
47-
- stage: BuildSource
39+
- stage: Deploy
40+
displayName: "Deploy Docs"
4841
dependsOn:
4942
- Testing
5043
- DocBuild
51-
displayName: "Build Source distribution"
52-
jobs:
53-
- template: .ci/azure/sdist.yml
54-
55-
- stage: Deploy
56-
displayName: "Deploy Source, Wheels, and Docs"
57-
dependsOn:
58-
- BuildWheels
59-
- BuildSource
6044
condition: and(succeeded(), or(eq(variables.IS_TAG, true), eq(variables.IS_MAIN, true)))
6145
jobs:
6246
- template: .ci/azure/deploy.yml

discretize/_extensions/meson.build

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,34 @@
11
# NumPy include directory
2-
# The try-except is needed because when things are
3-
# split across drives on Windows, there is no relative path and an exception
4-
# gets raised. There may be other such cases, so add a catch-all and switch to
5-
# an absolute path. Relative paths are needed when for example a virtualenv is
6-
# placed inside the source tree; Meson rejects absolute paths to places inside
7-
# the source tree.
8-
# For cross-compilation it is often not possible to run the Python interpreter
9-
# in order to retrieve numpy's include directory. It can be specified in the
10-
# cross file instead:
11-
# [properties]
12-
# numpy-include-dir = /abspath/to/host-pythons/site-packages/numpy/core/include
13-
#
14-
# This uses the path as is, and avoids running the interpreter.
15-
incdir_numpy = meson.get_external_property('numpy-include-dir', 'not-given')
16-
if incdir_numpy == 'not-given'
17-
incdir_numpy = run_command(py,
18-
[
19-
'-c',
20-
'''import os
2+
numpy_nodepr_api = ['-DNPY_NO_DEPRECATED_API=NPY_1_22_API_VERSION']
3+
np_dep = dependency('numpy', required: false)
4+
if not np_dep.found()
5+
# For cross-compilation it is often not possible to run the Python interpreter
6+
# in order to retrieve numpy's include directory. It can be specified in the
7+
# cross file instead:
8+
# [properties]
9+
# numpy-include-dir = /abspath/to/host-pythons/site-packages/numpy/core/include
10+
#
11+
# This uses the path as is, and avoids running the interpreter.
12+
incdir_numpy = meson.get_external_property('numpy-include-dir', 'not-given')
13+
if incdir_numpy == 'not-given'
14+
incdir_numpy = run_command(py,
15+
[
16+
'-c',
17+
'''import os
2118
import numpy as np
2219
try:
2320
incdir = os.path.relpath(np.get_include())
2421
except Exception:
2522
incdir = np.get_include()
2623
print(incdir)
27-
'''
28-
],
29-
check: true
30-
).stdout().strip()
31-
else
32-
_incdir_numpy_abs = incdir_numpy
24+
'''
25+
],
26+
check: true
27+
).stdout().strip()
28+
endif
29+
inc_np = include_directories(incdir_numpy)
30+
np_dep = declare_dependency(include_directories: inc_np)
3331
endif
34-
inc_np = include_directories(incdir_numpy)
35-
np_dep = declare_dependency(include_directories: inc_np)
3632

3733
# Deal with M_PI & friends; add `use_math_defines` to c_args or cpp_args
3834
# Cython doesn't always get this right itself (see, e.g., gh-16800), so
@@ -44,7 +40,6 @@ else
4440
use_math_defines = []
4541
endif
4642

47-
numpy_nodepr_api = '-DNPY_NO_DEPRECATED_API=NPY_1_9_API_VERSION'
4843
c_undefined_ok = ['-Wno-maybe-uninitialized']
4944

5045
cython_c_args = [numpy_nodepr_api, use_math_defines]
@@ -54,14 +49,19 @@ if cy_line_trace
5449
cython_c_args += ['-DCYTHON_TRACE_NOGIL=1']
5550
endif
5651

52+
cython_args = []
53+
if cy.version().version_compare('>=3.1.0')
54+
cython_args += ['-Xfreethreading_compatible=True']
55+
endif
56+
5757
cython_cpp_args = cython_c_args
5858

5959
module_path = 'discretize/_extensions'
6060

6161
py.extension_module(
6262
'interputils_cython',
6363
'interputils_cython.pyx',
64-
include_directories: incdir_numpy,
64+
cython_args: cython_args,
6565
c_args: cython_c_args,
6666
install: true,
6767
subdir: module_path,
@@ -71,7 +71,7 @@ py.extension_module(
7171
py.extension_module(
7272
'tree_ext',
7373
['tree_ext.pyx' , 'tree.cpp', 'geom.cpp'],
74-
include_directories: incdir_numpy,
74+
cython_args: cython_args,
7575
cpp_args: cython_cpp_args,
7676
install: true,
7777
subdir: module_path,
@@ -82,7 +82,7 @@ py.extension_module(
8282
py.extension_module(
8383
'simplex_helpers',
8484
'simplex_helpers.pyx',
85-
include_directories: incdir_numpy,
85+
cython_args: cython_args,
8686
cpp_args: cython_cpp_args,
8787
install: true,
8888
subdir: module_path,

discretize/operators/differential_operators.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
av,
1414
av_extrap,
1515
make_boundary_bool,
16+
cross2d,
1617
)
1718
from discretize.utils.code_utils import deprecate_method, deprecate_property
1819

@@ -2237,7 +2238,12 @@ def boundary_edge_vector_integral(self):
22372238
if self.dim > 2:
22382239
Av *= 2
22392240

2240-
w_cross_n = np.cross(-w, Av.T @ dA)
2241+
av_da = Av.T @ dA
2242+
2243+
if self.dim == 2:
2244+
w_cross_n = cross2d(av_da, w)
2245+
else:
2246+
w_cross_n = np.cross(av_da, w)
22412247

22422248
if self.dim == 2:
22432249
return Pe.T @ sp.diags(w_cross_n, format="csr")

discretize/unstructured_mesh.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numpy as np
44
import scipy.sparse as sp
55
from scipy.spatial import KDTree
6-
from discretize.utils import Identity, invert_blocks, spzeros
6+
from discretize.utils import Identity, invert_blocks, spzeros, cross2d
77
from discretize.base import BaseMesh
88
from discretize._extensions.simplex_helpers import (
99
_build_faces_edges,
@@ -264,7 +264,7 @@ def face_normals(self): # NOQA D102
264264
if self.dim == 2:
265265
# Take the normal as being the cross product of edge_tangents
266266
# and a unit vector in a "3rd" dimension.
267-
normal = np.cross(self.edge_tangents, [0, 0, 1])[:, :-1]
267+
normal = np.c_[self.edge_tangents[:, 1], -self.edge_tangents[:, 0]]
268268
else:
269269
# define normal as |01 x 02|
270270
# therefore clockwise path about the normal is 0->1->2->0
@@ -346,7 +346,7 @@ def edge_curl(self): # NOQA D102
346346
# cp = np.cross(l01, -l20)
347347
# cp is a bunch of 1s (where simplices are CCW) and -1s (where simplices are CW)
348348
# (but we take the sign here to guard against numerical precision)
349-
cp = np.sign(np.cross(l20, l01))
349+
cp = np.sign(cross2d(l20, l01))
350350
face_areas = face_areas * cp
351351
# don't due *= here
352352

@@ -812,29 +812,34 @@ def get_interpolation_matrix( # NOQA D102
812812
n_items = self.n_edges
813813
elif location_type[:-2] == "faces":
814814
# grab the barycentric transforms associated with each simplex:
815-
ts = transform[
816-
inds,
817-
:,
818-
]
815+
ts = transform[inds, :]
819816
ts = np.hstack((ts, -ts.sum(axis=1)[:, None]))
820817
# use Whitney 2 - form basis functions for face vector interp
821818
faces = self._simplex_faces[inds]
822819
areas = self.face_areas
823820

824821
# [1, 2], [0, 2], [0, 1]
825822
if self.dim == 2:
823+
# i j k
824+
# t0 t1 t2
825+
# 0 0 1
826+
# t1 * i - t0 * j
827+
826828
f0 = (
827-
barys[:, 1] * (np.cross(ts[:, 2], [0, 0, 1])[:, i_dir])
828-
+ barys[:, 2] * (np.cross([0, 0, 1], ts[:, 1])[:, i_dir])
829-
) * areas[faces[:, 0]]
829+
cross2d(barys[:, 1:], ts[:, 1:, 1 - i_dir]) * areas[faces[:, 0]]
830+
)
830831
f1 = (
831-
barys[:, 0] * (np.cross(ts[:, 2], [0, 0, 1])[:, i_dir])
832-
+ barys[:, 2] * (np.cross([0, 0, 1], ts[:, 0])[:, i_dir])
833-
) * areas[faces[:, 1]]
832+
cross2d(barys[:, [0, 2]], ts[:, [0, 2], 1 - i_dir])
833+
* areas[faces[:, 1]]
834+
)
834835
f2 = (
835-
barys[:, 0] * (np.cross(ts[:, 1], [0, 0, 1])[:, i_dir])
836-
+ barys[:, 1] * (np.cross([0, 0, 1], ts[:, 0])[:, i_dir])
837-
) * areas[faces[:, 2]]
836+
cross2d(barys[:, :-1], ts[:, :-1, 1 - i_dir])
837+
* areas[faces[:, 2]]
838+
)
839+
if i_dir == 1:
840+
f0 *= -1
841+
f1 *= -1
842+
f2 *= -1
838843
Aij = np.c_[f0, f1, f2].reshape(-1)
839844
ind_ptr = 3 * np.arange(n_loc + 1)
840845
else:
@@ -1219,7 +1224,7 @@ def boundary_edge_vector_integral(self): # NOQA D102
12191224
Pe = self.project_edge_to_boundary_edge
12201225
n_boundary_edges, n_edges = Pe.shape
12211226
index = boundary_face_edges
1222-
w_cross_n = np.cross(-self.edge_tangents[index], dA)
1227+
w_cross_n = cross2d(dA, self.edge_tangents[index])
12231228
M_be = (
12241229
sp.csr_matrix((w_cross_n, (index, index)), shape=(n_edges, n_edges))
12251230
@ Pe.T

discretize/utils/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
invert_blocks
7878
make_property_tensor
7979
inverse_property_tensor
80+
cross2d
8081
8182
Mesh Utilities
8283
--------------
@@ -165,6 +166,7 @@
165166
inv2X2BlockDiagonal,
166167
makePropertyTensor,
167168
invPropertyTensor,
169+
cross2d,
168170
)
169171
from discretize.utils.mesh_utils import (
170172
meshTensor,

0 commit comments

Comments
 (0)