Working multi-precision simulations

The pure gauge theory with groups SU(2) and SU(3) is working
properly.
This commit is contained in:
Alberto Ramos 2021-09-20 18:21:16 +02:00
parent 1416efdbee
commit 09a09153b9
8 changed files with 188 additions and 283 deletions

View file

@ -13,20 +13,22 @@
# SU(2) group elements represented trough Cayley-Dickson # SU(2) group elements represented trough Cayley-Dickson
# construction # construction
# https://en.wikipedia.org/wiki/Cayley%E2%80%93Dickson_construction # https://en.wikipedia.org/wiki/Cayley%E2%80%93Dickson_construction
using CUDA using CUDA, Random
import Base.:*, Base.:+, Base.:-,Base.:/,Base.:\,Base.exp import Base.:*, Base.:+, Base.:-,Base.:/,Base.:\,Base.exp,Base.zero,Base.one
import Random.rand
struct SU2{T} <: Group struct SU2{T} <: Group
t1::Complex{T} t1::Complex{T}
t2::Complex{T} t2::Complex{T}
end end
SU2() = SU2{Float64}(complex(1.0), complex(0.0)) SU2(a::T, b::T) where T <: AbstractFloat = SU2{T}(complex(a), complex(b))
SU2(a::T, b::T) where T <: AbstractFloat = SU2{T}(complex(a), complex(b)) inverse(b::SU2{T}) where T <: AbstractFloat = SU2{T}(conj(b.t1), -b.t2)
inverse(b::SU2{T}) where T <: AbstractFloat = SU2{T}(conj(b.t1), -b.t2) dag(a::SU2{T}) where T <: AbstractFloat = inverse(a)
dag(a::SU2{T}) where T <: AbstractFloat = inverse(a) norm(a::SU2{T}) where T <: AbstractFloat = sqrt(abs2(a.t1) + abs2(a.t2))
norm(a::SU2{T}) where T <: AbstractFloat = sqrt(abs2(a.t1) + abs2(a.t2)) norm2(a::SU2{T}) where T <: AbstractFloat = abs2(a.t1) + abs2(a.t2)
norm2(a::SU2{T}) where T <: AbstractFloat = abs2(a.t1) + abs2(a.t2) tr(g::SU2{T}) where T <: AbstractFloat = complex(2.0*real(g.t1), 0.0)
tr(g::SU2{T}) where T <: AbstractFloat = complex(2.0*real(g.t1), 0.0) Base.one(::Type{SU2{T}}) where T <: AbstractFloat = SU2{T}(one(T),zero(T))
Random.rand(rng::AbstractRNG, ::Random.SamplerType{SU2{T}}) where T <: AbstractFloat = exp(SU2alg{T}(randn(rng,T),randn(rng,T),randn(rng,T)))
""" """
function normalize(a::SU2) function normalize(a::SU2)
@ -56,6 +58,9 @@ projalg(g::SU2{T}) where T <: AbstractFloat = SU2alg{T}(imag(g.t
dot(a::SU2alg{T}, b::SU2alg{T}) where T <: AbstractFloat = a.t1*b.t1 + a.t2*b.t2 + a.t3*b.t3 dot(a::SU2alg{T}, b::SU2alg{T}) where T <: AbstractFloat = a.t1*b.t1 + a.t2*b.t2 + a.t3*b.t3
norm(a::SU2alg{T}) where T <: AbstractFloat = sqrt(a.t1^2 + a.t2^2 + a.t3^2) norm(a::SU2alg{T}) where T <: AbstractFloat = sqrt(a.t1^2 + a.t2^2 + a.t3^2)
norm2(a::SU2alg{T}) where T <: AbstractFloat = a.t1^2 + a.t2^2 + a.t3^2 norm2(a::SU2alg{T}) where T <: AbstractFloat = a.t1^2 + a.t2^2 + a.t3^2
Base.zero(::Type{SU2alg{T}}) where T <: AbstractFloat = SU2alg{T}(zero(T),zero(T),zero(T))
Random.rand(rng::AbstractRNG, ::Random.SamplerType{SU2alg{T}}) where T <: AbstractFloat = SU2alg{T}(randn(rng,T),randn(rng,T),randn(rng,T))
Base.:+(a::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1,a.t2,a.t3) Base.:+(a::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1,a.t2,a.t3)
Base.:-(a::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(-a.t1,-a.t2,-a.t3) Base.:-(a::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(-a.t1,-a.t2,-a.t3)
Base.:+(a::SU2alg{T},b::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1+b.t1,a.t2+b.t2,a.t3+b.t3) Base.:+(a::SU2alg{T},b::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1+b.t1,a.t2+b.t2,a.t3+b.t3)

View file

@ -17,8 +17,10 @@
# a.u32 = conj(a.u13*a.u21 - a.u11*a.u23) # a.u32 = conj(a.u13*a.u21 - a.u11*a.u23)
# a.u33 = conj(a.u11*a.u22 - a.u12*a.u21) # a.u33 = conj(a.u11*a.u22 - a.u12*a.u21)
# #
using Random
import Base.:*, Base.:+, Base.:-,Base.:/,Base.:\ import Base.:*, Base.:+, Base.:-,Base.:/,Base.:\,Base.one,Base.zero
import Random.rand
struct SU3{T} <: Group struct SU3{T} <: Group
u11::Complex{T} u11::Complex{T}
u12::Complex{T} u12::Complex{T}
@ -27,11 +29,12 @@ struct SU3{T} <: Group
u22::Complex{T} u22::Complex{T}
u23::Complex{T} u23::Complex{T}
end end
SU3() = SU3{Float64}(1.0,0.0,0.0,0.0,1.0,0.0) inverse(a::SU3{T}) where T <: AbstractFloat = SU3{T}(conj(a.u11),conj(a.u21),(a.u12*a.u23 - a.u13*a.u22), conj(a.u12),conj(a.u22),(a.u13*a.u21 - a.u11*a.u23))
inverse(a::SU3{T}) where T <: AbstractFloat = SU3{T}(conj(a.u11),conj(a.u21),(a.u12*a.u23 - a.u13*a.u22), dag(a::SU3{T}) where T <: AbstractFloat = inverse(a)
conj(a.u12),conj(a.u22),(a.u13*a.u21 - a.u11*a.u23)) tr(a::SU3{T}) where T <: AbstractFloat = a.u11+a.u22+conj(a.u11*a.u22 - a.u12*a.u21)
dag(a::SU3{T}) where T <: AbstractFloat = inverse(a) Base.one(::Type{SU3{T}}) where T <: AbstractFloat = SU3{T}(one(T),zero(T),zero(T),zero(T),one(T),zero(T))
tr(a::SU3{T}) where T <: AbstractFloat = a.u11+a.u22+conj(a.u11*a.u22 - a.u12*a.u21) Random.rand(rng::AbstractRNG, ::Random.SamplerType{SU3{T}}) where T <: AbstractFloat = exp(SU3alg{T}(randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T)))
function Base.:*(a::SU3{T},b::SU3{T}) where T <: AbstractFloat function Base.:*(a::SU3{T},b::SU3{T}) where T <: AbstractFloat
@ -103,7 +106,7 @@ struct SU3alg{T} <: Algebra
t7::T t7::T
t8::T t8::T
end end
SU3alg() = SU3alg{Float64}(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0)
function projalg(a::SU3{T}) where T <: AbstractFloat function projalg(a::SU3{T}) where T <: AbstractFloat
sr3ov2::T = 0.866025403784438646763723170752 sr3ov2::T = 0.866025403784438646763723170752
@ -122,6 +125,9 @@ end
dot(a::SU3alg{T},b::SU3alg{T}) where T <: AbstractFloat = a.t1*b.t1 + a.t2*b.t2 + a.t3*b.t3 + a.t4*b.t4 + a.t5*b.t5 + a.t6*b.t6 + a.t7*b.t7 + a.t8*b.t8 dot(a::SU3alg{T},b::SU3alg{T}) where T <: AbstractFloat = a.t1*b.t1 + a.t2*b.t2 + a.t3*b.t3 + a.t4*b.t4 + a.t5*b.t5 + a.t6*b.t6 + a.t7*b.t7 + a.t8*b.t8
norm2(a::SU3alg{T}) where T <: AbstractFloat = a.t1^2 + a.t2^2 + a.t3^2 + a.t4^2 + a.t5^2 + a.t6^2 + a.t7^2 + a.t8^2 norm2(a::SU3alg{T}) where T <: AbstractFloat = a.t1^2 + a.t2^2 + a.t3^2 + a.t4^2 + a.t5^2 + a.t6^2 + a.t7^2 + a.t8^2
norm(a::SU3alg{T}) where T <: AbstractFloat = sqrt(a.t1^2 + a.t2^2 + a.t3^2 + a.t4^2 + a.t5^2 + a.t6^2 + a.t7^2 + a.t8^2) norm(a::SU3alg{T}) where T <: AbstractFloat = sqrt(a.t1^2 + a.t2^2 + a.t3^2 + a.t4^2 + a.t5^2 + a.t6^2 + a.t7^2 + a.t8^2)
Base.zero(::Type{SU3alg{T}}) where T <: AbstractFloat = SU3alg{T}(zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T))
Random.rand(rng::AbstractRNG, ::Random.SamplerType{SU3alg{T}}) where T <: AbstractFloat = SU3alg{T}(randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T),randn(rng,T))
Base.:+(a::SU3alg{T}) where T <: AbstractFloat = SU3alg{T}(a.t1,a.t2,a.t3,a.t4,a.t5,a.t6,a.t7,a.t8) Base.:+(a::SU3alg{T}) where T <: AbstractFloat = SU3alg{T}(a.t1,a.t2,a.t3,a.t4,a.t5,a.t6,a.t7,a.t8)
Base.:-(a::SU3alg{T}) where T <: AbstractFloat = SU3alg{T}(-a.t1,-a.t2,-a.t3,-a.t4,-a.t5,-a.t6,-a.t7,-a.t8) Base.:-(a::SU3alg{T}) where T <: AbstractFloat = SU3alg{T}(-a.t1,-a.t2,-a.t3,-a.t4,-a.t5,-a.t6,-a.t7,-a.t8)
Base.:+(a::SU3alg{T},b::SU3alg{T}) where T <: AbstractFloat = SU3alg{T}(a.t1+b.t1,a.t2+b.t2,a.t3+b.t3,a.t4+b.t4,a.t5+b.t5,a.t6+b.t6,a.t7+b.t7,a.t8+b.t8) Base.:+(a::SU3alg{T},b::SU3alg{T}) where T <: AbstractFloat = SU3alg{T}(a.t1+b.t1,a.t2+b.t2,a.t3+b.t3,a.t4+b.t4,a.t5+b.t5,a.t6+b.t6,a.t7+b.t7,a.t8+b.t8)

View file

@ -23,13 +23,13 @@ include("Space/Space.jl")
using .Space using .Space
export SpaceParm export SpaceParm
export up, dw, updw export up, dw, updw, global_point
include("YM/YM.jl") include("YM/YM.jl")
using .YM using .YM
export YMworkspace, GaugeParm, force0_wilson!, field, field_pln, randomn!, zero!, norm2 export YMworkspace, GaugeParm, force0_wilson!, field, field_pln, randomize!, zero!, norm2
export gauge_action, hamiltonian, plaquette, HMC!, OMF4! export gauge_action, hamiltonian, plaquette, HMC!, OMF4!
end # module end # module

View file

@ -12,6 +12,8 @@
module Space module Space
import Base.show
struct SpaceParm{N,M} struct SpaceParm{N,M}
ndim::Int64 ndim::Int64
iL::NTuple{N,Int64} iL::NTuple{N,Int64}
@ -53,6 +55,24 @@ struct SpaceParm{N,M}
end end
end end
export SpaceParm export SpaceParm
function Base.show(io::IO, lp::SpaceParm)
println(io, "Lattice dimensions: ", lp.ndim)
print(io, "Lattice size: ")
for i in 1:lp.ndim-1
print(io, lp.iL[i], " x ")
end
println(io,lp.iL[end])
print(io, "Thread block size: ")
for i in 1:lp.ndim-1
print(io, lp.blk[i], " x ")
end
println(io,lp.blk[end], " [", lp.bsz,
"] (Number of blocks: [", lp.rsz,"])")
return
end
@inline function up(p::NTuple{2,Int64}, id::Int64, lp::SpaceParm) @inline function up(p::NTuple{2,Int64}, id::Int64, lp::SpaceParm)
@ -131,6 +151,22 @@ end
return bu, ru, bd, rd return bu, ru, bd, rd
end end
export up, dw, updw @inline function global_point(p::NTuple{2,Int64}, lp::SpaceParm)
@inline cntb(nb, id::Int64, lp::SpaceParm) = mod(div(nb-1,lp.blkS[id]),lp.blk[id])
@inline cntr(nr, id::Int64, lp::SpaceParm) = mod(div(nr-1,lp.rbkS[id]),lp.rbk[id])
@inline cnt(nb, nr, id::Int64, lp::SpaceParm) = 1 + cntb(nb,id,lp) + cntr(nr,id,lp)*lp.blk[id]
pt = ntuple(i -> cnt(p[1], p[2], i, lp), lp.ndim)
return pt
end
@inline function point_idx(pt::NTuple{4, Int64}, lp::SpaceParm)
end
export up, dw, updw, global_point, point_idx
end end

View file

@ -16,46 +16,53 @@ using CUDA, Random, StructArrays
using ..Space using ..Space
using ..Groups using ..Groups
struct GaugeParm struct GaugeParm{T}
beta::Float64 beta::T
cG::Tuple{Float64,Float64} cG::NTuple{2,T}
ng::Int32 ng::Int64
end end
export GaugeParm export GaugeParm
include("YMfields.jl") struct YMworkspace{T}
export field, field_pln, randomn!, zero!, norm2 GRP
ALG
struct YMworkspace PRC
frc1 frc1
frc2 frc2
mom mom
U1 U1
cm # complex of volume cm # complex of volume
rm # float of volume rm # float of volume
function YMworkspace(::Type{T}, lp::SpaceParm) where {T <: Union{Group,Algebra}} function YMworkspace(::Type{G}, ::Type{T}, lp::SpaceParm) where {G <: Group, T <: AbstractFloat}
if (T == SU2) if (G == SU2)
f1 = field(SU2alg, lp) GRP = SU2
f2 = field(SU2alg, lp) ALG = SU2alg
mm = field(SU2alg, lp) f1 = field(SU2alg, T, lp)
u1 = field(SU2, lp) f2 = field(SU2alg, T, lp)
mm = field(SU2alg, T, lp)
u1 = field(SU2, T, lp)
end end
if (T == SU3) if (G == SU3)
f1 = field(SU3alg, lp) GRP = SU3
f2 = field(SU3alg, lp) ALG = SU3alg
mm = field(SU3alg, lp) f1 = field(SU3alg, T, lp)
u1 = field(SU3, lp) f2 = field(SU3alg, T, lp)
mm = field(SU3alg, T, lp)
u1 = field(SU3, T, lp)
end end
cs = CuArray{ComplexF64, 2}(undef, lp.bsz,lp.rsz) cs = CuArray{Complex{T}, 2}(undef, lp.bsz,lp.rsz)
rs = CuArray{Float64, 2}(undef, lp.bsz,lp.rsz) rs = CuArray{T, 2}(undef, lp.bsz,lp.rsz)
return new(f1, f2, mm, u1, cs, rs) return new{T}(GRP,ALG,T,f1, f2, mm, u1, cs, rs)
end end
end end
export YMworkspace export YMworkspace
include("YMfields.jl")
export field, field_pln, randomize!, zero!, norm2
include("YMact.jl") include("YMact.jl")
export krnl_plaq!, force0_wilson! export krnl_plaq!, force0_wilson!

View file

@ -16,7 +16,7 @@ function krnl_plaq!(plx, U, ipl, lp::SpaceParm)
bu1, ru1 = up((b, r), id1, lp) bu1, ru1 = up((b, r), id1, lp)
bu2, ru2 = up((b, r), id2, lp) bu2, ru2 = up((b, r), id2, lp)
@inbounds plx[b, r] = tr(U[b,r,id1]*U[bu1,ru1,id2] / (U[b,r,id2]*U[bu2,ru2,id1])) @inbounds plx[b, r] = tr(U[b,id1,r]*U[bu1,id2,ru1] / (U[b,id2,r]*U[bu2,id1,ru2]))
return nothing return nothing
end end
@ -24,33 +24,14 @@ end
function krnl_plaq!(plx, U, lp::SpaceParm) function krnl_plaq!(plx, U, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
if (b < 1) || (b > lp.bsz) plx[b,r] = zero(plx[b,r])
@cuprintln("Error b: %b, %r") @inbounds for ipl in 1:lp.npls
end id1, id2 = lp.plidx[ipl]
if (r < 1) || (r > lp.rsz)
@cuprintln("Error r: %b, %r") bu1, ru1 = up((b, r), id1, lp)
end bu2, ru2 = up((b, r), id2, lp)
plx[b,r] = complex(0.0) plx[b,r] += tr(U[b,id1,r]*U[bu1,id2,ru1] / (U[b,id2,r]*U[bu2,id1,ru2]))
for ipl in 1:lp.npls
id1, id2 = lp.plidx[ipl]
bu1, ru1 = up((b, r), id1, lp)
bu2, ru2 = up((b, r), id2, lp)
if (bu1 < 1) || (bu1 > lp.bsz)
@cuprintln("Error bu1: %b, %r, %id1")
end
if (ru1 < 1) || (ru1 > lp.rsz)
@cuprintln("Error ru1: %b, %r, %id1")
end
if (bu2 < 1) || (bu2 > lp.bsz)
@cuprintln("Error bu2: %b, %r, %id2")
end
if (ru2 < 1) || (ru2 > lp.rsz)
@cuprintln("Error ru2: %b, %r, %id2")
end
plx[b,r] += tr(U[r,id1,b]*U[bu1,id2,ru1] / (U[b,id2,r]*U[bu2,id1,ru2]))
end end
return nothing return nothing
@ -72,10 +53,10 @@ function krnl_force_wilson_pln!(frc1, frc2, U, ipl, lp::SpaceParm)
F2 = projalg(g1*g2) F2 = projalg(g1*g2)
F3 = projalg(g2*g1) F3 = projalg(g2*g1)
frc1[b ,r,id1 ] -= F1 frc1[b ,id1, r ] -= F1
frc1[b ,r,id2 ] += F1 frc1[b ,id2, r ] += F1
frc2[bu1,ru1,id2] -= F2 frc2[bu1,id2,ru1] -= F2
frc2[bu2,ru2,id1] += F3 frc2[bu2,id1,ru2] += F3
end end
return nothing return nothing
@ -125,8 +106,8 @@ function krnl_force_wilson!(frc, U, lp::SpaceParm)
F2 = projalg((U[b,id2,r]/(U[bd1,id2,rd1]*U[bdu,id1,rdu]))*U[bd1,id1,rd1]) F2 = projalg((U[b,id2,r]/(U[bd1,id2,rd1]*U[bdu,id1,rdu]))*U[bd1,id1,rd1])
F3 = projalg((U[bd2,id2,rd2]\U[bd2,id1,rd2])*(U[bud,id2,rud]/U[b,id1,r])) F3 = projalg((U[bd2,id2,rd2]\U[bd2,id1,rd2])*(U[bud,id2,rud]/U[b,id1,r]))
frc[b,r,id1] -= F1 - F3 frc[b,id1,r] -= F1 - F3
frc[b,r,id2] += F1 - F2 frc[b,id2,r] += F1 - F2
end end
end end
@ -138,29 +119,30 @@ function krnl_add_force_plns!(frc, fpl, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
@inbounds for ipl in 1:lp.npls @inbounds for ipl in 1:lp.npls
id1, id2 = lp.plidx[ipl] id1, id2 = lp.plidx[ipl]
frc[b,r,id1] += fpl[b,ipl,r,1,1] + fpl[b,ipl,r,1,2] frc[b,id1,r] += fpl[b,ipl,r,1,1] + fpl[b,ipl,r,1,2]
frc[b,r,id2] += fpl[b,ipl,r,2,1] + fpl[b,ipl,r,2,2] frc[b,id2,r] += fpl[b,ipl,r,2,1] + fpl[b,ipl,r,2,2]
end end
return nothing return nothing
end end
function force0_wilson_pln!(frc1, frc2, U, lp::SpaceParm) function force0_wilson_pln!(frc1, ftmp, U, lp::SpaceParm)
zero!(frc1, lp) fill!(frc1, zero(eltype(frc1)))
zero!(frc2, lp) fill!(ftmp, zero(eltype(ftmp)))
for i in 1:lp.npls for i in 1:lp.npls
CUDA.@sync begin CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_force_wilson_pln!(frc1,frc2,U,i,lp) CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_force_wilson_pln!(frc1,ftmp,U,i,lp)
end end
end end
frc1 .= frc1 .+ ftmp
return nothing return nothing
end end
function force0_wilson!(frc1, U, lp::SpaceParm) function force0_wilson!(frc1, U, lp::SpaceParm)
zero!(frc1, lp) fill!(frc1, zero(eltype(frc1)))
CUDA.@sync begin CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_force_wilson!(frc1,U,lp) CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_force_wilson!(frc1,U,lp)
end end
@ -173,7 +155,7 @@ function force0_wilson_nw!(frc1, fpln, U, lp::SpaceParm)
CUDA.@sync begin CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz*lp.npls krnl_force_wilson_nw!(fpln,U,lp) CUDA.@cuda threads=lp.bsz blocks=lp.rsz*lp.npls krnl_force_wilson_nw!(fpln,U,lp)
end end
zero!(frc1, lp) fill!(frc1, zero(eltype(frc1)))
CUDA.@sync begin CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_add_force_plns!(frc1, fpln,lp) CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_add_force_plns!(frc1, fpln,lp)
end end

View file

@ -11,196 +11,66 @@
un(t) = t <: Union{Group, Complex} un(t) = t <: Union{Group, Complex}
function field(::Type{T}, lp::SpaceParm) where {T <: Union{Group, Algebra}} function field(::Type{G}, ::Type{T}, lp::SpaceParm) where {G <: Union{Group, Algebra}, T <: AbstractFloat}
sz = lp.bsz, lp.ndim, lp.rsz sz = lp.bsz, lp.ndim, lp.rsz
if (T == SU2) if (G == SU2)
# As = StructArray{SU2}(undef, sz, unwrap=un) # As = StructArray{SU2}(undef, sz, unwrap=un)
return CuArray{SU2, 3}(undef, sz) return CuArray{SU2{T}, 3}(undef, sz)
elseif (T == SU2alg) elseif (G == SU2alg)
# As = StructArray{SU2alg}(undef, sz, unwrap=un) # As = StructArray{SU2alg}(undef, sz, unwrap=un)
return CuArray{SU2alg, 3}(undef, sz) return CuArray{SU2alg{T}, 3}(undef, sz)
elseif (T == SU3) elseif (G == SU3)
# As = StructArray{SU3}(undef, sz, unwrap=un) # As = StructArray{SU3}(undef, sz, unwrap=un)
return CuArray{SU3, 3}(undef, sz) return CuArray{SU3{T}, 3}(undef, sz)
# As = Array{SU3, lp.ndim+1}(undef, sz) # As = Array{SU3, lp.ndim+1}(undef, sz)
elseif (T == SU3alg) elseif (G == SU3alg)
# As = StructArray{SU3alg}(undef, sz, unwrap=un) # As = StructArray{SU3alg}(undef, sz, unwrap=un)
return CuArray{SU3alg, 3}(undef, sz) return CuArray{SU3alg{T}, 3}(undef, sz)
# As = Array{SU3alg, lp.ndim+1}(undef, sz) # As = Array{SU3alg, lp.ndim+1}(undef, sz)
end end
return replace_storage(CuArray, As) return replace_storage(CuArray, As)
end end
function krnl_SU3_one!(G, lp::SpaceParm) function randomize!(f, lp::SpaceParm, ymws::YMworkspace)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
G[b,id,r] = SU3(1.0,0.0,0.0,0.0,1.0,0.0)
end
return nothing
end
function krnl_SU2_one!(G, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
G[b,id,r] = SU2(1.0,0.0)
end
return nothing
end
function krnl_SU3alg_zero!(G, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
G[b,id,r] = SU3alg(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0)
end
return nothing
end
function krnl_SU2alg_zero!(G, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
G[b,id,r] = SU2alg(0.0,0.0,0.0)
end
return nothing
end
function krnl_SU3alg_assign!(G, M, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
G[b,id,r] = SU3alg(M[b,id,r,1], M[b,id,r,2], M[b,id,r,3], M[b,id,r,4],
M[b,id,r,5], M[b,id,r,6], M[b,id,r,7], M[b,id,r,8])
end
return nothing
end
function krnl_SU2alg_assign!(G, M, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
G[b,id,r] = SU2alg(M[b,id,r,1], M[b,id,r,2], M[b,id,r,3])
end
return nothing
end
function randomn!(X, lp)
if (eltype(X) == SU2alg)
# randn!(CURAND.default_rng(), LazyRows(X).t1)
# randn!(CURAND.default_rng(), LazyRows(X).t2)
# randn!(CURAND.default_rng(), LazyRows(X).t3)
M = CuArray{Float64}(undef, lp.bsz, lp.ndim, lp.rsz, 3)
randn!(CURAND.default_rng(), M)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_SU2alg_assign!(X, M, lp)
end
elseif (eltype(X) == SU3alg)
# randn!(CURAND.default_rng(), LazyRows(X).t1)
# randn!(CURAND.default_rng(), LazyRows(X).t2)
# randn!(CURAND.default_rng(), LazyRows(X).t3)
# randn!(CURAND.default_rng(), LazyRows(X).t4)
# randn!(CURAND.default_rng(), LazyRows(X).t5)
# randn!(CURAND.default_rng(), LazyRows(X).t6)
# randn!(CURAND.default_rng(), LazyRows(X).t7)
# randn!(CURAND.default_rng(), LazyRows(X).t8)
M = CuArray{Float64}(undef, lp.bsz, lp.ndim, lp.rsz, 8)
randn!(CURAND.default_rng(), M)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_SU3alg_assign!(X, M, lp)
end
end
return nothing
end
function zero!(X, lp)
if (eltype(X) == SU2alg)
# fill!(LazyRows(X).t1, 0.0)
# fill!(LazyRows(X).t2, 0.0)
# fill!(LazyRows(X).t3, 0.0)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_SU2alg_zero!(X, lp)
end
end
if (eltype(X) == SU3alg)
# fill!(LazyRows(X).t1, 0.0)
# fill!(LazyRows(X).t2, 0.0)
# fill!(LazyRows(X).t3, 0.0)
# fill!(LazyRows(X).t4, 0.0)
# fill!(LazyRows(X).t5, 0.0)
# fill!(LazyRows(X).t6, 0.0)
# fill!(LazyRows(X).t7, 0.0)
# fill!(LazyRows(X).t8, 0.0)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_SU3alg_zero!(X, lp)
end
end
if (eltype(X) == SU2)
# fill!(LazyRows(X).t1.re, 1.0)
# fill!(LazyRows(X).t1.im, 0.0)
# fill!(LazyRows(X).t2.re, 0.0)
# fill!(LazyRows(X).t2.im, 0.0)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_SU2_one!(X, lp)
end
end
if (eltype(X) == SU3)
# fill!(LazyRows(X).u11.re, 1.0)
# fill!(LazyRows(X).u11.im, 0.0)
# fill!(LazyRows(X).u12.re, 0.0)
# fill!(LazyRows(X).u12.im, 0.0)
# fill!(LazyRows(X).u13.re, 0.0)
# fill!(LazyRows(X).u13.im, 0.0)
# fill!(LazyRows(X).u21.re, 0.0)
# fill!(LazyRows(X).u21.im, 0.0)
# fill!(LazyRows(X).u22.re, 1.0)
# fill!(LazyRows(X).u22.im, 0.0)
# fill!(LazyRows(X).u23.re, 0.0)
# fill!(LazyRows(X).u23.im, 0.0)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_SU3_one!(X, lp)
end
end
return nothing
end
function norm_field(X) if ymws.ALG == SU2alg
m = CUDA.randn(ymws.PRC, lp.bsz,lp.ndim,3,lp.rsz)
return CUDA.mapreduce(norm2, +, X) CUDA.@sync begin
# d = 0.0 CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_assign_SU2!(f,m,lp)
if (eltype(X) == SU2alg) end
# d = CUDA.mapreduce(x->x^2, +, LazyRows(X).t1) + return nothing
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t2) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t3)
elseif (eltype(X) == SU3alg)
# d = CUDA.mapreduce(x->x^2, +, LazyRows(X).t1) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t2) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t3) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t4) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t5) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t6) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t7) +
# CUDA.mapreduce(x->x^2, +, LazyRows(X).t8)
d = CUDA.mapreduce(norm2, +, X)
end end
return d if ymws.ALG == SU3alg
m = CUDA.randn(ymws.PRC, lp.bsz,lp.ndim,8,lp.rsz)
CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_assign_SU3!(f,m,lp)
end
return nothing
end
return nothing
end end
function krnl_assign_SU3!(frc, m, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
frc[b,id,r] = SU3alg(m[b,id,1,r], m[b,id,2,r], m[b,id,3,r],
m[b,id,4,r], m[b,id,5,r], m[b,id,6,r],
m[b,id,7,r], m[b,id,8,r])
end
return nothing
end
function krnl_assign_SU2!(frc, m, lp::SpaceParm)
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
for id in 1:lp.ndim
frc[b,id,r] = SU2alg(m[b,id,1,r], m[b,id,2,r], m[b,id,3,r])
end
return nothing
end

View file

@ -9,7 +9,7 @@
### created: Thu Jul 15 11:27:28 2021 ### created: Thu Jul 15 11:27:28 2021
### ###
function gauge_action(U, lp::SpaceParm, gp::GaugeParm, ymws::YMworkspace) function gauge_action(U, lp::SpaceParm, gp::GaugeParm{T}, ymws::YMworkspace{T}) where T <: AbstractFloat
CUDA.@sync begin CUDA.@sync begin
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_plaq!(ymws.cm, U, lp) CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_plaq!(ymws.cm, U, lp)
@ -32,7 +32,7 @@ function plaquette(U, lp::SpaceParm, gp::GaugeParm, ymws::YMworkspace)
end end
function hamiltonian(mom, U, lp, gp, ymws) function hamiltonian(mom, U, lp, gp, ymws)
K = norm_field(mom)/2.0 K = CUDA.mapreduce(norm2, +, mom)/2
V = gauge_action(U, lp, gp, ymws) V = gauge_action(U, lp, gp, ymws)
println("K: ", K, " V: ", V) println("K: ", K, " V: ", V)
return K+V return K+V
@ -42,7 +42,7 @@ function HMC!(U, eps, ns, lp::SpaceParm, gp::GaugeParm, ymws::YMworkspace; noacc
ymws.U1 .= U ymws.U1 .= U
randomn!(ymws.mom, lp) randomize!(ymws.mom, lp, ymws)
hini = hamiltonian(ymws.mom, U, lp, gp, ymws) hini = hamiltonian(ymws.mom, U, lp, gp, ymws)
OMF4!(ymws.mom, U, eps, ns, lp, gp, ymws) OMF4!(ymws.mom, U, eps, ns, lp, gp, ymws)
@ -78,14 +78,14 @@ function krnl_updt!(mom, frc1, frc2, eps1, U, eps2, lp::SpaceParm)
return nothing return nothing
end end
function OMF4!(mom, U, eps, ns, lp::SpaceParm, gp::GaugeParm, ymws::YMworkspace) function OMF4!(mom, U, eps, ns, lp::SpaceParm, gp::GaugeParm{T}, ymws::YMworkspace{T}) where T <: AbstractFloat
r1::Float64 = 0.08398315262876693 r1::T = 0.08398315262876693
r2::Float64 = 0.2539785108410595 r2::T = 0.2539785108410595
r3::Float64 = 0.6822365335719091 r3::T = 0.6822365335719091
r4::Float64 = -0.03230286765269967 r4::T = -0.03230286765269967
r5::Float64 = 0.5-r1-r3 r5::T = 0.5-r1-r3
r6::Float64 = 1.0-2.0*(r2+r4) r6::T = 1.0-2.0*(r2+r4)
# ee = eps*gp.beta/gp.ng # ee = eps*gp.beta/gp.ng
# @device_code_warntype force0_wilson!(ymws.frc1,ymws.frc2, U, lp, gp) # @device_code_warntype force0_wilson!(ymws.frc1,ymws.frc2, U, lp, gp)
@ -129,36 +129,35 @@ function OMF4!(mom, U, eps, ns, lp::SpaceParm, gp::GaugeParm, ymws::YMworkspace)
# end # end
ee = eps*gp.beta/gp.ng ee = eps*gp.beta/gp.ng
force0_wilson!(ymws.frc1, U, lp) force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
zero!(ymws.frc2, lp)
for i in 1:ns for i in 1:ns
# STEP 1 # STEP 1
mom .= mom .+ (r1*ee) .* (ymws.frc1 .+ ymws.frc2) mom .= mom .+ (r1*ee) .* ymws.frc1
U .= expm.(U, mom, eps*r2) U .= expm.(U, mom, eps*r2)
# STEP 2 # STEP 2
force0_wilson!(ymws.frc1, U, lp) force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
mom .= mom .+ (r3*ee) .* (ymws.frc1 .+ ymws.frc2) mom .= mom .+ (r3*ee) .* ymws.frc1
U .= expm.(U, mom, eps*r4) U .= expm.(U, mom, eps*r4)
# STEP 3 # STEP 3
force0_wilson!(ymws.frc1, U, lp) force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
mom .= mom .+ (r5*ee) .* (ymws.frc1 .+ ymws.frc2) mom .= mom .+ (r5*ee) .* ymws.frc1
U .= expm.(U, mom, eps*r6) U .= expm.(U, mom, eps*r6)
# STEP 4 # STEP 4
force0_wilson!(ymws.frc1, U, lp) force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
mom .= mom .+ (r5*ee) .* (ymws.frc1 .+ ymws.frc2) mom .= mom .+ (r5*ee) .* ymws.frc1
U .= expm.(U, mom, eps*r4) U .= expm.(U, mom, eps*r4)
# STEP 5 # STEP 5
force0_wilson!(ymws.frc1, U, lp) force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
mom .= mom .+ (r3*ee) .* (ymws.frc1 .+ ymws.frc2) mom .= mom .+ (r3*ee) .* ymws.frc1
U .= expm.(U, mom, eps*r2) U .= expm.(U, mom, eps*r2)
# STEP 6 # STEP 6
force0_wilson!(ymws.frc1, U, lp) force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
mom .= mom .+ (r1*ee) .* (ymws.frc1 .+ ymws.frc2) mom .= mom .+ (r1*ee) .* ymws.frc1
end end
return nothing return nothing