mirror of
https://igit.ific.uv.es/alramos/latticegpu.jl.git
synced 2025-05-14 11:13:42 +02:00
Working multi-precision simulations
The pure gauge theory with groups SU(2) and SU(3) is working properly.
This commit is contained in:
parent
1416efdbee
commit
09a09153b9
8 changed files with 188 additions and 283 deletions
|
@ -13,20 +13,22 @@
|
|||
# SU(2) group elements represented trough Cayley-Dickson
|
||||
# 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
|
||||
t1::Complex{T}
|
||||
t2::Complex{T}
|
||||
end
|
||||
SU2() = SU2{Float64}(complex(1.0), complex(0.0))
|
||||
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)
|
||||
dag(a::SU2{T}) where T <: AbstractFloat = inverse(a)
|
||||
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)
|
||||
tr(g::SU2{T}) where T <: AbstractFloat = complex(2.0*real(g.t1), 0.0)
|
||||
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)
|
||||
dag(a::SU2{T}) where T <: AbstractFloat = inverse(a)
|
||||
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)
|
||||
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)
|
||||
|
@ -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
|
||||
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
|
||||
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},b::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1+b.t1,a.t2+b.t2,a.t3+b.t3)
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
# a.u32 = conj(a.u13*a.u21 - a.u11*a.u23)
|
||||
# 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
|
||||
u11::Complex{T}
|
||||
u12::Complex{T}
|
||||
|
@ -27,11 +29,12 @@ struct SU3{T} <: Group
|
|||
u22::Complex{T}
|
||||
u23::Complex{T}
|
||||
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))
|
||||
dag(a::SU3{T}) where T <: AbstractFloat = inverse(a)
|
||||
tr(a::SU3{T}) where T <: AbstractFloat = a.u11+a.u22+conj(a.u11*a.u22 - a.u12*a.u21)
|
||||
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))
|
||||
dag(a::SU3{T}) where T <: AbstractFloat = inverse(a)
|
||||
tr(a::SU3{T}) where T <: AbstractFloat = a.u11+a.u22+conj(a.u11*a.u22 - a.u12*a.u21)
|
||||
Base.one(::Type{SU3{T}}) where T <: AbstractFloat = SU3{T}(one(T),zero(T),zero(T),zero(T),one(T),zero(T))
|
||||
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
|
||||
|
||||
|
@ -103,7 +106,7 @@ struct SU3alg{T} <: Algebra
|
|||
t7::T
|
||||
t8::T
|
||||
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
|
||||
|
||||
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
|
||||
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)
|
||||
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},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)
|
||||
|
|
|
@ -23,13 +23,13 @@ include("Space/Space.jl")
|
|||
|
||||
using .Space
|
||||
export SpaceParm
|
||||
export up, dw, updw
|
||||
export up, dw, updw, global_point
|
||||
|
||||
|
||||
include("YM/YM.jl")
|
||||
|
||||
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!
|
||||
|
||||
end # module
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
module Space
|
||||
|
||||
import Base.show
|
||||
|
||||
struct SpaceParm{N,M}
|
||||
ndim::Int64
|
||||
iL::NTuple{N,Int64}
|
||||
|
@ -53,6 +55,24 @@ struct SpaceParm{N,M}
|
|||
end
|
||||
end
|
||||
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)
|
||||
|
||||
|
@ -131,6 +151,22 @@ end
|
|||
return bu, ru, bd, rd
|
||||
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
|
||||
|
|
51
src/YM/YM.jl
51
src/YM/YM.jl
|
@ -16,46 +16,53 @@ using CUDA, Random, StructArrays
|
|||
using ..Space
|
||||
using ..Groups
|
||||
|
||||
struct GaugeParm
|
||||
beta::Float64
|
||||
cG::Tuple{Float64,Float64}
|
||||
ng::Int32
|
||||
struct GaugeParm{T}
|
||||
beta::T
|
||||
cG::NTuple{2,T}
|
||||
ng::Int64
|
||||
end
|
||||
export GaugeParm
|
||||
|
||||
include("YMfields.jl")
|
||||
export field, field_pln, randomn!, zero!, norm2
|
||||
|
||||
struct YMworkspace
|
||||
struct YMworkspace{T}
|
||||
GRP
|
||||
ALG
|
||||
PRC
|
||||
frc1
|
||||
frc2
|
||||
mom
|
||||
U1
|
||||
cm # complex 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)
|
||||
f1 = field(SU2alg, lp)
|
||||
f2 = field(SU2alg, lp)
|
||||
mm = field(SU2alg, lp)
|
||||
u1 = field(SU2, lp)
|
||||
if (G == SU2)
|
||||
GRP = SU2
|
||||
ALG = SU2alg
|
||||
f1 = field(SU2alg, T, lp)
|
||||
f2 = field(SU2alg, T, lp)
|
||||
mm = field(SU2alg, T, lp)
|
||||
u1 = field(SU2, T, lp)
|
||||
end
|
||||
|
||||
if (T == SU3)
|
||||
f1 = field(SU3alg, lp)
|
||||
f2 = field(SU3alg, lp)
|
||||
mm = field(SU3alg, lp)
|
||||
u1 = field(SU3, lp)
|
||||
if (G == SU3)
|
||||
GRP = SU3
|
||||
ALG = SU3alg
|
||||
f1 = field(SU3alg, T, lp)
|
||||
f2 = field(SU3alg, T, lp)
|
||||
mm = field(SU3alg, T, lp)
|
||||
u1 = field(SU3, T, lp)
|
||||
end
|
||||
cs = CuArray{ComplexF64, 2}(undef, lp.bsz,lp.rsz)
|
||||
rs = CuArray{Float64, 2}(undef, lp.bsz,lp.rsz)
|
||||
cs = CuArray{Complex{T}, 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
|
||||
export YMworkspace
|
||||
|
||||
include("YMfields.jl")
|
||||
export field, field_pln, randomize!, zero!, norm2
|
||||
|
||||
include("YMact.jl")
|
||||
export krnl_plaq!, force0_wilson!
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ function krnl_plaq!(plx, U, ipl, lp::SpaceParm)
|
|||
bu1, ru1 = up((b, r), id1, 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
|
||||
end
|
||||
|
@ -24,33 +24,14 @@ end
|
|||
function krnl_plaq!(plx, U, lp::SpaceParm)
|
||||
|
||||
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
|
||||
if (b < 1) || (b > lp.bsz)
|
||||
@cuprintln("Error b: %b, %r")
|
||||
end
|
||||
if (r < 1) || (r > lp.rsz)
|
||||
@cuprintln("Error r: %b, %r")
|
||||
end
|
||||
plx[b,r] = zero(plx[b,r])
|
||||
@inbounds for ipl in 1:lp.npls
|
||||
id1, id2 = lp.plidx[ipl]
|
||||
|
||||
plx[b,r] = complex(0.0)
|
||||
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)
|
||||
|
||||
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]))
|
||||
plx[b,r] += tr(U[b,id1,r]*U[bu1,id2,ru1] / (U[b,id2,r]*U[bu2,id1,ru2]))
|
||||
end
|
||||
|
||||
return nothing
|
||||
|
@ -72,10 +53,10 @@ function krnl_force_wilson_pln!(frc1, frc2, U, ipl, lp::SpaceParm)
|
|||
F2 = projalg(g1*g2)
|
||||
F3 = projalg(g2*g1)
|
||||
|
||||
frc1[b ,r,id1 ] -= F1
|
||||
frc1[b ,r,id2 ] += F1
|
||||
frc2[bu1,ru1,id2] -= F2
|
||||
frc2[bu2,ru2,id1] += F3
|
||||
frc1[b ,id1, r ] -= F1
|
||||
frc1[b ,id2, r ] += F1
|
||||
frc2[bu1,id2,ru1] -= F2
|
||||
frc2[bu2,id1,ru2] += F3
|
||||
end
|
||||
|
||||
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])
|
||||
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,r,id2] += F1 - F2
|
||||
frc[b,id1,r] -= F1 - F3
|
||||
frc[b,id2,r] += F1 - F2
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -138,29 +119,30 @@ function krnl_add_force_plns!(frc, fpl, lp::SpaceParm)
|
|||
b, r = CUDA.threadIdx().x, CUDA.blockIdx().x
|
||||
@inbounds for ipl in 1:lp.npls
|
||||
id1, id2 = lp.plidx[ipl]
|
||||
frc[b,r,id1] += 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,id1,r] += fpl[b,ipl,r,1,1] + fpl[b,ipl,r,1,2]
|
||||
frc[b,id2,r] += fpl[b,ipl,r,2,1] + fpl[b,ipl,r,2,2]
|
||||
end
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function force0_wilson_pln!(frc1, frc2, U, lp::SpaceParm)
|
||||
function force0_wilson_pln!(frc1, ftmp, U, lp::SpaceParm)
|
||||
|
||||
zero!(frc1, lp)
|
||||
zero!(frc2, lp)
|
||||
fill!(frc1, zero(eltype(frc1)))
|
||||
fill!(ftmp, zero(eltype(ftmp)))
|
||||
for i in 1:lp.npls
|
||||
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
|
||||
frc1 .= frc1 .+ ftmp
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function force0_wilson!(frc1, U, lp::SpaceParm)
|
||||
|
||||
zero!(frc1, lp)
|
||||
fill!(frc1, zero(eltype(frc1)))
|
||||
CUDA.@sync begin
|
||||
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_force_wilson!(frc1,U,lp)
|
||||
end
|
||||
|
@ -173,7 +155,7 @@ function force0_wilson_nw!(frc1, fpln, U, lp::SpaceParm)
|
|||
CUDA.@sync begin
|
||||
CUDA.@cuda threads=lp.bsz blocks=lp.rsz*lp.npls krnl_force_wilson_nw!(fpln,U,lp)
|
||||
end
|
||||
zero!(frc1, lp)
|
||||
fill!(frc1, zero(eltype(frc1)))
|
||||
CUDA.@sync begin
|
||||
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_add_force_plns!(frc1, fpln,lp)
|
||||
end
|
||||
|
|
|
@ -11,22 +11,22 @@
|
|||
|
||||
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
|
||||
if (T == SU2)
|
||||
if (G == SU2)
|
||||
# As = StructArray{SU2}(undef, sz, unwrap=un)
|
||||
return CuArray{SU2, 3}(undef, sz)
|
||||
elseif (T == SU2alg)
|
||||
return CuArray{SU2{T}, 3}(undef, sz)
|
||||
elseif (G == SU2alg)
|
||||
# As = StructArray{SU2alg}(undef, sz, unwrap=un)
|
||||
return CuArray{SU2alg, 3}(undef, sz)
|
||||
elseif (T == SU3)
|
||||
return CuArray{SU2alg{T}, 3}(undef, sz)
|
||||
elseif (G == SU3)
|
||||
# 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)
|
||||
elseif (T == SU3alg)
|
||||
elseif (G == SU3alg)
|
||||
# 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)
|
||||
end
|
||||
|
||||
|
@ -34,173 +34,43 @@ function field(::Type{T}, lp::SpaceParm) where {T <: Union{Group, Algebra}}
|
|||
|
||||
end
|
||||
|
||||
function krnl_SU3_one!(G, lp::SpaceParm)
|
||||
function randomize!(f, lp::SpaceParm, ymws::YMworkspace)
|
||||
|
||||
if ymws.ALG == SU2alg
|
||||
m = CUDA.randn(ymws.PRC, lp.bsz,lp.ndim,3,lp.rsz)
|
||||
CUDA.@sync begin
|
||||
CUDA.@cuda threads=lp.bsz blocks=lp.rsz krnl_assign_SU2!(f,m,lp)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
function krnl_assign_SU3!(frc, m, lp::SpaceParm)
|
||||
|
||||
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)
|
||||
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_SU2_one!(G, lp::SpaceParm)
|
||||
function krnl_assign_SU2!(frc, m, 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)
|
||||
frc[b,id,r] = SU2alg(m[b,id,1,r], m[b,id,2,r], m[b,id,3,r])
|
||||
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)
|
||||
|
||||
return CUDA.mapreduce(norm2, +, X)
|
||||
# d = 0.0
|
||||
if (eltype(X) == SU2alg)
|
||||
# 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)
|
||||
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
|
||||
|
||||
return d
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
### 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.@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
|
||||
|
||||
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)
|
||||
println("K: ", K, " V: ", V)
|
||||
return K+V
|
||||
|
@ -42,7 +42,7 @@ function HMC!(U, eps, ns, lp::SpaceParm, gp::GaugeParm, ymws::YMworkspace; noacc
|
|||
|
||||
ymws.U1 .= U
|
||||
|
||||
randomn!(ymws.mom, lp)
|
||||
randomize!(ymws.mom, lp, ymws)
|
||||
hini = hamiltonian(ymws.mom, U, 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
|
||||
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
|
||||
r2::Float64 = 0.2539785108410595
|
||||
r3::Float64 = 0.6822365335719091
|
||||
r4::Float64 = -0.03230286765269967
|
||||
r5::Float64 = 0.5-r1-r3
|
||||
r6::Float64 = 1.0-2.0*(r2+r4)
|
||||
r1::T = 0.08398315262876693
|
||||
r2::T = 0.2539785108410595
|
||||
r3::T = 0.6822365335719091
|
||||
r4::T = -0.03230286765269967
|
||||
r5::T = 0.5-r1-r3
|
||||
r6::T = 1.0-2.0*(r2+r4)
|
||||
|
||||
# ee = eps*gp.beta/gp.ng
|
||||
# @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
|
||||
|
||||
ee = eps*gp.beta/gp.ng
|
||||
force0_wilson!(ymws.frc1, U, lp)
|
||||
zero!(ymws.frc2, lp)
|
||||
force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
|
||||
for i in 1:ns
|
||||
# STEP 1
|
||||
mom .= mom .+ (r1*ee) .* (ymws.frc1 .+ ymws.frc2)
|
||||
mom .= mom .+ (r1*ee) .* ymws.frc1
|
||||
U .= expm.(U, mom, eps*r2)
|
||||
|
||||
# STEP 2
|
||||
force0_wilson!(ymws.frc1, U, lp)
|
||||
mom .= mom .+ (r3*ee) .* (ymws.frc1 .+ ymws.frc2)
|
||||
force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
|
||||
mom .= mom .+ (r3*ee) .* ymws.frc1
|
||||
U .= expm.(U, mom, eps*r4)
|
||||
|
||||
# STEP 3
|
||||
force0_wilson!(ymws.frc1, U, lp)
|
||||
mom .= mom .+ (r5*ee) .* (ymws.frc1 .+ ymws.frc2)
|
||||
force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
|
||||
mom .= mom .+ (r5*ee) .* ymws.frc1
|
||||
U .= expm.(U, mom, eps*r6)
|
||||
|
||||
# STEP 4
|
||||
force0_wilson!(ymws.frc1, U, lp)
|
||||
mom .= mom .+ (r5*ee) .* (ymws.frc1 .+ ymws.frc2)
|
||||
force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
|
||||
mom .= mom .+ (r5*ee) .* ymws.frc1
|
||||
U .= expm.(U, mom, eps*r4)
|
||||
|
||||
# STEP 5
|
||||
force0_wilson!(ymws.frc1, U, lp)
|
||||
mom .= mom .+ (r3*ee) .* (ymws.frc1 .+ ymws.frc2)
|
||||
force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
|
||||
mom .= mom .+ (r3*ee) .* ymws.frc1
|
||||
U .= expm.(U, mom, eps*r2)
|
||||
|
||||
# STEP 6
|
||||
force0_wilson!(ymws.frc1, U, lp)
|
||||
mom .= mom .+ (r1*ee) .* (ymws.frc1 .+ ymws.frc2)
|
||||
force0_wilson_pln!(ymws.frc1, ymws.frc2, U, lp)
|
||||
mom .= mom .+ (r1*ee) .* ymws.frc1
|
||||
end
|
||||
|
||||
return nothing
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue