-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attempt to improve some codes in QuadForm
#1254
Conversation
src/QuadForm/Herm/Lattices.jl
Outdated
@@ -251,7 +251,7 @@ function scale(L::HermLat) | |||
for i in 1:d | |||
push!(to_sum, involution(L)(to_sum[i])) | |||
end | |||
s = sum(to_sum, init = zero(base_field(L))*base_ring(L)) | |||
s = sum(to_sum; init = 0*base_ring(L)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
src/QuadForm/Herm/Lattices.jl
Outdated
@@ -359,7 +359,7 @@ function jordan_decomposition(L::HermLat, p) | |||
|
|||
k = 1 | |||
while k <= n | |||
G = S * F * transpose(_map(S, aut)) | |||
G = S * F * transpose(map(aut, S)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What did _map
do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same, but I run several examples using both functions and the underscore one seems to be slightly faster, allocations are the same... I will revert those changed. I first thought that this was a work-around before map
was fully implemented.
@@ -305,8 +305,8 @@ function generators(L::AbstractLat; minimal::Bool = false) | |||
d = ncols(St) | |||
for i in 1:nrows(St) | |||
if base_ring(L) isa NfOrd | |||
I = numerator(St.coeffs[i]) | |||
den = denominator(St.coeffs[i]) | |||
I = numerator(coefficient_ideals(St)[i]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check that this does not make a copy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No copy, access directly St.coeffs
src/QuadForm/Quad/GenusRep.jl
Outdated
@@ -155,7 +155,7 @@ function spinor_genera_in_genus(L, mod_out) | |||
# The smaller the element, the better | |||
for d in diagonal(Gr) | |||
if (iszero(spinornorm) && !iszero(d)) || (!iszero(d) && abs(norm(d)) < abs(norm(spinornorm))) | |||
spinornorm = d | |||
add!(spinornorm, spinornorm, d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why add? Wasn't there a =
before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spinornorm
is already initialized to be zero, I thought that doing so would lighten the allocation process (?)
add!
will just modify the content of spinornorm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Nothing is gained from this. It is actually worse with the change. Before it was just an assignment, which is a noop (no operation; does not cost anything). Now there is an addition, which is not for free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I will correct it.
src/QuadForm/Quad/GenusRep.jl
Outdated
@@ -167,7 +167,7 @@ function spinor_genera_in_genus(L, mod_out) | |||
end | |||
end | |||
@assert !iszero(Gr[1, i]) | |||
spinornorm = 2 * Gr[1, i] | |||
add!(spinornorm, spinornorm, 2 * Gr[1, i]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
src/QuadForm/Quad/GenusRep.jl
Outdated
@@ -511,7 +511,7 @@ function maximal_norm_splitting(L, p) | |||
end | |||
end | |||
|
|||
@assert all(let G = G; k -> nrows(G[k]) in [1,2]; end, 1:length(G)) | |||
@assert all(k -> nrows(G[k]) in [1,2], 1:length(G)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you check with code_warntype
? This is added to work around a julia bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran the code_warntype
and notice wrong appears.. The assertion works also (like if I change some values it returns an error, and does nothing otherwise). So it seems to be fixed (?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
src/QuadForm/Quad/GenusRep.jl
Outdated
@hassert :GenRep 1 all(k -> isone(quo(R, factors[k])[2](FacElem(s * the_idele[k]))), 1:length(the_idele)) | ||
@hassert :GenRep 1 all(j -> sign(s * the_idele_inf[j], IP[j]) == 1, 1:length(IP)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
src/QuadForm/Quad/Lattices.jl
Outdated
@@ -232,8 +232,7 @@ function scale(L::QuadLat) | |||
end | |||
G = gram_matrix_of_rational_span(L) | |||
C = coefficient_ideals(L) | |||
to_sum = [ G[i, j] * C[i] * involution(L)(C[j]) for j in 1:length(C) for i in 1:j] | |||
s = sum(to_sum) | |||
s = sum(G[i, j] * C[i] * involution(L)(C[j]) for j in 1:length(C) for i in 1:j) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs an init
src/QuadForm/Quad/Spaces.jl
Outdated
@@ -613,13 +612,13 @@ end | |||
function _quadratic_form_with_invariants(dim::Int, det::nf_elem, finite::Vector, negative::Dict{<:InfPlc, Int}) | |||
@hassert :Lattice 1 dim >= 1 | |||
@hassert :Lattice 1 !iszero(det) | |||
K::AnticNumberField = parent(det) | |||
K = parent(det) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was added for type stability. Have you checked that everything is still fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will have to re-put it. There are very odd things happening in this function, which I barely understand on the code_warntype
. The variable finite0
is defined and used only at the very end of the function in a hassert
. If we remove the hassert
and infer the type for finite0
, for instance
local finite0::Vector{<: NfOrdIdl}
finite0 = copy(finite)
or
local finite0::typeof(finite)
finite0 = copy(finite)
or
finite0 = eltype(finite)[p for p in finite]
in all cases, if we remove the only line calling this variable, then code_warntype
will still show finite0::Any
in red...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all related to JuliaLang/julia#15276. Every time one uses a p -> begin; x[1] + y[1] + z + p; end
, every "captured" variable which is used (like x
, y
, z
), might become unstable in the surrounding function. This also effects generators like (p + z for p in 1:10)
. The let
is a workaround, also mentioned in the issue above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I completely forgot about this. So maybe the code_warntype
might not capture the issue. Since it was a recent fix I will put this back too until we make sure the problem is solved (to avoid any performance issue)
src/QuadForm/Quad/ZGenus.jl
Outdated
@@ -135,20 +134,19 @@ function _p_adic_symbol(A::MatElem, p, val) | |||
q = p^m0 | |||
n = nrows(A) | |||
A = divexact(A, q) | |||
Fp = Native.GF(p) | |||
Fp = GF(p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, should be Native.GF
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will revert them. What is the reason for this ?
src/QuadForm/Quad/ZGenus.jl
Outdated
q = ZZ(2)^m0 | ||
A = divexact(A, q) | ||
A_2 = change_base_ring(Native.GF(2), A) | ||
A_2 = change_base_ring(GF(2), A) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No
@@ -1693,9 +1695,9 @@ function _gram_from_jordan_block(p::ZZRingElem, block, discr_form=false) | |||
q = zero_matrix(QQ, 0, 0) | |||
end | |||
if discr_form | |||
q = q * (1//2)^level | |||
map_entries!(x -> x * (1//2)^level, q, q) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that work and yield the correct result?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works, one has to take care of the type but if everything is made of QQFieldElem
, then this overwrites the content of q
; the tests show that nothing goes wrong.
src/QuadForm/Quad/ZGenus.jl
Outdated
@@ -2148,11 +2150,11 @@ function _M_p(species, p) | |||
p = QQ(p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_p
etc while you are at it
push!(primes, p ) | ||
end | ||
end | ||
primes = union!(Hecke.primes(G1), Hecke.primes(G2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does primes(G1)
make a copy? If not this is wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
src/QuadForm/Quad/ZLattices.jl
Outdated
@@ -437,8 +439,8 @@ function assert_has_automorphisms(L::ZZLat; redo::Bool = false, | |||
end | |||
|
|||
# Now gens are with respect to the basis of L | |||
@hassert :Lattice 1 all(let gens = gens; i -> change_base_ring(FlintQQ, gens[i]) * GL * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
src/QuadForm/Quad/ZLattices.jl
Outdated
@@ -1198,7 +1201,7 @@ function is_maximal_even(L::ZZLat, p) | |||
return true, L | |||
end | |||
G = change_base_ring(ZZ, gram_matrix(L)) | |||
k = Native.GF(p) | |||
k = GF(p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No
src/QuadForm/Torsion.jl
Outdated
@@ -1501,7 +1500,7 @@ Return the radical `\{x \in T | b(x,T) = 0 and q(x)=0\}` of the quadratic form | |||
function radical_quadratic(T::TorQuadModule) | |||
Kb, ib = radical_bilinear(T) | |||
G = gram_matrix_quadratic(Kb)*1//modulus_bilinear_form(Kb) | |||
F = Native.GF(2, cached=false) | |||
F = GF(2; cached=false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this looks innocent. Most of the let
statements came from painstakingly working through issues with @code_warntype
. So please make sure that code stability is not degraded. Same is true for sum(iterator)
vs sum(Bla[x for x in iterator])
. There once were some compiler bugs. Not sure if they are around anymore.
I will check all that, yes, thanks for all the comment. |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #1254 +/- ##
==========================================
- Coverage 74.55% 74.42% -0.14%
==========================================
Files 346 346
Lines 110993 111276 +283
==========================================
+ Hits 82756 82813 +57
- Misses 28237 28463 +226
|
Not sure if you were finished with the revision? |
Sorry, I forgot to mention it - I am done with the revision. |
end | ||
end | ||
|
||
for d in cartesian_product_iterator(dets, inplace = true)# Iterators.product(dets...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inplace = true
is the default for the function so I do not see why keeping it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I forgot about that, you are right.
@@ -1748,7 +1748,7 @@ function hermitian_local_genera(E, p, rank::Int, det_val::Int, min_scale::Int, m | |||
end | |||
end | |||
|
|||
for dn in cartesian_product_iterator(det_norms, inplace = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, why?
src/QuadForm/Herm/Mass.jl
Outdated
@@ -292,7 +292,7 @@ function _standard_mass(L::HermLat, prec::Int = 10) | |||
local relzeta::arb | |||
|
|||
while true | |||
relzeta = prod(arb[_L_function(E, 1 - i, wprec) for i in 1:2:m]) | |||
relzeta = prod(_L_function(E, 1 - i, wprec) for i in 1:2:m; init = 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
relzeta = prod(_L_function(E, 1 - i, wprec) for i in 1:2:m; init = 1) | |
relzeta = prod(_L_function(E, 1 - i, wprec) for i in 1:2:m; init = one(ArbField(wprec, cached = false))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thanks, that was the thing I was trying to get but couldn't make it work.
I added a few things. There are still some |
Yes I guess so, I just missed them in my last commit. Since we have to make a new commit for your suggestion, I will put everything together. |
71 min for the long tests is pretty quick. Not sure it is due to the changes here. |
Mainly trying to avoid creation of lists when it is not necessary and use more the the
!
functions whenever possible.I have tried to improve some type stability by giving new names to variables which were changing types during the sub-processes and inferring more type for lists. Hopefully this with help for compilation time (?).
I have added some semi-colons and spaces in some places where I noticed then missing, for code readability: this was not my first goal so the code is not perfectly reformatted.