Thank you for the fast response @doken.
This is not the case in general, this here is just for benchmarking purposes.
I am using the development image and compiling myself using routines you provided in this post.
DOLFINX_CMAKE_BUILD_TYPE
is RELWITHDEBUG
.
I changed DOLFINX_CMAKE_BUILD_TYPE
to RELEASE
and it’s way faster. I also recover similar ratios to yours. Here is the profiling output with the same problem size as my previous post and the changed compilation flag:
Total time: 9.21398 s
File: /root/shared/cases/test_profiling/main.py
Function: main at line 59
Line # Hits Time Per Hit % Time Line Contents
==============================================================
59 def main():
60 # Mesh and problems
61 1 711.0 711.0 0.0 points_side = 512
62 1 746203133.0 7e+08 8.1 mesh1 = mesh.create_unit_square(MPI.COMM_WORLD, points_side, points_side, mesh.CellType.triangle)
63 1 501749562.0 5e+08 5.4 mesh2 = mesh.create_unit_square(MPI.COMM_WORLD, points_side, points_side, mesh.CellType.quadrilateral)
64
65 1 85418134.0 9e+07 0.9 (V1, V2) = (fem.functionspace(mesh1, ("Lagrange", 1)),fem.functionspace(mesh2, ("Lagrange", 1)))
66 1 602114.0 602114.0 0.0 (u1, u2) = (fem.Function(V1),fem.Function(V2))
67 # Solve Poisson problem on mesh1
68 1 5740625915.0 6e+09 62.3 u1 = solve(mesh1,u1)
69 # Interpolate from mesh1 to mesh2
70 1 2139375620.0 2e+09 23.2 interpolate(u1,u2)
71 # Write post
72 #write_post(mesh1,mesh2,u1,u2)
Timer unit: 1e-09 s
Total time: 2.13935 s
File: /root/shared/cases/test_profiling/main.py
Function: interpolate at line 16
Line # Hits Time Per Hit % Time Line Contents
==============================================================
16 def interpolate(sending_func,
17 receiving_func,):
18 '''
19 Interpolate sending_func to receiving_func,
20 each comming from separate meshes
21 '''
22 1 2992.0 2992.0 0.0 targetSpace = receiving_func.function_space
23 2 1625102126.0 8e+08 76.0 nmmid = dolfinx.fem.create_nonmatching_meshes_interpolation_data(
24 1 1992.0 1992.0 0.0 targetSpace.mesh,
25 1 4648.0 4648.0 0.0 targetSpace.element,
26 1 4988.0 4988.0 0.0 sending_func.ufl_function_space().mesh,
27 1 240.0 240.0 0.0 padding=0,)
28 1 514233567.0 5e+08 24.0 receiving_func.interpolate(sending_func, nmm_interpolation_data=nmmid)
29 1 662.0 662.0 0.0 return receiving_func
Total time: 5.73651 s
File: /root/shared/cases/test_profiling/main.py
Function: solve at line 31
Line # Hits Time Per Hit % Time Line Contents
==============================================================
31 def solve(domain,u):
32 '''
33 Solve Poisson problem
34 '''
35 1 2006.0 2006.0 0.0 V = u.function_space
36 # Dirichlet BC
37 1 6169.0 6169.0 0.0 cdim = domain.topology.dim
38 1 434.0 434.0 0.0 fdim = cdim-1
39 1 130067690.0 1e+08 2.3 domain.topology.create_connectivity(fdim,cdim)
40 1 834879.0 834879.0 0.0 bfacets = mesh.exterior_facet_indices(domain.topology)
41 1 358413.0 358413.0 0.0 u_bc = fem.Function(V)
42 1 55060674.0 6e+07 1.0 u_bc.interpolate(exact_sol)
43 1 791758.0 791758.0 0.0 dirichlet_bcs = [fem.dirichletbc(u_bc, fem.locate_dofs_topological(V, fdim, bfacets))]
44 # Forms
45 1 189370.0 189370.0 0.0 u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
46 1 1423918.0 1e+06 0.0 a = ufl.inner(ufl.grad(u),ufl.grad(v))*ufl.dx
47 1 552468.0 552468.0 0.0 l = rhs()*v*ufl.dx
48 2 116950761.0 6e+07 2.0 problem = dolfinx.fem.petsc.LinearProblem(a,l,
49 1 284.0 284.0 0.0 bcs=dirichlet_bcs,)
50 1 5430272793.0 5e+09 94.7 return problem.solve()
Total time: 0 s
File: /root/shared/cases/test_profiling/main.py
Function: write_post at line 52
Line # Hits Time Per Hit % Time Line Contents
==============================================================
52 def write_post(mesh1,mesh2,u1,u2):
53 writer1, writer2 = io.VTKFile(mesh1.comm, f"out/result1.vtk",'w'),io.VTKFile(mesh2.comm, f"out/result2.vtk",'w')
54 writer1.write_function(u1)
55 writer2.write_function(u2)
56 writer1.close()
57 writer2.close()
Total time: 0.568868 s
File: /root/shared/dolfinx/python/dolfinx/fem/function.py
Function: interpolate at line 419
Line # Hits Time Per Hit % Time Line Contents
==============================================================
419 def interpolate(
420 self,
421 u: typing.Union[typing.Callable, Expression, Function],
422 cells: typing.Optional[np.ndarray] = None,
423 nmm_interpolation_data: typing.Optional[PointOwnershipData] = None,
424 ) -> None:
425 """Interpolate an expression
426
427 Args:
428 u: The function, Expression or Function to interpolate.
429 cells: The cells to interpolate over. If `None` then all
430 cells are interpolated over.
431 nmm_interpolation_data: Data needed to interpolate functions defined on other meshes
432 """
433 2 2360.0 1180.0 0.0 if nmm_interpolation_data is None:
434 1 14532.0 14532.0 0.0 x_dtype = self.function_space.mesh.geometry.x.dtype
435 2 7494.0 3747.0 0.0 nmm_interpolation_data = PointOwnershipData(
436 1 5191.0 5191.0 0.0 src_owner=np.empty(0, dtype=np.int32),
437 1 1168.0 1168.0 0.0 dest_owners=np.empty(0, dtype=np.int32),
438 1 930.0 930.0 0.0 dest_points=np.empty(0, dtype=x_dtype),
439 1 906.0 906.0 0.0 dest_cells=np.empty(0, dtype=np.int32),
440 )
441
442 2 2575.0 1287.5 0.0 @singledispatch
443 2 81575.0 40787.5 0.0 def _interpolate(u, cells: typing.Optional[np.ndarray] = None):
444 """Interpolate a cpp.fem.Function"""
445 self._cpp_object.interpolate(u, cells, nmm_interpolation_data) # type: ignore
446
447 2 11195.0 5597.5 0.0 @_interpolate.register(Function)
448 2 29680.0 14840.0 0.0 def _(u: Function, cells: typing.Optional[np.ndarray] = None):
449 """Interpolate a fem.Function"""
450 self._cpp_object.interpolate(u._cpp_object, cells, nmm_interpolation_data) # type: ignore
451
452 2 4630.0 2315.0 0.0 @_interpolate.register(int)
453 2 10731.0 5365.5 0.0 def _(u_ptr: int, cells: typing.Optional[np.ndarray] = None):
454 """Interpolate using a pointer to a function f(x)"""
455 self._cpp_object.interpolate_ptr(u_ptr, cells) # type: ignore
456
457 2 3924.0 1962.0 0.0 @_interpolate.register(Expression)
458 2 9801.0 4900.5 0.0 def _(expr: Expression, cells: typing.Optional[np.ndarray] = None):
459 """Interpolate Expression for the set of cells"""
460 self._cpp_object.interpolate(expr._cpp_object, cells) # type: ignore
461
462 2 795.0 397.5 0.0 if cells is None:
463 2 5627.0 2813.5 0.0 mesh = self.function_space.mesh
464 2 21926.0 10963.0 0.0 map = mesh.topology.index_map(mesh.topology.dim)
465 2 412585.0 206292.5 0.1 cells = np.arange(map.size_local + map.num_ghosts, dtype=np.int32)
466
467 2 767.0 383.5 0.0 try:
468 # u is a Function or Expression (or pointer to one)
469 2 514046880.0 3e+08 90.4 _interpolate(u, cells)
470 1 612.0 612.0 0.0 except TypeError:
471 # u is callable
472 1 964.0 964.0 0.0 assert callable(u)
473 1 22065639.0 2e+07 3.9 x = _cpp.fem.interpolation_coords(self._V.element, self._V.mesh.geometry, cells)
474 1 32125337.0 3e+07 5.6 self._cpp_object.interpolate(np.asarray(u(x), dtype=self.dtype), cells) # type: ignore
Appreciate the help @dokken!