Skip to content

Commit 6f9a377

Browse files
authored
Merge pull request #48 from araujoms/atomiconce
use @atomiconce only for 1.11+
2 parents 83bd0a1 + 114ac60 commit 6f9a377

File tree

3 files changed

+101
-40
lines changed

3 files changed

+101
-40
lines changed

src/Perms/perm_images.jl

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,41 +41,80 @@ AP.inttype(::Type{Perm{T}}) where {T} = T
4141
AP.inttype(::Type{Perm}) = UInt16
4242
AP.__unsafe_image(n::Integer, σ::Perm) = oftype(n, @inbounds σ.images[n])
4343

44-
function Base.copy(p::Perm)
45-
imgs = copy(p.images)
46-
q = typeof(p)(imgs; check = false)
47-
if isdefined(p, :inv, :acquire)
48-
inv_imgs = copy(p.inv.images)
49-
q⁻¹ = typeof(p)(inv_imgs; check = false)
50-
@atomic :release q⁻¹.inv = q
51-
@atomiconce :release :acquire q.inv = q⁻¹
44+
@static if VERSION < v"1.11"
45+
function Base.copy(p::Perm)
46+
imgs = copy(p.images)
47+
q = typeof(p)(imgs; check = false)
48+
if isdefined(p, :inv, :sequentially_consistent)
49+
inv_imgs = copy(@atomic(p.inv).images)
50+
q⁻¹ = typeof(p)(inv_imgs; check = false)
51+
@atomic q.inv = q⁻¹
52+
@atomic q⁻¹.inv = q
53+
end
54+
return q
5255
end
53-
return q
54-
end
5556

56-
function Base.inv::Perm)
57-
if !isdefined(σ, :inv, :acquire)
58-
if isone(σ)
59-
@atomiconce :release :acquire σ.inv = σ
60-
else
61-
σ⁻¹ = typeof(σ)(invperm.images); check = false)
62-
# this order is important:
63-
# fuly initialize the "local" inverse first and only then
64-
# update σ to make the local inverse visible globally
65-
@atomic :release σ⁻¹.inv = σ
66-
@atomiconce :release :acquire σ.inv = σ⁻¹
57+
function Base.inv::Perm)
58+
if !isdefined(σ, :inv, :sequentially_consistent)
59+
if isone(σ)
60+
@atomic σ.inv = σ
61+
else
62+
σ⁻¹ = typeof(σ)(invperm.images); check = false)
63+
# we don't want to end up with two copies of inverse σ floating around
64+
if !isdefined(σ, :inv, :sequentially_consistent)
65+
@atomic σ.inv = σ⁻¹
66+
@atomic σ⁻¹.inv = σ
67+
end
68+
end
6769
end
70+
return σ.inv
71+
end
72+
73+
function AP.cycles::Perm)
74+
if !isdefined(σ, :cycles, :sequentially_consistent)
75+
cdec = AP.CycleDecomposition(σ)
76+
# we can afford producing more than one cycle decomposition
77+
@atomic σ.cycles = cdec
78+
end
79+
return σ.cycles
80+
end
81+
else
82+
function Base.copy(p::Perm)
83+
imgs = copy(p.images)
84+
q = typeof(p)(imgs; check = false)
85+
if isdefined(p, :inv, :acquire)
86+
inv_imgs = copy(p.inv.images)
87+
q⁻¹ = typeof(p)(inv_imgs; check = false)
88+
@atomic :release q⁻¹.inv = q
89+
@atomiconce :release :acquire q.inv = q⁻¹
90+
end
91+
return q
92+
end
93+
94+
function Base.inv::Perm)
95+
if !isdefined(σ, :inv, :acquire)
96+
if isone(σ)
97+
@atomiconce :release :acquire σ.inv = σ
98+
else
99+
σ⁻¹ = typeof(σ)(invperm.images); check = false)
100+
# this order is important:
101+
# fuly initialize the "local" inverse first and only then
102+
# update σ to make the local inverse visible globally
103+
@atomic :release σ⁻¹.inv = σ
104+
@atomiconce :release :acquire σ.inv = σ⁻¹
105+
end
106+
end
107+
return σ.inv
68108
end
69-
return σ.inv
70-
end
71109

72-
function AP.cycles::Perm)
73-
if !isdefined(σ, :cycles, :acquire)
74-
cdec = AP.CycleDecomposition(σ)
75-
# we can afford producing more than one cycle decomposition
76-
@atomiconce :release :acquire σ.cycles = cdec
110+
function AP.cycles::Perm)
111+
if !isdefined(σ, :cycles, :acquire)
112+
cdec = AP.CycleDecomposition(σ)
113+
# we can afford producing more than one cycle decomposition
114+
@atomiconce :release :acquire σ.cycles = cdec
115+
end
116+
return σ.cycles
77117
end
78-
return σ.cycles
79118
end
80119

81120
function Base.isodd::Perm)

src/group_interface.jl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22

33
Base.one(G::PermGroup{P}) where {P} = Permutation(one(P), G)
44

5-
function GroupsCore.order(::Type{T}, G::AbstractPermutationGroup) where {T}
6-
if !isdefined(G, :order, :acquire)
7-
ord = order(BigInt, StabilizerChain(G))
8-
@atomiconce :release :acquire G.order = ord
5+
@static if VERSION < v"1.11"
6+
function GroupsCore.order(::Type{T}, G::AbstractPermutationGroup) where {T}
7+
if !isdefined(G, :order, :sequentially_consistent)
8+
ord = order(StabilizerChain(G))
9+
@atomic G.order = ord
10+
end
11+
return convert(T, G.order)
12+
end
13+
else
14+
function GroupsCore.order(::Type{T}, G::AbstractPermutationGroup) where {T}
15+
if !isdefined(G, :order, :acquire)
16+
ord = order(BigInt, StabilizerChain(G))
17+
@atomiconce :release :acquire G.order = ord
18+
end
19+
return convert(T, G.order)
920
end
10-
return convert(T, G.order)
1121
end
1222

1323
GroupsCore.gens(G::PermGroup) = Permutation.(G.__gens_raw, Ref(G))

src/perm_group.jl

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,25 @@ The first call on a particular group `G` will construct the chain from `gens(G)`
8888
and complete it by the deterministic Schreier-Sims algorithm.
8989
The subsequent calls just return the cached data structure.
9090
"""
91-
92-
function StabilizerChain(G::PermGroup{P,T}) where {P,T}
93-
if !isdefined(G, :stabchain, :acquire)
94-
stabchain = schreier_sims(T, __gens_raw(G))
95-
@atomiconce :release :acquire G.stabchain = stabchain
91+
@static if VERSION < v"1.11"
92+
function StabilizerChain(G::PermGroup{P,T}) where {P,T}
93+
if !isdefined(G, :stabchain, :sequentially_consistent)
94+
stabchain = schreier_sims(T, __gens_raw(G))
95+
# this may take some time, so let's check again
96+
if !isdefined(G, :stabchain, :sequentially_consistent)
97+
@atomic G.stabchain = stabchain
98+
end
99+
end
100+
return G.stabchain
101+
end
102+
else
103+
function StabilizerChain(G::PermGroup{P,T}) where {P,T}
104+
if !isdefined(G, :stabchain, :acquire)
105+
stabchain = schreier_sims(T, __gens_raw(G))
106+
@atomiconce :release :acquire G.stabchain = stabchain
107+
end
108+
return G.stabchain
96109
end
97-
return G.stabchain
98110
end
99111

100112
basis(G::AbstractPermutationGroup) = basis(StabilizerChain(G))

0 commit comments

Comments
 (0)