Skip to content

Commit 230aafc

Browse files
efaulhaberLasNikas
authored andcommitted
Avoid bounds checking where it is safe to do so (trixi-framework#656)
* Avoid bounds checking where it is safe to do so * Avoid one more bounds check in density diffusion * Reformat code * Use `extract_svector` from PointNeighbors.jl * Revert 09ab7ba * Fix tests
1 parent fc3a38d commit 230aafc

File tree

9 files changed

+87
-65
lines changed

9 files changed

+87
-65
lines changed

src/TrixiParticles.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module TrixiParticles
33
using Reexport: @reexport
44

55
using Adapt: Adapt
6+
using Base: @propagate_inbounds
67
using CSV: CSV
78
using Dates
89
using DataFrames: DataFrame

src/general/density_calculators.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ difference of the coordinates, ``v_{ab} = v_a - v_b`` of the velocities of parti
2323
"""
2424
struct ContinuityDensity end
2525

26-
@inline function particle_density(v, system, particle)
26+
@propagate_inbounds function particle_density(v, system, particle)
2727
particle_density(v, system.density_calculator, system, particle)
2828
end
2929

30-
@inline function particle_density(v, ::SummationDensity, system, particle)
30+
@propagate_inbounds function particle_density(v, ::SummationDensity, system, particle)
3131
return system.cache.density[particle]
3232
end
3333

34-
@inline function particle_density(v, ::ContinuityDensity, system, particle)
34+
@propagate_inbounds function particle_density(v, ::ContinuityDensity, system, particle)
3535
return v[end, particle]
3636
end
3737

src/general/system.jl

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,28 +54,31 @@ initialize!(system, neighborhood_search) = system
5454
@inline active_particles(system, ::Nothing) = eachparticle(system)
5555

5656
# This should not be dispatched by system type. We always expect to get a column of `A`.
57-
@inline function extract_svector(A, system, i)
57+
@propagate_inbounds function extract_svector(A, system, i)
5858
extract_svector(A, Val(ndims(system)), i)
5959
end
6060

6161
# Return the `i`-th column of the array `A` as an `SVector`.
6262
@inline function extract_svector(A, ::Val{NDIMS}, i) where {NDIMS}
63-
return SVector(ntuple(@inline(dim->A[dim, i]), NDIMS))
63+
# Explicit bounds check, which can be removed by calling this function with `@inbounds`
64+
@boundscheck checkbounds(A, NDIMS, i)
65+
66+
# Assume inbounds access now
67+
return SVector(ntuple(@inline(dim->@inbounds A[dim, i]), NDIMS))
6468
end
6569

6670
# Return `A[:, :, i]` as an `SMatrix`.
6771
@inline function extract_smatrix(A, system, particle)
6872
# Extract the matrix elements for this particle as a tuple to pass to SMatrix
69-
return SMatrix{ndims(system), ndims(system)}(
70-
# Convert linear index to Cartesian index
71-
ntuple(@inline(i->A[mod(i - 1, ndims(system)) + 1,
72-
div(i - 1, ndims(system)) + 1,
73-
particle]),
74-
Val(ndims(system)^2)))
73+
return SMatrix{ndims(system),
74+
ndims(system)}(ntuple(@inline(i->A[mod(i - 1, ndims(system)) + 1,
75+
div(i - 1, ndims(system)) + 1,
76+
particle]),
77+
Val(ndims(system)^2)))
7578
end
7679

7780
# Specifically get the current coordinates of a particle for all system types.
78-
@inline function current_coords(u, system, particle)
81+
@propagate_inbounds function current_coords(u, system, particle)
7982
return extract_svector(current_coordinates(u, system), system, particle)
8083
end
8184

@@ -91,7 +94,8 @@ end
9194
# This can be dispatched by system type.
9295
@inline initial_coordinates(system) = system.initial_condition.coordinates
9396

94-
@inline current_velocity(v, system, particle) = extract_svector(v, system, particle)
97+
@propagate_inbounds current_velocity(v, system, particle) = extract_svector(v, system,
98+
particle)
9599

96100
@inline function current_acceleration(system, particle)
97101
# TODO: Return `dv` of solid particles

src/schemes/fluid/fluid.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function create_cache_density(ic, ::ContinuityDensity)
1313
return (;)
1414
end
1515

16-
@inline hydrodynamic_mass(system::FluidSystem, particle) = system.mass[particle]
16+
@propagate_inbounds hydrodynamic_mass(system::FluidSystem, particle) = system.mass[particle]
1717

1818
function write_u0!(u0, system::FluidSystem)
1919
(; initial_condition) = system

src/schemes/fluid/viscosity.jl

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
# Unpack the neighboring systems viscosity to dispatch on the viscosity type
3-
@inline function dv_viscosity(particle_system, neighbor_system,
4-
v_particle_system, v_neighbor_system,
5-
particle, neighbor, pos_diff, distance,
6-
sound_speed, m_a, m_b, rho_a, rho_b, grad_kernel)
3+
@propagate_inbounds function dv_viscosity(particle_system, neighbor_system,
4+
v_particle_system, v_neighbor_system,
5+
particle, neighbor, pos_diff, distance,
6+
sound_speed, m_a, m_b, rho_a, rho_b, grad_kernel)
77
viscosity = viscosity_model(particle_system, neighbor_system)
88

99
return dv_viscosity(viscosity, particle_system, neighbor_system,
@@ -12,10 +12,10 @@
1212
sound_speed, m_a, m_b, rho_a, rho_b, grad_kernel)
1313
end
1414

15-
@inline function dv_viscosity(viscosity, particle_system, neighbor_system,
16-
v_particle_system, v_neighbor_system,
17-
particle, neighbor, pos_diff, distance,
18-
sound_speed, m_a, m_b, rho_a, rho_b, grad_kernel)
15+
@propagate_inbounds function dv_viscosity(viscosity, particle_system, neighbor_system,
16+
v_particle_system, v_neighbor_system,
17+
particle, neighbor, pos_diff, distance,
18+
sound_speed, m_a, m_b, rho_a, rho_b, grad_kernel)
1919
return viscosity(particle_system, neighbor_system,
2020
v_particle_system, v_neighbor_system,
2121
particle, neighbor, pos_diff, distance,
@@ -105,12 +105,16 @@ function kinematic_viscosity(system, viscosity::ViscosityMorris)
105105
return viscosity.nu
106106
end
107107

108-
@inline function (viscosity::Union{ArtificialViscosityMonaghan,
109-
ViscosityMorris})(particle_system, neighbor_system,
110-
v_particle_system, v_neighbor_system,
111-
particle, neighbor, pos_diff,
112-
distance, sound_speed, m_a, m_b,
113-
rho_a, rho_b, grad_kernel)
108+
@propagate_inbounds function (viscosity::Union{ArtificialViscosityMonaghan,
109+
ViscosityMorris})(particle_system,
110+
neighbor_system,
111+
v_particle_system,
112+
v_neighbor_system,
113+
particle, neighbor,
114+
pos_diff, distance,
115+
sound_speed,
116+
m_a, m_b, rho_a, rho_b,
117+
grad_kernel)
114118
(; smoothing_length) = particle_system
115119

116120
rho_mean = 0.5 * (rho_a + rho_b)
@@ -250,4 +254,6 @@ function kinematic_viscosity(system, viscosity::ViscosityAdami)
250254
return viscosity.nu
251255
end
252256

253-
@inline viscous_velocity(v, system, particle) = current_velocity(v, system, particle)
257+
@propagate_inbounds function viscous_velocity(v, system, particle)
258+
return current_velocity(v, system, particle)
259+
end

src/schemes/fluid/weakly_compressible_sph/density_diffusion.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ function update!(density_diffusion::DensityDiffusionAntuono, neighborhood_search
199199
return density_diffusion
200200
end
201201

202-
@inline function density_diffusion!(dv, density_diffusion::DensityDiffusion,
203-
v_particle_system, particle, neighbor, pos_diff,
204-
distance, m_b, rho_a, rho_b,
205-
particle_system::FluidSystem, grad_kernel)
202+
@propagate_inbounds function density_diffusion!(dv, density_diffusion::DensityDiffusion,
203+
v_particle_system, particle, neighbor,
204+
pos_diff, distance, m_b, rho_a, rho_b,
205+
particle_system::FluidSystem, grad_kernel)
206206
# Density diffusion terms are all zero for distance zero
207207
distance < sqrt(eps()) && return
208208

src/schemes/fluid/weakly_compressible_sph/rhs.jl

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,47 @@ function interact!(dv, v_particle_system, u_particle_system,
2323
foreach_point_neighbor(particle_system, neighbor_system,
2424
system_coords, neighbor_system_coords,
2525
neighborhood_search) do particle, neighbor, pos_diff, distance
26-
rho_a = particle_density(v_particle_system, particle_system, particle)
27-
rho_b = particle_density(v_neighbor_system, neighbor_system, neighbor)
26+
# `foreach_point_neighbor` makes sure that `particle` and `neighbor` are
27+
# in bounds of the respective system. For performance reasons, we use `@inbounds`
28+
# in this hot loop to avoid bounds checking when extracting particle quantities.
29+
rho_a = @inbounds particle_density(v_particle_system, particle_system, particle)
30+
rho_b = @inbounds particle_density(v_neighbor_system, neighbor_system, neighbor)
2831
rho_mean = 0.5 * (rho_a + rho_b)
2932

30-
# Determine correction values
31-
viscosity_correction, pressure_correction, surface_tension_correction = free_surface_correction(correction,
32-
particle_system,
33-
rho_mean)
33+
# Determine correction factors.
34+
# This can be ignored, as these are all 1 when no correction is used.
35+
(viscosity_correction, pressure_correction,
36+
surface_tension_correction) = free_surface_correction(correction, particle_system,
37+
rho_mean)
3438

3539
grad_kernel = smoothing_kernel_grad(particle_system, pos_diff, distance, particle)
3640

37-
m_a = hydrodynamic_mass(particle_system, particle)
38-
m_b = hydrodynamic_mass(neighbor_system, neighbor)
41+
m_a = @inbounds hydrodynamic_mass(particle_system, particle)
42+
m_b = @inbounds hydrodynamic_mass(neighbor_system, neighbor)
3943

4044
# The following call is equivalent to
4145
# `p_a = particle_pressure(v_particle_system, particle_system, particle)`
4246
# `p_b = particle_pressure(v_neighbor_system, neighbor_system, neighbor)`
4347
# Only when the neighbor system is a `BoundarySPHSystem` or a `TotalLagrangianSPHSystem`
4448
# with the boundary model `PressureMirroring`, this will return `p_b = p_a`, which is
4549
# the pressure of the fluid particle.
46-
p_a, p_b = particle_neighbor_pressure(v_particle_system, v_neighbor_system,
47-
particle_system, neighbor_system,
48-
particle, neighbor)
50+
p_a, p_b = @inbounds particle_neighbor_pressure(v_particle_system,
51+
v_neighbor_system,
52+
particle_system, neighbor_system,
53+
particle, neighbor)
4954

5055
dv_pressure = pressure_correction *
5156
pressure_acceleration(particle_system, neighbor_system, neighbor,
5257
m_a, m_b, p_a, p_b, rho_a, rho_b, pos_diff,
5358
distance, grad_kernel, correction)
5459

60+
# Propagate `@inbounds` to the viscosity function, which accesses particle data
5561
dv_viscosity_ = viscosity_correction *
56-
dv_viscosity(particle_system, neighbor_system,
57-
v_particle_system, v_neighbor_system,
58-
particle, neighbor, pos_diff, distance,
59-
sound_speed, m_a, m_b, rho_a, rho_b, grad_kernel)
62+
@inbounds dv_viscosity(particle_system, neighbor_system,
63+
v_particle_system, v_neighbor_system,
64+
particle, neighbor, pos_diff, distance,
65+
sound_speed, m_a, m_b, rho_a, rho_b,
66+
grad_kernel)
6067

6168
dv_surface_tension = surface_tension_correction *
6269
surface_tension_force(surface_tension_a, surface_tension_b,
@@ -66,17 +73,19 @@ function interact!(dv, v_particle_system, u_particle_system,
6673
dv_adhesion = adhesion_force(surface_tension, particle_system, neighbor_system,
6774
particle, neighbor, pos_diff, distance)
6875

69-
@inbounds for i in 1:ndims(particle_system)
70-
dv[i, particle] += dv_pressure[i] + dv_viscosity_[i] + dv_surface_tension[i] +
71-
dv_adhesion[i]
76+
for i in 1:ndims(particle_system)
77+
@inbounds dv[i, particle] += dv_pressure[i] + dv_viscosity_[i] +
78+
dv_surface_tension[i] + dv_adhesion[i]
7279
# Debug example
7380
# debug_array[i, particle] += dv_pressure[i]
7481
end
7582

7683
# TODO If variable smoothing_length is used, this should use the neighbor smoothing length
77-
continuity_equation!(dv, density_calculator, v_particle_system, v_neighbor_system,
78-
particle, neighbor, pos_diff, distance, m_b, rho_a, rho_b,
79-
particle_system, neighbor_system, grad_kernel)
84+
# Propagate `@inbounds` to the continuity equation, which accesses particle data
85+
@inbounds continuity_equation!(dv, density_calculator, v_particle_system,
86+
v_neighbor_system, particle, neighbor,
87+
pos_diff, distance, m_b, rho_a, rho_b,
88+
particle_system, neighbor_system, grad_kernel)
8089
end
8190
# Debug example
8291
# periodic_box = neighborhood_search.periodic_box
@@ -98,12 +107,12 @@ end
98107
end
99108

100109
# This formulation was chosen to be consistent with the used pressure_acceleration formulations.
101-
@inline function continuity_equation!(dv, density_calculator::ContinuityDensity,
102-
v_particle_system, v_neighbor_system,
103-
particle, neighbor, pos_diff, distance,
104-
m_b, rho_a, rho_b,
105-
particle_system::WeaklyCompressibleSPHSystem,
106-
neighbor_system, grad_kernel)
110+
@propagate_inbounds function continuity_equation!(dv, density_calculator::ContinuityDensity,
111+
v_particle_system, v_neighbor_system,
112+
particle, neighbor, pos_diff, distance,
113+
m_b, rho_a, rho_b,
114+
particle_system::WeaklyCompressibleSPHSystem,
115+
neighbor_system, grad_kernel)
107116
(; density_diffusion) = particle_system
108117

109118
vdiff = current_velocity(v_particle_system, particle_system, particle) -
@@ -121,9 +130,10 @@ end
121130
end
122131
end
123132

124-
@inline function particle_neighbor_pressure(v_particle_system, v_neighbor_system,
125-
particle_system, neighbor_system,
126-
particle, neighbor)
133+
@propagate_inbounds function particle_neighbor_pressure(v_particle_system,
134+
v_neighbor_system,
135+
particle_system, neighbor_system,
136+
particle, neighbor)
127137
p_a = particle_pressure(v_particle_system, particle_system, particle)
128138
p_b = particle_pressure(v_neighbor_system, neighbor_system, neighbor)
129139

src/schemes/fluid/weakly_compressible_sph/system.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ end
211211
return ndims(system) + 1
212212
end
213213

214-
@inline function particle_pressure(v, system::WeaklyCompressibleSPHSystem, particle)
214+
@propagate_inbounds function particle_pressure(v, system::WeaklyCompressibleSPHSystem,
215+
particle)
215216
return system.pressure[particle]
216217
end
217218

test/systems/solid_system.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
Base.ntuple(f, ::Symbol) = ntuple(f, 2) # Make `extract_svector` work
132132
function TrixiParticles.current_coords(system::Val{:mock_system_tensor},
133133
particle)
134-
return TrixiParticles.extract_svector(current_coordinates[i], system,
134+
return TrixiParticles.extract_svector(current_coordinates[i], Val(2),
135135
particle)
136136
end
137137

0 commit comments

Comments
 (0)