From 59bf15f2f064296f1f810ef6b57b4dd1d419b848 Mon Sep 17 00:00:00 2001 From: antonydellavecchia Date: Sun, 28 Jul 2024 22:17:27 +0200 Subject: [PATCH 01/20] some progress on lie algebra serialization --- experimental/LieAlgebras/src/LieAlgebras.jl | 8 ++++++++ experimental/LieAlgebras/src/serialization.jl | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 experimental/LieAlgebras/src/serialization.jl diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index 1fa023704c07..4af4587a76ed 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -20,6 +20,7 @@ import ..Oscar: _is_tensor_product, _iso_oscar_gap, _vec, + AbstractSerializer, action, basis_matrix, basis, @@ -71,8 +72,13 @@ import ..Oscar: order, parent_type, rank, + register_serialization_type, root, roots, + save_data_dict, + save_object, + save_typed_object, + SerializerState, sub, symbols, symmetric_power, @@ -228,6 +234,8 @@ include("iso_oscar_gap.jl") include("iso_gap_oscar.jl") include("GapWrapper.jl") +include("serialization.jl") + end # module LieAlgebras using .LieAlgebras diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl new file mode 100644 index 000000000000..6e6ac3443c09 --- /dev/null +++ b/experimental/LieAlgebras/src/serialization.jl @@ -0,0 +1,10 @@ +Oscar.encode_type(::Type{<: AbstractLieAlgebra}) = "AbstractLieAlgebra" +@register_serialization_type AbstractLieAlgebra uses_id + +function save_object(s::SerializerState, L::AbstractLieAlgebra{T}) where T <: FieldElem + save_data_dict(s) do + save_typed_object(s, coefficient_ring(L), :base_field) + save_object(s, _struct_consts(L), :struct_const) + save_object(s, symbols(L), :symbols) + end +end From 034d32fd5a35d35258048ac481bc740dbd5f726e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Mon, 29 Jul 2024 12:42:09 +0200 Subject: [PATCH 02/20] more progress --- experimental/LieAlgebras/src/LieAlgebras.jl | 5 ++++- experimental/LieAlgebras/src/serialization.jl | 16 +++++++++++----- experimental/LieAlgebras/test/setup_tests.jl | 2 ++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index 4af4587a76ed..1a9a57e7ce90 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -16,6 +16,7 @@ using AbstractAlgebra.PrettyPrinting # functions with new methods import ..Oscar: + @register_serialization_type, _is_exterior_power, _is_tensor_product, _iso_oscar_gap, @@ -37,6 +38,7 @@ import ..Oscar: coefficients, compose, derived_series, + DeserializerState, dim, direct_sum, dot, @@ -64,6 +66,8 @@ import ..Oscar: is_solvable, is_welldefined, kernel, + load_object, + load_typed_object, lower_central_series, matrix, normalizer, @@ -72,7 +76,6 @@ import ..Oscar: order, parent_type, rank, - register_serialization_type, root, roots, save_data_dict, diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 6e6ac3443c09..142857f1d439 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -1,10 +1,16 @@ -Oscar.encode_type(::Type{<: AbstractLieAlgebra}) = "AbstractLieAlgebra" -@register_serialization_type AbstractLieAlgebra uses_id +@register_serialization_type AbstractLieAlgebra -function save_object(s::SerializerState, L::AbstractLieAlgebra{T}) where T <: FieldElem +function save_object(s::SerializerState, L::AbstractLieAlgebra) save_data_dict(s) do - save_typed_object(s, coefficient_ring(L), :base_field) - save_object(s, _struct_consts(L), :struct_const) + save_typed_object(s, coefficient_ring(L), :base_ring) + save_object(s, _struct_consts(L), :struct_consts) save_object(s, symbols(L), :symbols) end end + +function load_object(s::DeserializerState, ::Type{AbstractLieAlgebra}) + R = load_typed_object(s, :base_ring) + struct_consts = load_object(s, :struct_consts) + s = load_object(s, :symbols) + return lie_algebra(R, struct_consts, s; check=false) +end diff --git a/experimental/LieAlgebras/test/setup_tests.jl b/experimental/LieAlgebras/test/setup_tests.jl index c01437f9a029..e8b79758ed31 100644 --- a/experimental/LieAlgebras/test/setup_tests.jl +++ b/experimental/LieAlgebras/test/setup_tests.jl @@ -1,3 +1,5 @@ +include(joinpath(Oscar.oscardir, "test", "Serialization", "setup_tests.jl")) + if !isdefined(Main, :GAPWrap) import Oscar: GAPWrap end From 66af597499e6a417a9aab0cc145b9e1b08eb4c81 Mon Sep 17 00:00:00 2001 From: antonydellavecchia Date: Mon, 29 Jul 2024 17:25:17 +0200 Subject: [PATCH 03/20] serialization for SRow --- experimental/LieAlgebras/src/serialization.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 142857f1d439..b7a37051f65b 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -10,7 +10,7 @@ end function load_object(s::DeserializerState, ::Type{AbstractLieAlgebra}) R = load_typed_object(s, :base_ring) - struct_consts = load_object(s, :struct_consts) - s = load_object(s, :symbols) + struct_consts = load_object(s, Matrix, (SRow, R), :struct_consts) + s = load_object(s, Vector, Symbol, :symbols) return lie_algebra(R, struct_consts, s; check=false) end From 021451064b39af184a4e1ed9c8611a6c57e2f820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Mon, 29 Jul 2024 16:02:22 +0200 Subject: [PATCH 04/20] more --- experimental/LieAlgebras/src/LieAlgebras.jl | 1 + experimental/LieAlgebras/src/serialization.jl | 38 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index 1a9a57e7ce90..c9062966ff56 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -78,6 +78,7 @@ import ..Oscar: rank, root, roots, + save_data_array, save_data_dict, save_object, save_typed_object, diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index b7a37051f65b..18c1bcb2dfcf 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -1,4 +1,4 @@ -@register_serialization_type AbstractLieAlgebra +@register_serialization_type AbstractLieAlgebra uses_id function save_object(s::SerializerState, L::AbstractLieAlgebra) save_data_dict(s) do @@ -10,7 +10,41 @@ end function load_object(s::DeserializerState, ::Type{AbstractLieAlgebra}) R = load_typed_object(s, :base_ring) - struct_consts = load_object(s, Matrix, (SRow, R), :struct_consts) + struct_consts = load_object(s, Matrix, sparse_row_type(R), :struct_consts) s = load_object(s, Vector, Symbol, :symbols) return lie_algebra(R, struct_consts, s; check=false) end + +@register_serialization_type LinearLieAlgebra uses_id + +function save_object(s::SerializerState, L::LinearLieAlgebra) + save_data_dict(s) do + save_typed_object(s, coefficient_ring(L), :base_ring) + save_object(s, L.n, :n) + save_object(s, matrix_repr_basis(L), :basis) + save_object(s, symbols(L), :symbols) + end +end + +function load_object(s::DeserializerState, ::Type{LinearLieAlgebra}) + R = load_typed_object(s, :base_ring) + n = load_object(s, Int, :n) + basis = load_object(s, Vector, dense_matrix_type(R), :basis) + s = load_object(s, Vector, Symbol, :symbols) + return lie_algebra(R, n, basis, s; check=false) +end + +@register_serialization_type DirectSumLieAlgebra uses_id + +function save_object(s::SerializerState, L::DirectSumLieAlgebra) + save_data_dict(s) do + save_typed_object(s, coefficient_ring(L), :base_ring) + save_object(s, L.summands, :summands) + end +end + +function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) + R = load_typed_object(s, :base_ring) + summands = load_object(s, :summands) + return direct_sum(R, summands) +end From a7f80a0aba54d27e205ebd77bcef3da5cfa5b27d Mon Sep 17 00:00:00 2001 From: antonydellavecchia Date: Mon, 29 Jul 2024 17:48:15 +0200 Subject: [PATCH 05/20] fix for general lie algebras --- experimental/LieAlgebras/src/serialization.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 18c1bcb2dfcf..38a924d77536 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -21,15 +21,16 @@ function save_object(s::SerializerState, L::LinearLieAlgebra) save_data_dict(s) do save_typed_object(s, coefficient_ring(L), :base_ring) save_object(s, L.n, :n) - save_object(s, matrix_repr_basis(L), :basis) + save_typed_object(s, matrix_repr_basis(L), :basis) save_object(s, symbols(L), :symbols) end end function load_object(s::DeserializerState, ::Type{LinearLieAlgebra}) R = load_typed_object(s, :base_ring) + T = elem_type(R) n = load_object(s, Int, :n) - basis = load_object(s, Vector, dense_matrix_type(R), :basis) + basis = load_typed_object(s, :basis) s = load_object(s, Vector, Symbol, :symbols) return lie_algebra(R, n, basis, s; check=false) end From 3b84f2f17747a5a095e137ea5fd2b6f423175119 Mon Sep 17 00:00:00 2001 From: antonydellavecchia Date: Tue, 30 Jul 2024 11:07:35 +0200 Subject: [PATCH 06/20] direct sum lie algebras working --- experimental/LieAlgebras/src/serialization.jl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 38a924d77536..322a03b0fc34 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -40,12 +40,20 @@ end function save_object(s::SerializerState, L::DirectSumLieAlgebra) save_data_dict(s) do save_typed_object(s, coefficient_ring(L), :base_ring) - save_object(s, L.summands, :summands) + save_data_array(s, :summands) do + for summand in L.summands + ref = Oscar.save_as_ref(s, summand) + save_object(s, ref) + end + end end end function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) R = load_typed_object(s, :base_ring) - summands = load_object(s, :summands) + summands = Oscar.load_array_node(s, :summands) do _ + Oscar.load_ref(s) + end + return direct_sum(R, summands) end From 53186b2aea293589aaaf6498c07577c1f7a81cc5 Mon Sep 17 00:00:00 2001 From: antonydellavecchia Date: Tue, 30 Jul 2024 11:36:10 +0200 Subject: [PATCH 07/20] remove whitespace --- experimental/LieAlgebras/src/serialization.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 322a03b0fc34..71ada4dacf99 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -54,6 +54,6 @@ function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) summands = Oscar.load_array_node(s, :summands) do _ Oscar.load_ref(s) end - + return direct_sum(R, summands) end From 7c6d84a4822e320df58d18659043f349090a51c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 15:41:18 +0200 Subject: [PATCH 08/20] Fix for empty direct sum --- experimental/LieAlgebras/src/serialization.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 71ada4dacf99..307615ce3ad3 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -51,9 +51,11 @@ end function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) R = load_typed_object(s, :base_ring) - summands = Oscar.load_array_node(s, :summands) do _ - Oscar.load_ref(s) - end + summands = Vector{LieAlgebra{elem_type(R)}}( + Oscar.load_array_node(s, :summands) do _ + Oscar.load_ref(s) + end, + ) return direct_sum(R, summands) end From 03cd6313703607850a360e6937bdda2ca054ff9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 16:43:56 +0200 Subject: [PATCH 09/20] Make LieAlgebraElem work --- experimental/LieAlgebras/src/LieAlgebras.jl | 2 ++ experimental/LieAlgebras/src/serialization.jl | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index c9062966ff56..57ed56c8eeee 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -90,6 +90,8 @@ import ..Oscar: weyl_vector, word, zero_map, + save_type_params, + load_type_params, ⊕, ⊗ diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 307615ce3ad3..e4aecca7637d 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -59,3 +59,28 @@ function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) return direct_sum(R, summands) end + +@register_serialization_type AbstractLieAlgebraElem uses_params +@register_serialization_type LinearLieAlgebraElem uses_params +@register_serialization_type DirectSumLieAlgebraElem uses_params + +function save_object(s::SerializerState, x::LieAlgebraElem) + save_object(s, coefficients(x)) +end + +function load_object(s::DeserializerState, ::Type{<:LieAlgebraElem}, L::LieAlgebra) + return L(load_object(s, Vector, coefficient_ring(L))) +end + +function save_type_params(s::SerializerState, x::LieAlgebraElem) + save_data_dict(s) do + save_object(s, Oscar.encode_type(typeof(x)), :name) + parent_x = parent(x) + parent_ref = Oscar.save_as_ref(s, parent_x) + save_object(s, parent_ref, :params) + end +end + +function load_type_params(s::DeserializerState, ::Type{<:LieAlgebraElem}) + return load_typed_object(s) +end From b0ed460f31517c5c1f37313c72697b603e1408cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 17:27:35 +0200 Subject: [PATCH 10/20] Some optimizations --- experimental/LieAlgebras/src/serialization.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index e4aecca7637d..96d856328766 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -21,16 +21,15 @@ function save_object(s::SerializerState, L::LinearLieAlgebra) save_data_dict(s) do save_typed_object(s, coefficient_ring(L), :base_ring) save_object(s, L.n, :n) - save_typed_object(s, matrix_repr_basis(L), :basis) + save_object(s, matrix_repr_basis(L), :basis) save_object(s, symbols(L), :symbols) end end function load_object(s::DeserializerState, ::Type{LinearLieAlgebra}) R = load_typed_object(s, :base_ring) - T = elem_type(R) n = load_object(s, Int, :n) - basis = load_typed_object(s, :basis) + basis = load_object(s, Vector, (dense_matrix_type(R), matrix_space(R, n, n)), :basis) s = load_object(s, Vector, Symbol, :symbols) return lie_algebra(R, n, basis, s; check=false) end From e43225f4b73697fa01b8775b389dc8439b913cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 17:27:52 +0200 Subject: [PATCH 11/20] Add serialization tests --- experimental/LieAlgebras/test/setup_tests.jl | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/experimental/LieAlgebras/test/setup_tests.jl b/experimental/LieAlgebras/test/setup_tests.jl index e8b79758ed31..23ba3a21836d 100644 --- a/experimental/LieAlgebras/test/setup_tests.jl +++ b/experimental/LieAlgebras/test/setup_tests.jl @@ -120,6 +120,31 @@ if !isdefined(Main, :lie_algebra_conformance_test) @test dim(L) == sum(length, chev; init=0) end end + + @testset "Serialization" begin + mktempdir() do path + test_save_load_roundtrip(path, L) do loaded + # nothing, cause `L === loaded` anyway + end + + if dim(L) >= 1 + x = basis(L, 1) + test_save_load_roundtrip(path, x) do loaded + @test parent(loaded) === L + @test coefficients(loaded) == coefficients(x) + end + end + + if dim(L) >= 1 # TODO: remove this condition once deserializing empty vectors keeps the type + test_save_load_roundtrip(path, basis(L)) do loaded + @test length(loaded) == dim(L) + @test all( + coefficients(loaded[i]) == coefficients(basis(L, i)) for i in 1:dim(L) + ) + end + end + end + end end end From d6a7f2a8ab7c5e699273086a10c12b233acbe2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 20:51:23 +0200 Subject: [PATCH 12/20] Add serialization of attributes --- experimental/LieAlgebras/src/serialization.jl | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 96d856328766..90962d500b30 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -5,14 +5,17 @@ function save_object(s::SerializerState, L::AbstractLieAlgebra) save_typed_object(s, coefficient_ring(L), :base_ring) save_object(s, _struct_consts(L), :struct_consts) save_object(s, symbols(L), :symbols) + save_attrs(s, L) end end function load_object(s::DeserializerState, ::Type{AbstractLieAlgebra}) R = load_typed_object(s, :base_ring) - struct_consts = load_object(s, Matrix, sparse_row_type(R), :struct_consts) - s = load_object(s, Vector, Symbol, :symbols) - return lie_algebra(R, struct_consts, s; check=false) + struct_consts = load_object(s, Matrix, (sparse_row_type(R), R), :struct_consts) + symbs = load_object(s, Vector, Symbol, :symbols) + L = lie_algebra(R, struct_consts, symbs; check=false) + load_attrs!(s, L) + return L end @register_serialization_type LinearLieAlgebra uses_id @@ -23,6 +26,7 @@ function save_object(s::SerializerState, L::LinearLieAlgebra) save_object(s, L.n, :n) save_object(s, matrix_repr_basis(L), :basis) save_object(s, symbols(L), :symbols) + save_attrs(s, L) end end @@ -30,8 +34,10 @@ function load_object(s::DeserializerState, ::Type{LinearLieAlgebra}) R = load_typed_object(s, :base_ring) n = load_object(s, Int, :n) basis = load_object(s, Vector, (dense_matrix_type(R), matrix_space(R, n, n)), :basis) - s = load_object(s, Vector, Symbol, :symbols) - return lie_algebra(R, n, basis, s; check=false) + symbs = load_object(s, Vector, Symbol, :symbols) + L = lie_algebra(R, n, basis, symbs; check=false) + load_attrs!(s, L) + return L end @register_serialization_type DirectSumLieAlgebra uses_id @@ -45,6 +51,7 @@ function save_object(s::SerializerState, L::DirectSumLieAlgebra) save_object(s, ref) end end + save_attrs(s, L) end end @@ -56,7 +63,40 @@ function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) end, ) - return direct_sum(R, summands) + L = direct_sum(R, summands) + load_attrs!(s, L) + return L +end + +function save_attrs(s::SerializerState, L::LieAlgebra) + save_data_dict(s, :attrs) do + for bool_prop in (:is_abelian, :is_nilpotent, :is_perfect, :is_simple, :is_solvable) + if has_attribute(L, bool_prop) + save_object(s, get_attribute(L, bool_prop), bool_prop) + end + end + for symbol_prop in (:type,) + if has_attribute(L, symbol_prop) + save_object(s, get_attribute(L, symbol_prop), symbol_prop) + end + end + # TODO: handle root_system + end +end + +function load_attrs!(s::DeserializerState, L::LieAlgebra) + Oscar.load_node(s, :attrs) do _ + for bool_prop in (:is_abelian, :is_nilpotent, :is_perfect, :is_simple, :is_solvable) + if haskey(s, bool_prop) + set_attribute!(L, bool_prop, load_object(s, Bool, bool_prop)) + end + end + for symbol_prop in (:type,) + if haskey(s, symbol_prop) + set_attribute!(L, symbol_prop, load_object(s, Symbol, symbol_prop)) + end + end + end end @register_serialization_type AbstractLieAlgebraElem uses_params From d2377c070948f4cd20990c184a10720185c62b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 21:51:29 +0200 Subject: [PATCH 13/20] Add macro for importing serialization functions --- experimental/LieAlgebras/src/LieAlgebras.jl | 14 ++------------ experimental/LieAlgebras/src/serialization.jl | 12 ++++++------ 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/experimental/LieAlgebras/src/LieAlgebras.jl b/experimental/LieAlgebras/src/LieAlgebras.jl index 57ed56c8eeee..72f41ca70cfe 100644 --- a/experimental/LieAlgebras/src/LieAlgebras.jl +++ b/experimental/LieAlgebras/src/LieAlgebras.jl @@ -16,12 +16,10 @@ using AbstractAlgebra.PrettyPrinting # functions with new methods import ..Oscar: - @register_serialization_type, _is_exterior_power, _is_tensor_product, _iso_oscar_gap, _vec, - AbstractSerializer, action, basis_matrix, basis, @@ -38,7 +36,6 @@ import ..Oscar: coefficients, compose, derived_series, - DeserializerState, dim, direct_sum, dot, @@ -66,8 +63,6 @@ import ..Oscar: is_solvable, is_welldefined, kernel, - load_object, - load_typed_object, lower_central_series, matrix, normalizer, @@ -78,11 +73,6 @@ import ..Oscar: rank, root, roots, - save_data_array, - save_data_dict, - save_object, - save_typed_object, - SerializerState, sub, symbols, symmetric_power, @@ -90,11 +80,11 @@ import ..Oscar: weyl_vector, word, zero_map, - save_type_params, - load_type_params, ⊕, ⊗ +Oscar.@import_all_serialization_functions + import Base: getindex, deepcopy_internal, hash, issubset, iszero, parent, zero export AbstractLieAlgebra, AbstractLieAlgebraElem diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 90962d500b30..72a9b11ce739 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -47,7 +47,7 @@ function save_object(s::SerializerState, L::DirectSumLieAlgebra) save_typed_object(s, coefficient_ring(L), :base_ring) save_data_array(s, :summands) do for summand in L.summands - ref = Oscar.save_as_ref(s, summand) + ref = save_as_ref(s, summand) save_object(s, ref) end end @@ -58,8 +58,8 @@ end function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) R = load_typed_object(s, :base_ring) summands = Vector{LieAlgebra{elem_type(R)}}( - Oscar.load_array_node(s, :summands) do _ - Oscar.load_ref(s) + load_array_node(s, :summands) do _ + load_ref(s) end, ) @@ -85,7 +85,7 @@ function save_attrs(s::SerializerState, L::LieAlgebra) end function load_attrs!(s::DeserializerState, L::LieAlgebra) - Oscar.load_node(s, :attrs) do _ + load_node(s, :attrs) do _ for bool_prop in (:is_abelian, :is_nilpotent, :is_perfect, :is_simple, :is_solvable) if haskey(s, bool_prop) set_attribute!(L, bool_prop, load_object(s, Bool, bool_prop)) @@ -113,9 +113,9 @@ end function save_type_params(s::SerializerState, x::LieAlgebraElem) save_data_dict(s) do - save_object(s, Oscar.encode_type(typeof(x)), :name) + save_object(s, encode_type(typeof(x)), :name) parent_x = parent(x) - parent_ref = Oscar.save_as_ref(s, parent_x) + parent_ref = save_as_ref(s, parent_x) save_object(s, parent_ref, :params) end end From a75ee7c9dcfd82527024b980a13d5db794e5efc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 30 Jul 2024 22:00:56 +0200 Subject: [PATCH 14/20] Add reference to issue --- experimental/LieAlgebras/test/setup_tests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/LieAlgebras/test/setup_tests.jl b/experimental/LieAlgebras/test/setup_tests.jl index 23ba3a21836d..e641bd923ff6 100644 --- a/experimental/LieAlgebras/test/setup_tests.jl +++ b/experimental/LieAlgebras/test/setup_tests.jl @@ -135,7 +135,7 @@ if !isdefined(Main, :lie_algebra_conformance_test) end end - if dim(L) >= 1 # TODO: remove this condition once deserializing empty vectors keeps the type + if dim(L) >= 1 # TODO: remove this condition once deserializing empty vectors keeps the type (https://github.com/oscar-system/Oscar.jl/issues/3983) test_save_load_roundtrip(path, basis(L)) do loaded @test length(loaded) == dim(L) @test all( From df840935d3a6d47570ce585840b8ff8b8c64ea6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 31 Jul 2024 11:34:46 +0200 Subject: [PATCH 15/20] foo --- experimental/LieAlgebras/src/serialization.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 72a9b11ce739..ba22bb665556 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -1,3 +1,9 @@ +############################################################################### +# +# Lie algebras +# +############################################################################### + @register_serialization_type AbstractLieAlgebra uses_id function save_object(s::SerializerState, L::AbstractLieAlgebra) @@ -9,7 +15,7 @@ function save_object(s::SerializerState, L::AbstractLieAlgebra) end end -function load_object(s::DeserializerState, ::Type{AbstractLieAlgebra}) +function load_object(s::DeserializerState, ::Type{<:AbstractLieAlgebra}) R = load_typed_object(s, :base_ring) struct_consts = load_object(s, Matrix, (sparse_row_type(R), R), :struct_consts) symbs = load_object(s, Vector, Symbol, :symbols) @@ -30,7 +36,7 @@ function save_object(s::SerializerState, L::LinearLieAlgebra) end end -function load_object(s::DeserializerState, ::Type{LinearLieAlgebra}) +function load_object(s::DeserializerState, ::Type{<:LinearLieAlgebra}) R = load_typed_object(s, :base_ring) n = load_object(s, Int, :n) basis = load_object(s, Vector, (dense_matrix_type(R), matrix_space(R, n, n)), :basis) @@ -55,7 +61,7 @@ function save_object(s::SerializerState, L::DirectSumLieAlgebra) end end -function load_object(s::DeserializerState, ::Type{DirectSumLieAlgebra}) +function load_object(s::DeserializerState, ::Type{<:DirectSumLieAlgebra}) R = load_typed_object(s, :base_ring) summands = Vector{LieAlgebra{elem_type(R)}}( load_array_node(s, :summands) do _ From 772f3d280a5b375d99379bd483c7e3033e484fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 31 Jul 2024 15:20:44 +0200 Subject: [PATCH 16/20] Add serialization of root systems --- experimental/LieAlgebras/src/serialization.jl | 64 +++++++++++++++++++ .../LieAlgebras/test/RootSystem-test.jl | 24 +++++++ 2 files changed, 88 insertions(+) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index ba22bb665556..91f14410fe33 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -129,3 +129,67 @@ end function load_type_params(s::DeserializerState, ::Type{<:LieAlgebraElem}) return load_typed_object(s) end + +############################################################################### +# +# Root systems +# +############################################################################### + +@register_serialization_type RootSystem uses_id + +function save_object(s::SerializerState, R::RootSystem) + save_data_dict(s) do + save_object(s, cartan_matrix(R), :cartan_matrix) + if has_root_system_type(R) + type, type_ordering = root_system_type_with_ordering(R) + save_object(s, type, :type) + if type_ordering != 1:length(type_ordering) # don't save if it's the default + save_object(s, type_ordering, :type_ordering) + end + end + end +end + +function load_object(s::DeserializerState, ::Type{RootSystem}) + cm = load_object(s, Matrix, Int, :cartan_matrix) + R = root_system(cm; check=false, detect_type=false) + if haskey(s, :type) + type = Vector{Tuple{Symbol,Int}}(load_object(s, Vector, (Tuple, [Symbol, Int]), :type)) # coercion needed due to https://github.com/oscar-system/Oscar.jl/issues/3983 + if haskey(s, :type_ordering) + type_ordering = load_object(s, Vector, Int, :type_ordering) + set_root_system_type!(R, type, type_ordering) + else + set_root_system_type!(R, type) + end + end + return R +end + +@register_serialization_type RootSpaceElem uses_params +@register_serialization_type DualRootSpaceElem uses_params + +function save_object(s::SerializerState, r::Union{RootSpaceElem,DualRootSpaceElem}) + save_object(s, _vec(coefficients(r))) +end + +function load_object( + s::DeserializerState, T::Type{<:Union{RootSpaceElem,DualRootSpaceElem}}, R::RootSystem +) + return T(R, load_object(s, Vector, QQ)) +end + +function save_type_params(s::SerializerState, r::Union{RootSpaceElem,DualRootSpaceElem}) + save_data_dict(s) do + save_object(s, encode_type(typeof(r)), :name) + rs_x = root_system(r) + rs_ref = save_as_ref(s, rs_x) + save_object(s, rs_ref, :params) + end +end + +function load_type_params( + s::DeserializerState, ::Type{<:Union{RootSpaceElem,DualRootSpaceElem}} +) + return load_typed_object(s) +end diff --git a/experimental/LieAlgebras/test/RootSystem-test.jl b/experimental/LieAlgebras/test/RootSystem-test.jl index 1f0732d05145..54b8d884270b 100644 --- a/experimental/LieAlgebras/test/RootSystem-test.jl +++ b/experimental/LieAlgebras/test/RootSystem-test.jl @@ -115,6 +115,30 @@ 1:n_roots(R), ) end + + @testset "Serialization" begin + mktempdir() do path + test_save_load_roundtrip(path, R) do loaded + # nothing, cause `R === loaded` anyway + end + + if n_roots(R) >= 1 + r = positive_root(R, n_positive_roots(R)) + test_save_load_roundtrip(path, r) do loaded + @test root_system(loaded) === R + @test coefficients(loaded) == coefficients(r) + end + end + + test_save_load_roundtrip(path, positive_roots(R)) do loaded + @test length(loaded) == n_positive_roots(R) + @test all( + coefficients(loaded[i]) == coefficients(root(R, i)) for + i in 1:n_positive_roots(R) + ) + end + end + end end @testset "rk 0" begin From 22958c75d3197c5f544e49d7b1d90248af5c3aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 31 Jul 2024 15:48:19 +0200 Subject: [PATCH 17/20] Add serialization of weyl groups --- experimental/LieAlgebras/src/serialization.jl | 42 ++++++++++++++ .../LieAlgebras/test/WeylGroup-test.jl | 58 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 91f14410fe33..f630772da5b6 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -193,3 +193,45 @@ function load_type_params( ) return load_typed_object(s) end + +############################################################################### +# +# Weyl groups +# +############################################################################### + +@register_serialization_type WeylGroup uses_id + +function save_object(s::SerializerState, W::WeylGroup) + save_data_dict(s) do + save_typed_object(s, root_system(W), :root_system) + end +end + +function load_object(s::DeserializerState, ::Type{WeylGroup}) + R = load_typed_object(s, :root_system) + return weyl_group(R) +end + +@register_serialization_type WeylGroupElem uses_params + +function save_object(s::SerializerState, x::WeylGroupElem) + save_object(s, word(x)) +end + +function load_object(s::DeserializerState, ::Type{WeylGroupElem}, W::WeylGroup) + return W(load_object(s, Vector, UInt8); normalize=false) +end + +function save_type_params(s::SerializerState, x::WeylGroupElem) + save_data_dict(s) do + save_object(s, encode_type(typeof(x)), :name) + parent_x = parent(x) + parent_ref = save_as_ref(s, parent_x) + save_object(s, parent_ref, :params) + end +end + +function load_type_params(s::DeserializerState, ::Type{WeylGroupElem}) + return load_typed_object(s) +end diff --git a/experimental/LieAlgebras/test/WeylGroup-test.jl b/experimental/LieAlgebras/test/WeylGroup-test.jl index 375cbb4b5569..da8ae8a26d44 100644 --- a/experimental/LieAlgebras/test/WeylGroup-test.jl +++ b/experimental/LieAlgebras/test/WeylGroup-test.jl @@ -431,4 +431,62 @@ include( @test allunique(orb) end end + + @testset "Serialization" begin + mktempdir() do path + @testset "simple saving and loading" begin + W = weyl_group((:A, 2), (:B, 4)) + + test_save_load_roundtrip(path, W) do loaded + # nothing, cause `W === loaded` anyway + end + + x = rand(W) + test_save_load_roundtrip(path, x) do loaded + @test parent(loaded) === W + @test word(loaded) == word(x) + end + + test_save_load_roundtrip(path, gens(W)) do loaded + @test length(loaded) == ngens(W) + @test all( + word(loaded[i]) == word(gen(W, i)) for i in 1:ngens(W) + ) + end + end + + @testset "cyclic reference between R and W survives" begin + Oscar.reset_global_serializer_state() + + R_filename = joinpath(path, "R.mrdi") + W_filename = joinpath(path, "W.mrdi") + + R = root_system(:D, 5) + W = weyl_group(R) + + save(R_filename, R) + save(W_filename, W) + + Oscar.reset_global_serializer_state() + + loaded_R = load(R_filename) + loaded_W = load(W_filename) + + @test loaded_R === root_system(loaded_W) + @test loaded_W === weyl_group(loaded_R) + + loaded_R = loaded_W = nothing # unset all references + + Oscar.reset_global_serializer_state() + + loaded_W = load(W_filename) + loaded_R = load(R_filename) + + @test loaded_R === root_system(loaded_W) + @test loaded_W === weyl_group(loaded_R) + + loaded_R = loaded_W = nothing # unset all references + end + end + end end From 8f2012857e2b2783c5bf88fa4cbcb9811dddc2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 31 Jul 2024 16:27:03 +0200 Subject: [PATCH 18/20] Connect Lie algebra and root system serialization --- experimental/LieAlgebras/src/serialization.jl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index f630772da5b6..798a406806e7 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -86,7 +86,10 @@ function save_attrs(s::SerializerState, L::LieAlgebra) save_object(s, get_attribute(L, symbol_prop), symbol_prop) end end - # TODO: handle root_system + if has_root_system(L) + save_typed_object(s, root_system(L), :root_system) + save_object(s, chevalley_basis(L), :chevalley_basis) + end end end @@ -102,6 +105,14 @@ function load_attrs!(s::DeserializerState, L::LieAlgebra) set_attribute!(L, symbol_prop, load_object(s, Symbol, symbol_prop)) end end + if haskey(s, :root_system) + @assert L isa AbstractLieAlgebra # TODO: adapt once we have a proper interface for this + L.root_system = load_typed_object(s, :root_system) + chevalley_basis = load_object( + s, Tuple, [(Vector, (AbstractLieAlgebraElem, L)) for _ in 1:3], :chevalley_basis + ) + # chevalley basis will become an attribute in the near future + end end end From a37ff80d28367b0f561e3a8003db73c6defdeffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 20 Aug 2024 17:28:53 +0200 Subject: [PATCH 19/20] Make attribute serialization work for Lie algebras --- experimental/LieAlgebras/src/serialization.jl | 73 ++++++++----------- experimental/LieAlgebras/test/setup_tests.jl | 2 +- 2 files changed, 32 insertions(+), 43 deletions(-) diff --git a/experimental/LieAlgebras/src/serialization.jl b/experimental/LieAlgebras/src/serialization.jl index 798a406806e7..3afbb460d7a7 100644 --- a/experimental/LieAlgebras/src/serialization.jl +++ b/experimental/LieAlgebras/src/serialization.jl @@ -4,13 +4,18 @@ # ############################################################################### -@register_serialization_type AbstractLieAlgebra uses_id +const lie_algebra_serialization_attributes = [ + :is_abelian, :is_nilpotent, :is_perfect, :is_simple, :is_solvable +] + +@register_serialization_type AbstractLieAlgebra uses_id lie_algebra_serialization_attributes function save_object(s::SerializerState, L::AbstractLieAlgebra) save_data_dict(s) do save_typed_object(s, coefficient_ring(L), :base_ring) save_object(s, _struct_consts(L), :struct_consts) save_object(s, symbols(L), :symbols) + save_root_system_data(s, L) save_attrs(s, L) end end @@ -20,11 +25,15 @@ function load_object(s::DeserializerState, ::Type{<:AbstractLieAlgebra}) struct_consts = load_object(s, Matrix, (sparse_row_type(R), R), :struct_consts) symbs = load_object(s, Vector, Symbol, :symbols) L = lie_algebra(R, struct_consts, symbs; check=false) - load_attrs!(s, L) + load_root_system_data(s, L) + load_attrs(s, L) return L end -@register_serialization_type LinearLieAlgebra uses_id +@register_serialization_type LinearLieAlgebra uses_id [ + lie_algebra_serialization_attributes; + [:type, :form] +] function save_object(s::SerializerState, L::LinearLieAlgebra) save_data_dict(s) do @@ -32,6 +41,7 @@ function save_object(s::SerializerState, L::LinearLieAlgebra) save_object(s, L.n, :n) save_object(s, matrix_repr_basis(L), :basis) save_object(s, symbols(L), :symbols) + save_root_system_data(s, L) save_attrs(s, L) end end @@ -42,11 +52,12 @@ function load_object(s::DeserializerState, ::Type{<:LinearLieAlgebra}) basis = load_object(s, Vector, (dense_matrix_type(R), matrix_space(R, n, n)), :basis) symbs = load_object(s, Vector, Symbol, :symbols) L = lie_algebra(R, n, basis, symbs; check=false) - load_attrs!(s, L) + load_root_system_data(s, L) + load_attrs(s, L) return L end -@register_serialization_type DirectSumLieAlgebra uses_id +@register_serialization_type DirectSumLieAlgebra uses_id lie_algebra_serialization_attributes function save_object(s::SerializerState, L::DirectSumLieAlgebra) save_data_dict(s) do @@ -57,6 +68,7 @@ function save_object(s::SerializerState, L::DirectSumLieAlgebra) save_object(s, ref) end end + save_root_system_data(s, L) save_attrs(s, L) end end @@ -70,49 +82,26 @@ function load_object(s::DeserializerState, ::Type{<:DirectSumLieAlgebra}) ) L = direct_sum(R, summands) - load_attrs!(s, L) + load_root_system_data(s, L) + load_attrs(s, L) return L end -function save_attrs(s::SerializerState, L::LieAlgebra) - save_data_dict(s, :attrs) do - for bool_prop in (:is_abelian, :is_nilpotent, :is_perfect, :is_simple, :is_solvable) - if has_attribute(L, bool_prop) - save_object(s, get_attribute(L, bool_prop), bool_prop) - end - end - for symbol_prop in (:type,) - if has_attribute(L, symbol_prop) - save_object(s, get_attribute(L, symbol_prop), symbol_prop) - end - end - if has_root_system(L) - save_typed_object(s, root_system(L), :root_system) - save_object(s, chevalley_basis(L), :chevalley_basis) - end +function save_root_system_data(s::SerializerState, L::LieAlgebra) + if has_root_system(L) + save_typed_object(s, root_system(L), :root_system) + save_object(s, chevalley_basis(L), :chevalley_basis) end end -function load_attrs!(s::DeserializerState, L::LieAlgebra) - load_node(s, :attrs) do _ - for bool_prop in (:is_abelian, :is_nilpotent, :is_perfect, :is_simple, :is_solvable) - if haskey(s, bool_prop) - set_attribute!(L, bool_prop, load_object(s, Bool, bool_prop)) - end - end - for symbol_prop in (:type,) - if haskey(s, symbol_prop) - set_attribute!(L, symbol_prop, load_object(s, Symbol, symbol_prop)) - end - end - if haskey(s, :root_system) - @assert L isa AbstractLieAlgebra # TODO: adapt once we have a proper interface for this - L.root_system = load_typed_object(s, :root_system) - chevalley_basis = load_object( - s, Tuple, [(Vector, (AbstractLieAlgebraElem, L)) for _ in 1:3], :chevalley_basis - ) - # chevalley basis will become an attribute in the near future - end +function load_root_system_data(s::DeserializerState, L::LieAlgebra) + if haskey(s, :root_system) + @assert L isa AbstractLieAlgebra # TODO: adapt once we have a proper interface for this + L.root_system = load_typed_object(s, :root_system) + chevalley_basis = load_object( + s, Tuple, [(Vector, (AbstractLieAlgebraElem, L)) for _ in 1:3], :chevalley_basis + ) + # chevalley basis will become an attribute in the near future end end diff --git a/experimental/LieAlgebras/test/setup_tests.jl b/experimental/LieAlgebras/test/setup_tests.jl index e641bd923ff6..d54a58269fc1 100644 --- a/experimental/LieAlgebras/test/setup_tests.jl +++ b/experimental/LieAlgebras/test/setup_tests.jl @@ -123,7 +123,7 @@ if !isdefined(Main, :lie_algebra_conformance_test) @testset "Serialization" begin mktempdir() do path - test_save_load_roundtrip(path, L) do loaded + test_save_load_roundtrip(path, L; with_attrs=true) do loaded # nothing, cause `L === loaded` anyway end From 863cc95071492970b8cb62c8330d8bee8da7d220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 22 Aug 2024 17:40:35 +0200 Subject: [PATCH 20/20] Add artifact serialization test --- experimental/LieAlgebras/test/setup_tests.jl | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/experimental/LieAlgebras/test/setup_tests.jl b/experimental/LieAlgebras/test/setup_tests.jl index d54a58269fc1..db382a75e835 100644 --- a/experimental/LieAlgebras/test/setup_tests.jl +++ b/experimental/LieAlgebras/test/setup_tests.jl @@ -123,7 +123,25 @@ if !isdefined(Main, :lie_algebra_conformance_test) @testset "Serialization" begin mktempdir() do path - test_save_load_roundtrip(path, L; with_attrs=true) do loaded + is_abelian(L) # call something that puts an attribute on L + + test_save_load_roundtrip( + path, + L; + with_attrs=false, + check_func=loaded -> !has_attribute(loaded, :is_abelian), + ) do loaded + # nothing, cause `L === loaded` anyway + end + + test_save_load_roundtrip( + path, + L; + with_attrs=true, + check_func=loaded -> + has_attribute(loaded, :is_abelian) && + get_attribute(loaded, :is_abelian) == get_attribute(L, :is_abelian), + ) do loaded # nothing, cause `L === loaded` anyway end