Address computation in the generated pyop3 loops

Aperta
#5,588 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
42/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
c, python

Direzione di ricerca

Start by tracing pyop3's generated loop and the compressed indirection maps used for gather and scatter; the issue does not name source files or tests. Reproduce the supplied serial comparison, then inspect how a flat cell node map could be built and reused. Done means the generated loops match PyOP2's timings on the supplied triangle and extruded quad cases without changing the TSFC kernel.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Hi @connorjward, while looking into why G-ADOPT got slower after the switch to pyop3 I noticed that the time inside the compiled loops is higher than with PyOP2. I wanted to ask whether what I see is by design or something that could be optimised.

For each DoF the generated loop reads the cell closure, then the section offset and the orientation of that point, and then copies the packed values once more through a node permutation table. The scatter after the kernel does the same. PyOP2 read one precomputed cell node map. This is the gather of one P2 vector coefficient on triangles (c is the cell, index names shortened):

/* pyop3 */
for (i = 0; i < 3; ++i) for (j = 0; j < 2; ++j)
  t_3[2*i + j] = dat_3[idat_5[idat_1[3*c + i]] + idat_6[idat_3[3*c + i]]*2 + j];
for (i = 0; i < 3; ++i) for (j = 0; j < 2; ++j)
  t_3[6 + 2*i + j] = dat_3[idat_5[idat_7[3*c + i]] + idat_8[idat_9[3 + 7*c + i]]*2 + j];
for (i = 0; i < 6; ++i) for (j = 0; j < 2; ++j)
  t_4[2*i + j] = t_3[idat_10[i]*2 + j];

/* PyOP2 */
for (i = 0; i < 6; ++i) for (j = 0; j < 2; ++j)
  t2[2*i + j] = dat2[2*map0[6*c + i] + j];

The TSFC kernel is the same in both. For the residual of a P2 vector Laplacian with a P1 coefficient (script below) the time inside the compiled call per assemble is

mesh PyOP2 pyop3
triangles, 131k cells 4.55 ms 6.32 ms
extruded quads, 65k cells 5.77 ms 7.60 ms

This is serial with the default flags, pyop3 main (a591c1426) against the last PyOP2 commit (2093d46b4). I timed the C call on its own. The script prints the whole assemble, which adds 0.6 to 0.7 ms in both. When I changed the generated loop by hand to read through a flat map built on the first call it ran at the PyOP2 time. These loops already run with compress_indirection_maps.

Script
import sys, time
from firedrake import *

mesh = {"tri": lambda: UnitSquareMesh(256, 256),
        "ext": lambda: ExtrudedMesh(UnitIntervalMesh(256), 256)}[sys.argv[1]]()
V = VectorFunctionSpace(mesh, "CG", 2)
Q = FunctionSpace(mesh, "CG", 1)
x = SpatialCoordinate(mesh)
v = TestFunction(V)
w = Function(V).interpolate(as_vector([sin(x[0]), sin(x[1] + 1)]))
f = Function(V).interpolate(as_vector([x[0] * x[1], x[0] * x[1]]))
mu = Function(Q).interpolate(1 + x[0])
c = Constant(2.0)
F = mu * inner(grad(w), grad(v)) * dx + c * inner(w, v) * dx - inner(f, v) * dx

r = assemble(F)
times = []
for _ in range(200):
    t = time.perf_counter()
    assemble(F, tensor=r)
    times.append(time.perf_counter() - t)
print(f"{sys.argv[1]}: {min(times) * 1e3:.2f} ms per assemble")
Lingua principale
Python
Stelle
684
Fork
204
Merge medio
4g 14h
PR unite (30g)
46

Preparare l'ambiente

  • Nessun Dockerfile né file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di firedrakeproject/firedrake

Tutte le issue di firedrakeproject/firedrake

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.