You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
while experimenting with parallelizing Hamiltonian multiplication, I encountered some weird behaviour when trying to multi-thread Hamiltonian block multiplications. I first suspected my multithreading to somehow interfere with the internal multithreading, however this persisted even when using DFTK.disable_threading().
using DFTK
using LinearAlgebra
DFTK.disable_threading()
# setupfunctionsilicon_setup(; Ecut =15, a =10.26, kgrid=[2, 2, 2], supercell_size = [1,1,1])
# Silicon lattice constant in Bohr
lattice = a /2* [[011.];
[101.];
[110.]]
Si =ElementPsp(:Si; psp=load_psp("hgh/lda/Si-q4"))
atoms = [Si, Si]
positions = [ones(3)/8, -ones(3)/8]
if (prod(supercell_size) !=1)
lattice, atoms, positions =create_supercell(lattice, atoms, positions, supercell_size)
end
model =model_LDA(lattice, atoms, positions)
basis =PlaneWaveBasis(model; Ecut=Ecut, kgrid)
return [model, basis]
end
model, basis =silicon_setup();
filled_occ = DFTK.filled_occupation(model)
n_spin = model.n_spin_components
n_bands =div(model.n_electrons, n_spin * filled_occ, RoundUp)
Nk =length(basis.kpoints)
occupation = [filled_occ *ones(Float64, n_bands) for ik =1:Nk]
ψ = [DFTK.random_orbitals(basis, kpt, n_bands) for kpt in basis.kpoints];
ρ =guess_density(basis);
energies, H =energy_hamiltonian(basis, ψ, occupation; ρ)
# no multithreading
result_H_1 = [Array{ComplexF64}(undef, size(ψk)) for ψk = ψ]
for ik =1:Nk
result_H_1[ik] .= H.blocks[ik] * ψ[ik]
end# multithreading
result_H_2 = [Array{ComplexF64}(undef, size(ψk)) for ψk = ψ]
nthreads = Threads.nthreads()
chunk_length =cld(Nk, nthreads)
@syncfor (ichunk, chunk) inenumerate(Iterators.partition(1:Nk, chunk_length))
Threads.@spawnfor ik in chunk # spawn a task per chunk
result_H_2[ik] .= H.blocks[ik] * ψ[ik]
endend
err_H = [norm(result_H_1[ik] - result_H_2[ik]) for ik =1:Nk]
println("Error in H: $err_H")
When running with one thread, everything works as intended.
However, when running with >1 threads, weird things start happening. The result is non-deterministic, as if it was just random memory. For 2 threads, sometimes results with "reasonably small" error ~ 1e-1 can occur. For >2 threads, I have so far encountered various errors, even segfaults.
I suppose that different threads are trying to use the same scratch from DftHamiltonianBlock. Classic data race. 😄 I suppose that Hamiltonians are not threadsafe.
Yes, we use mpi to parallelize kpoints and threads to parallelize bands. I'm not sure how to solve this, other than documenting somewhere that you shouldn't do it. If you really want to do it a hack is to copy the hamiltonian nthreads() times and use a different one for each thread
Hi all,
while experimenting with parallelizing Hamiltonian multiplication, I encountered some weird behaviour when trying to multi-thread Hamiltonian block multiplications. I first suspected my multithreading to somehow interfere with the internal multithreading, however this persisted even when using
DFTK.disable_threading()
.When running with one thread, everything works as intended.
However, when running with >1 threads, weird things start happening. The result is non-deterministic, as if it was just random memory. For 2 threads, sometimes results with "reasonably small" error ~ 1e-1 can occur. For >2 threads, I have so far encountered various errors, even segfaults.
Is there something I am missing?
The text was updated successfully, but these errors were encountered: