Skip to content

Commit 13e95c6

Browse files
authored
Merge pull request #34 from 4Ran8jith/gitlab-main
Add DPNP Framework Support to Selected Benchmarks
2 parents 35cb9f3 + 7a33924 commit 13e95c6

File tree

42 files changed

+994
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+994
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,4 @@ dmypy.json
130130

131131
# dace
132132
.dacecache/
133+
*.csv

README.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
## Quickstart
55

66
To install NPBench, simply execute:
7+
78
```
89
python -m pip install -r requirements.txt
910
python -m pip install .
1011
```
12+
1113
You can then run a subset of the benchmarks with NumPy, Numba, and DaCe and plot
1214
the speedup of DaCe and Numba against NumPy:
13-
```
15+
16+
``` bash
1417
python -m pip install numba
1518
python -m pip install dace
1619
python quickstart.py
@@ -22,6 +25,7 @@ python plot_results.py
2225
Currently, the following frameworks are supported (in alphabetical order):
2326
- CuPy
2427
- DaCe
28+
- Dpnp
2529
- JAX
2630
- Numba
2731
- NumPy
@@ -56,6 +60,27 @@ However, you may want to install the latest version from the [GitHub repository]
5660
To run NPBench with DaCe, you have to select as framework (see details below)
5761
either `dace_cpu` or `dace_gpu`.
5862

63+
### DPNP
64+
65+
With `dpnp` it is strongly recommended to use `conda` instead of `pip` for its dependency on intel packages.
66+
Refer to this
67+
[LINK](https://intelpython.github.io/dpnp/quick_start_guide.html#building-for-custom-sycl-targets) to know more
68+
about building custom SYCL targets or installing `dpnp` package from the `intel` channel.
69+
70+
Unlike the pip installation, with conda it is advisable to try installing all packages at once.
71+
Edit the `environment.yml` to include packages and optional dependencies (e.g. hardware-dependent frameworks
72+
or utilities such as `ipython`). Then type:
73+
74+
``` bash
75+
$ conda env create -f environment.yml # environment.yml contains all the right dependencies
76+
$ conda activate npb # Activate the environment
77+
$ python -m pip install pygount # Only dependency not distributed with conda
78+
```
79+
80+
To run NPBench with dpnp, You must select as framework, either `dpnp_cpu` or `dpnp_gpu`, depending on your hardware. See details below.
81+
82+
_DPNP only contains a subset of the benchmarks, selected on interest and best-effort basis._
83+
5984
### Jax
6085

6186
JAX can be installed with pip:
@@ -73,7 +98,6 @@ JAX can be installed with pip:
7398
```
7499
For more installation options, please consult the JAX [installation guide](https://jax.readthedocs.io/en/latest/installation.html#installation).
75100

76-
77101
### Numba
78102

79103
Numba can be installed with pip:
@@ -172,7 +196,3 @@ NPBench is a collection of scientific Python/NumPy codes from various domains th
172196
- Pythran [benchmarks](https://github.com/serge-sans-paille/numpy-benchmarks/)
173197
- [Stockham-FFT](http://urn.kb.se/resolve?urn=urn:nbn:se:kth:diva-287731)
174198
- Weather stencils from [gt4py](https://github.com/GridTools/gt4py)
175-
176-
177-
178-

bench_info/covariance2.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"benchmark": {
3+
"name": "Covariance2",
4+
"short_name": "covarian2",
5+
"relative_path": "polybench/covariance2",
6+
"module_name": "covariance2",
7+
"func_name": "kernel",
8+
"kind": "microbench",
9+
"domain": "Learning",
10+
"dwarf": "dense_linear_algebra",
11+
"parameters": {
12+
"S": { "M": 500, "N": 600 },
13+
"M": { "M": 1400, "N": 1800 },
14+
"L": { "M": 3200, "N": 4000 },
15+
"paper": { "M": 1200, "N": 1400 }
16+
},
17+
"init": {
18+
"func_name": "initialize",
19+
"input_args": ["M", "N"],
20+
"output_args": ["float_n", "data"]
21+
},
22+
"input_args": ["M", "float_n", "data"],
23+
"array_args": ["data"],
24+
"output_args": []
25+
}
26+
}

environment.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: npb
2+
channels:
3+
- conda-forge
4+
- https://software.repos.intel.com/python/conda
5+
dependencies:
6+
- python=3.10.14
7+
- numpy=1.26.4 # dpnp theoretically requires numpy<=1.24.4, numba-dpex numpy>=1.26.4; seems that 1.26.4 works fine even for dpnp
8+
- matplotlib
9+
- pandas
10+
- scipy
11+
- dpnp
12+
- dace
13+
- numba
14+
- pythran
15+
- cupy
16+
# pygount has to be installed via pip
17+

framework_info/dpnp_cpu.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"framework": {
3+
"simple_name": "dpnp_cpu",
4+
"full_name": "Dpnp_CPU",
5+
"prefix": "dpc",
6+
"postfix": "dpnp_cpu",
7+
"class": "DpnpFramework",
8+
"arch": "cpu"
9+
}
10+
}

framework_info/dpnp_gpu.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"framework": {
3+
"simple_name": "dpnp_gpu",
4+
"full_name": "Dpnp_GPU",
5+
"prefix": "dpg",
6+
"postfix": "dpnp_gpu",
7+
"class": "DpnpFramework",
8+
"arch": "gpu"
9+
}
10+
}
11+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import dpnp as np
2+
3+
def build_up_b(b, rho, dt, u, v, dx, dy):
4+
b[1:-1, 1:-1] = (
5+
rho * (
6+
(1 / dt * ((u[1:-1, 2:] - u[1:-1, 0:-2]) / (2 * dx) +
7+
(v[2:, 1:-1] - v[0:-2, 1:-1]) / (2 * dy))) -
8+
((u[1:-1, 2:] - u[1:-1, 0:-2]) / (2 * dx))**2 -
9+
2 * ((u[2:, 1:-1] - u[0:-2, 1:-1]) / (2 * dy) *
10+
(v[1:-1, 2:] - v[1:-1, 0:-2]) / (2 * dx)) -
11+
((v[2:, 1:-1] - v[0:-2, 1:-1]) / (2 * dy))**2
12+
)
13+
)
14+
15+
def pressure_poisson(nit, p, dx, dy, b):
16+
pn = np.empty_like(p)
17+
for q in range(nit):
18+
pn[:] = p.copy()
19+
p[1:-1, 1:-1] = (
20+
((pn[1:-1, 2:] + pn[1:-1, 0:-2]) * dy**2 +
21+
(pn[2:, 1:-1] + pn[0:-2, 1:-1]) * dx**2) /
22+
(2 * (dx**2 + dy**2)) - dx**2 * dy**2 /
23+
(2 * (dx**2 + dy**2)) * b[1:-1, 1:-1]
24+
)
25+
26+
p[:, -1] = p[:, -2] # dp/dx = 0 at x = 2
27+
p[0, :] = p[1, :] # dp/dy = 0 at y = 0
28+
p[:, 0] = p[:, 1] # dp/dx = 0 at x = 0
29+
p[-1, :] = 0 # p = 0 at y = 2
30+
31+
def cavity_flow(nx, ny, nt, nit, u, v, dt, dx, dy, p, rho, nu):
32+
un = np.empty_like(u)
33+
vn = np.empty_like(v)
34+
b = np.zeros((ny, nx))
35+
36+
for n in range(nt):
37+
un[:] = u.copy()
38+
vn[:] = v.copy()
39+
40+
build_up_b(b, rho, dt, u, v, dx, dy)
41+
pressure_poisson(nit, p, dx, dy, b)
42+
43+
u[1:-1, 1:-1] = (
44+
un[1:-1, 1:-1] - un[1:-1, 1:-1] * dt / dx *
45+
(un[1:-1, 1:-1] - un[1:-1, 0:-2]) -
46+
vn[1:-1, 1:-1] * dt / dy *
47+
(un[1:-1, 1:-1] - un[0:-2, 1:-1]) - dt / (2 * rho * dx) *
48+
(p[1:-1, 2:] - p[1:-1, 0:-2]) + nu *
49+
(dt / dx**2 *
50+
(un[1:-1, 2:] - 2 * un[1:-1, 1:-1] + un[1:-1, 0:-2]) +
51+
dt / dy**2 *
52+
(un[2:, 1:-1] - 2 * un[1:-1, 1:-1] + un[0:-2, 1:-1]))
53+
)
54+
55+
v[1:-1, 1:-1] = (
56+
vn[1:-1, 1:-1] - un[1:-1, 1:-1] * dt / dx *
57+
(vn[1:-1, 1:-1] - vn[1:-1, 0:-2]) -
58+
vn[1:-1, 1:-1] * dt / dy *
59+
(vn[1:-1, 1:-1] - vn[0:-2, 1:-1]) - dt / (2 * rho * dy) *
60+
(p[2:, 1:-1] - p[0:-2, 1:-1]) + nu *
61+
(dt / dx**2 *
62+
(vn[1:-1, 2:] - 2 * vn[1:-1, 1:-1] + vn[1:-1, 0:-2]) +
63+
dt / dy**2 *
64+
(vn[2:, 1:-1] - 2 * vn[1:-1, 1:-1] + vn[0:-2, 1:-1]))
65+
)
66+
67+
u[0, :] = 0
68+
u[:, 0] = 0
69+
u[:, -1] = 0
70+
u[-1, :] = 1 # set velocity on cavity lid equal to 1
71+
v[0, :] = 0
72+
v[-1, :] = 0
73+
v[:, 0] = 0
74+
v[:, -1] = 0
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import dpnp as np
2+
3+
def build_up_b(rho, dt, dx, dy, u, v):
4+
b = np.zeros_like(u)
5+
b[1:-1,
6+
1:-1] = (rho * (1 / dt * ((u[1:-1, 2:] - u[1:-1, 0:-2]) / (2 * dx) +
7+
(v[2:, 1:-1] - v[0:-2, 1:-1]) / (2 * dy)) -
8+
((u[1:-1, 2:] - u[1:-1, 0:-2]) / (2 * dx))**2 - 2 *
9+
((u[2:, 1:-1] - u[0:-2, 1:-1]) / (2 * dy) *
10+
(v[1:-1, 2:] - v[1:-1, 0:-2]) / (2 * dx)) -
11+
((v[2:, 1:-1] - v[0:-2, 1:-1]) / (2 * dy))**2))
12+
13+
# Periodic BC Pressure @ x = 2
14+
b[1:-1, -1] = (rho * (1 / dt * ((u[1:-1, 0] - u[1:-1, -2]) / (2 * dx) +
15+
(v[2:, -1] - v[0:-2, -1]) / (2 * dy)) -
16+
((u[1:-1, 0] - u[1:-1, -2]) / (2 * dx))**2 - 2 *
17+
((u[2:, -1] - u[0:-2, -1]) / (2 * dy) *
18+
(v[1:-1, 0] - v[1:-1, -2]) / (2 * dx)) -
19+
((v[2:, -1] - v[0:-2, -1]) / (2 * dy))**2))
20+
21+
# Periodic BC Pressure @ x = 0
22+
b[1:-1, 0] = (rho * (1 / dt * ((u[1:-1, 1] - u[1:-1, -1]) / (2 * dx) +
23+
(v[2:, 0] - v[0:-2, 0]) / (2 * dy)) -
24+
((u[1:-1, 1] - u[1:-1, -1]) / (2 * dx))**2 - 2 *
25+
((u[2:, 0] - u[0:-2, 0]) / (2 * dy) *
26+
(v[1:-1, 1] - v[1:-1, -1]) /
27+
(2 * dx)) - ((v[2:, 0] - v[0:-2, 0]) / (2 * dy))**2))
28+
29+
return b
30+
31+
32+
def pressure_poisson_periodic(nit, p, dx, dy, b):
33+
pn = np.empty_like(p)
34+
35+
for q in range(nit):
36+
pn = p.copy()
37+
p[1:-1, 1:-1] = (((pn[1:-1, 2:] + pn[1:-1, 0:-2]) * dy**2 +
38+
(pn[2:, 1:-1] + pn[0:-2, 1:-1]) * dx**2) /
39+
(2 * (dx**2 + dy**2)) - dx**2 * dy**2 /
40+
(2 * (dx**2 + dy**2)) * b[1:-1, 1:-1])
41+
42+
# Periodic BC Pressure @ x = 2
43+
p[1:-1, -1] = (((pn[1:-1, 0] + pn[1:-1, -2]) * dy**2 +
44+
(pn[2:, -1] + pn[0:-2, -1]) * dx**2) /
45+
(2 * (dx**2 + dy**2)) - dx**2 * dy**2 /
46+
(2 * (dx**2 + dy**2)) * b[1:-1, -1])
47+
48+
# Periodic BC Pressure @ x = 0
49+
p[1:-1,
50+
0] = (((pn[1:-1, 1] + pn[1:-1, -1]) * dy**2 +
51+
(pn[2:, 0] + pn[0:-2, 0]) * dx**2) / (2 * (dx**2 + dy**2)) -
52+
dx**2 * dy**2 / (2 * (dx**2 + dy**2)) * b[1:-1, 0])
53+
54+
# Wall boundary conditions, pressure
55+
p[-1, :] = p[-2, :] # dp/dy = 0 at y = 2
56+
p[0, :] = p[1, :] # dp/dy = 0 at y = 0
57+
58+
59+
def channel_flow(nit, u, v, dt, dx, dy, p, rho, nu, F):
60+
udiff = 1
61+
stepcount = 0
62+
63+
while udiff > .001:
64+
un = u.copy()
65+
vn = v.copy()
66+
67+
b = build_up_b(rho, dt, dx, dy, u, v)
68+
pressure_poisson_periodic(nit, p, dx, dy, b)
69+
70+
u[1:-1,
71+
1:-1] = (un[1:-1, 1:-1] - un[1:-1, 1:-1] * dt / dx *
72+
(un[1:-1, 1:-1] - un[1:-1, 0:-2]) -
73+
vn[1:-1, 1:-1] * dt / dy *
74+
(un[1:-1, 1:-1] - un[0:-2, 1:-1]) - dt / (2 * rho * dx) *
75+
(p[1:-1, 2:] - p[1:-1, 0:-2]) + nu *
76+
(dt / dx**2 *
77+
(un[1:-1, 2:] - 2 * un[1:-1, 1:-1] + un[1:-1, 0:-2]) +
78+
dt / dy**2 *
79+
(un[2:, 1:-1] - 2 * un[1:-1, 1:-1] + un[0:-2, 1:-1])) +
80+
F * dt)
81+
82+
v[1:-1,
83+
1:-1] = (vn[1:-1, 1:-1] - un[1:-1, 1:-1] * dt / dx *
84+
(vn[1:-1, 1:-1] - vn[1:-1, 0:-2]) -
85+
vn[1:-1, 1:-1] * dt / dy *
86+
(vn[1:-1, 1:-1] - vn[0:-2, 1:-1]) - dt / (2 * rho * dy) *
87+
(p[2:, 1:-1] - p[0:-2, 1:-1]) + nu *
88+
(dt / dx**2 *
89+
(vn[1:-1, 2:] - 2 * vn[1:-1, 1:-1] + vn[1:-1, 0:-2]) +
90+
dt / dy**2 *
91+
(vn[2:, 1:-1] - 2 * vn[1:-1, 1:-1] + vn[0:-2, 1:-1])))
92+
93+
# Periodic BC u @ x = 2
94+
u[1:-1, -1] = (
95+
un[1:-1, -1] - un[1:-1, -1] * dt / dx *
96+
(un[1:-1, -1] - un[1:-1, -2]) - vn[1:-1, -1] * dt / dy *
97+
(un[1:-1, -1] - un[0:-2, -1]) - dt / (2 * rho * dx) *
98+
(p[1:-1, 0] - p[1:-1, -2]) + nu *
99+
(dt / dx**2 *
100+
(un[1:-1, 0] - 2 * un[1:-1, -1] + un[1:-1, -2]) + dt / dy**2 *
101+
(un[2:, -1] - 2 * un[1:-1, -1] + un[0:-2, -1])) + F * dt)
102+
103+
# Periodic BC u @ x = 0
104+
u[1:-1,
105+
0] = (un[1:-1, 0] - un[1:-1, 0] * dt / dx *
106+
(un[1:-1, 0] - un[1:-1, -1]) - vn[1:-1, 0] * dt / dy *
107+
(un[1:-1, 0] - un[0:-2, 0]) - dt / (2 * rho * dx) *
108+
(p[1:-1, 1] - p[1:-1, -1]) + nu *
109+
(dt / dx**2 *
110+
(un[1:-1, 1] - 2 * un[1:-1, 0] + un[1:-1, -1]) + dt / dy**2 *
111+
(un[2:, 0] - 2 * un[1:-1, 0] + un[0:-2, 0])) + F * dt)
112+
113+
# Periodic BC v @ x = 2
114+
v[1:-1, -1] = (
115+
vn[1:-1, -1] - un[1:-1, -1] * dt / dx *
116+
(vn[1:-1, -1] - vn[1:-1, -2]) - vn[1:-1, -1] * dt / dy *
117+
(vn[1:-1, -1] - vn[0:-2, -1]) - dt / (2 * rho * dy) *
118+
(p[2:, -1] - p[0:-2, -1]) + nu *
119+
(dt / dx**2 *
120+
(vn[1:-1, 0] - 2 * vn[1:-1, -1] + vn[1:-1, -2]) + dt / dy**2 *
121+
(vn[2:, -1] - 2 * vn[1:-1, -1] + vn[0:-2, -1])))
122+
123+
# Periodic BC v @ x = 0
124+
v[1:-1,
125+
0] = (vn[1:-1, 0] - un[1:-1, 0] * dt / dx *
126+
(vn[1:-1, 0] - vn[1:-1, -1]) - vn[1:-1, 0] * dt / dy *
127+
(vn[1:-1, 0] - vn[0:-2, 0]) - dt / (2 * rho * dy) *
128+
(p[2:, 0] - p[0:-2, 0]) + nu *
129+
(dt / dx**2 *
130+
(vn[1:-1, 1] - 2 * vn[1:-1, 0] + vn[1:-1, -1]) + dt / dy**2 *
131+
(vn[2:, 0] - 2 * vn[1:-1, 0] + vn[0:-2, 0])))
132+
133+
# Wall BC: u,v = 0 @ y = 0,2
134+
u[0, :] = 0
135+
u[-1, :] = 0
136+
v[0, :] = 0
137+
v[-1, :] = 0
138+
139+
udiff = (np.sum(u) - np.sum(un)) / np.sum(u)
140+
stepcount += 1
141+
142+
return stepcount
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import dpnp as np
2+
3+
def contour_integral(NR, NM, slab_per_bc, Ham, int_pts, Y):
4+
P0 = np.zeros((NR, NM), dtype=np.complex128)
5+
P1 = np.zeros((NR, NM), dtype=np.complex128)
6+
7+
for z in int_pts:
8+
Tz = np.zeros((NR, NR), dtype=np.complex128)
9+
10+
for n in range(slab_per_bc + 1):
11+
zz = np.power(z, slab_per_bc / 2 - n)
12+
Tz += zz * Ham[n]
13+
14+
if NR == NM:
15+
X = np.linalg.inv(Tz)
16+
else:
17+
X = np.linalg.solve(Tz, Y)
18+
19+
if abs(z) < 1.0:
20+
X = -X
21+
22+
P0 += X
23+
P1 += z * X
24+
25+
return P0, P1
26+

0 commit comments

Comments
 (0)