From f784e1b52bf98c472bce3e341334bd7458635df3 Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 6 Jul 2020 16:52:33 +0200 Subject: [PATCH 1/8] Do not use the shorthand notation "julia_..." The compiler must be able to derive the Julia module and operation from the GAP function call. --- gap/NemoLinearAlgebraForCAP.gi | 91 ++++++++++++---------------------- 1 file changed, 32 insertions(+), 59 deletions(-) diff --git a/gap/NemoLinearAlgebraForCAP.gi b/gap/NemoLinearAlgebraForCAP.gi index ae024ef..2df3b71 100644 --- a/gap/NemoLinearAlgebraForCAP.gi +++ b/gap/NemoLinearAlgebraForCAP.gi @@ -51,33 +51,6 @@ end ); InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( category, nemo_field ) - local julia_transpose, - julia_getindex, - julia_nullspace, - julia_cansolve, - julia_identity_matrix, - julia_zero_matrix, - julia_vcat, - julia_hcat, - julia_kronecker_product; - - julia_getindex := Julia.Base.getindex; - - julia_transpose := Julia.Nemo.transpose; - - julia_nullspace := Julia.Nemo.nullspace; - - julia_cansolve := Julia.Hecke.can_solve; - - julia_identity_matrix := Julia.Nemo.identity_matrix; - - julia_zero_matrix := Julia.Nemo.zero_matrix; - - julia_vcat := Julia.Nemo.vcat; - - julia_hcat := Julia.Nemo.hcat; - - julia_kronecker_product := Julia.Hecke.kronecker_product; ## AddIsEqualForCacheForObjects( category, @@ -109,7 +82,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( object ) local matrix; - matrix := julia_identity_matrix( nemo_field, Dimension( object ) ); + matrix := Julia.Nemo.identity_matrix( nemo_field, Dimension( object ) ); return NemoVectorSpaceMorphism( object, matrix, object ); @@ -158,7 +131,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, return NemoVectorSpaceMorphism( source, - julia_zero_matrix( nemo_field, Dimension( source ), Dimension( range ) ), + Julia.Nemo.zero_matrix( nemo_field, Dimension( source ), Dimension( range ) ), range ); @@ -179,7 +152,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, morphism := NemoVectorSpaceMorphism( sink, - julia_zero_matrix( nemo_field, Dimension( sink ), 0 ), + Julia.Nemo.zero_matrix( nemo_field, Dimension( sink ), 0 ), zero_object ); @@ -194,7 +167,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, morphism := NemoVectorSpaceMorphism( zero_object, - julia_zero_matrix( nemo_field, 0, Dimension( source ) ), + Julia.Nemo.zero_matrix( nemo_field, 0, Dimension( source ) ), source ); @@ -227,15 +200,15 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, dim_factor := Dimension( object_list[ projection_number ] ); projection_in_factor := - julia_zero_matrix( nemo_field, dim_pre, dim_factor ); + Julia.Nemo.zero_matrix( nemo_field, dim_pre, dim_factor ); projection_in_factor := - julia_vcat( projection_in_factor, - julia_identity_matrix( nemo_field, dim_factor ) ); + Julia.Nemo.vcat( projection_in_factor, + Julia.Nemo.identity_matrix( nemo_field, dim_factor ) ); projection_in_factor := - julia_vcat( projection_in_factor, - julia_zero_matrix( nemo_field, dim_post, dim_factor ) ); + Julia.Nemo.vcat( projection_in_factor, + Julia.Nemo.zero_matrix( nemo_field, dim_post, dim_factor ) ); return NemoVectorSpaceMorphism( direct_sum_object, projection_in_factor, object_list[ projection_number ] ); @@ -272,15 +245,15 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, dim_cofactor := Dimension( object_list[ injection_number ] ); - injection_of_cofactor := julia_zero_matrix( nemo_field, dim_cofactor, dim_pre ); + injection_of_cofactor := Julia.Nemo.zero_matrix( nemo_field, dim_cofactor, dim_pre ); injection_of_cofactor := - julia_hcat( injection_of_cofactor, - julia_identity_matrix( nemo_field, dim_cofactor ) ); + Julia.Nemo.hcat( injection_of_cofactor, + Julia.Nemo.identity_matrix( nemo_field, dim_cofactor ) ); injection_of_cofactor := - julia_hcat( injection_of_cofactor, - julia_zero_matrix( nemo_field, dim_cofactor, dim_post ) ); + Julia.Nemo.hcat( injection_of_cofactor, + Julia.Nemo.zero_matrix( nemo_field, dim_cofactor, dim_post ) ); return NemoVectorSpaceMorphism( object_list[ injection_number ], injection_of_cofactor, coproduct ); @@ -296,7 +269,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, for morphism in sink{ [ 2 .. Length( sink ) ] } do underlying_matrix_of_universal_morphism := - julia_vcat( underlying_matrix_of_universal_morphism, UnderlyingMatrix( morphism ) ); + Julia.Nemo.vcat( underlying_matrix_of_universal_morphism, UnderlyingMatrix( morphism ) ); od; @@ -309,19 +282,19 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( morphism ) local kernel_emb, kernel_object; - kernel_emb := julia_nullspace( - julia_transpose( UnderlyingMatrix( morphism ) ) + kernel_emb := Julia.Nemo.nullspace( + Julia.Nemo.transpose( UnderlyingMatrix( morphism ) ) ); kernel_object := NemoVectorSpaceObject( - julia_getindex( kernel_emb, 1 ), + Julia.Base.getindex( kernel_emb, 1 ), category ); kernel_emb := - julia_transpose( - julia_getindex( kernel_emb, 2 ) + Julia.Nemo.transpose( + Julia.Base.getindex( kernel_emb, 2 ) ); return NemoVectorSpaceMorphism( kernel_object, kernel_emb, Source( morphism ) ); @@ -334,19 +307,19 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, local right_divide, sol_exists; right_divide := - julia_cansolve( - julia_transpose( UnderlyingMatrix( beta ) ), julia_transpose( UnderlyingMatrix( alpha ) ) + Julia.Hecke.can_solve( + Julia.Nemo.transpose( UnderlyingMatrix( beta ) ), Julia.Nemo.transpose( UnderlyingMatrix( alpha ) ) ); ## tests if there is no solution - if julia_getindex( right_divide, 1 ) = false then + if Julia.Base.getindex( right_divide, 1 ) = false then return fail; fi; - right_divide := julia_transpose( julia_getindex( right_divide, 2 ) ); + right_divide := Julia.Nemo.transpose( Julia.Base.getindex( right_divide, 2 ) ); return NemoVectorSpaceMorphism( Source( alpha ), right_divide, @@ -359,13 +332,13 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( morphism ) local cokernel_proj, cokernel_obj; - cokernel_proj := julia_nullspace( UnderlyingMatrix( morphism ) ); + cokernel_proj := Julia.Nemo.nullspace( UnderlyingMatrix( morphism ) ); - cokernel_obj := NemoVectorSpaceObject( julia_getindex( cokernel_proj, 1 ), + cokernel_obj := NemoVectorSpaceObject( Julia.Base.getindex( cokernel_proj, 1 ), category ); - cokernel_proj := julia_getindex( cokernel_proj, 2 ); + cokernel_proj := Julia.Base.getindex( cokernel_proj, 2 ); return NemoVectorSpaceMorphism( Range( morphism ), cokernel_proj, cokernel_obj ); @@ -376,16 +349,16 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( alpha, beta ) local left_divide; - left_divide := julia_cansolve( UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ); + left_divide := Julia.Hecke.can_solve( UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ); ## tests if there is no solution - if julia_getindex( left_divide, 1 ) = false then + if Julia.Base.getindex( left_divide, 1 ) = false then return fail; fi; - left_divide := julia_getindex( left_divide, 2 ); + left_divide := Julia.Base.getindex( left_divide, 2 ); return NemoVectorSpaceMorphism( Range( alpha ), left_divide, @@ -418,7 +391,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( new_source, morphism_1, morphism_2, new_range ) return NemoVectorSpaceMorphism( new_source, - julia_kronecker_product( UnderlyingMatrix( morphism_1 ), UnderlyingMatrix( morphism_2 ) ), + Julia.Hecke.kronecker_product( UnderlyingMatrix( morphism_1 ), UnderlyingMatrix( morphism_2 ) ), new_range ); end ); @@ -499,4 +472,4 @@ InstallMethod( Display, Display( UnderlyingMatrix( morphism ) ); -end ); \ No newline at end of file +end ); From b2ab3e83ff92ab0b4c72d2e626a862050d29e084 Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Sat, 4 Jul 2020 12:15:53 +0200 Subject: [PATCH 2/8] Remove superfluous backslashes --- gap/NemoLinearAlgebraForCAP.gi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gap/NemoLinearAlgebraForCAP.gi b/gap/NemoLinearAlgebraForCAP.gi index 2df3b71..1c5b95e 100644 --- a/gap/NemoLinearAlgebraForCAP.gi +++ b/gap/NemoLinearAlgebraForCAP.gi @@ -95,7 +95,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, return NemoVectorSpaceMorphism( Source( alpha ), - Julia.Nemo.("\*")(UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ), + Julia.Nemo.("*")(UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ), Range( beta ) ); @@ -107,7 +107,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, return NemoVectorSpaceMorphism( Source( alpha ), - Julia.Nemo.("\+")( UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ), + Julia.Nemo.("+")( UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ), Range( beta ) ); @@ -119,7 +119,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, return NemoVectorSpaceMorphism( Source( alpha ), - Julia.Nemo.("\-")( UnderlyingMatrix( alpha ) ), + Julia.Nemo.("-")( UnderlyingMatrix( alpha ) ), Range( alpha ) ); From adb4f7521971fceb83a60c342a58325557245f97 Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 6 Jul 2020 17:03:02 +0200 Subject: [PATCH 3/8] Do not assign local variables twice --- gap/NemoLinearAlgebraForCAP.gi | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gap/NemoLinearAlgebraForCAP.gi b/gap/NemoLinearAlgebraForCAP.gi index 1c5b95e..afba075 100644 --- a/gap/NemoLinearAlgebraForCAP.gi +++ b/gap/NemoLinearAlgebraForCAP.gi @@ -280,21 +280,21 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, ## AddKernelEmbedding( category, function( morphism ) - local kernel_emb, kernel_object; + local kernel_emb_pair, kernel_object, kernel_emb; - kernel_emb := Julia.Nemo.nullspace( + kernel_emb_pair := Julia.Nemo.nullspace( Julia.Nemo.transpose( UnderlyingMatrix( morphism ) ) ); kernel_object := NemoVectorSpaceObject( - Julia.Base.getindex( kernel_emb, 1 ), + Julia.Base.getindex( kernel_emb_pair, 1 ), category ); kernel_emb := Julia.Nemo.transpose( - Julia.Base.getindex( kernel_emb, 2 ) + Julia.Base.getindex( kernel_emb_pair, 2 ) ); return NemoVectorSpaceMorphism( kernel_object, kernel_emb, Source( morphism ) ); @@ -304,22 +304,22 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, ## AddLift( category, function( alpha, beta ) - local right_divide, sol_exists; + local right_divide_pair, right_divide; - right_divide := + right_divide_pair := Julia.Hecke.can_solve( Julia.Nemo.transpose( UnderlyingMatrix( beta ) ), Julia.Nemo.transpose( UnderlyingMatrix( alpha ) ) ); ## tests if there is no solution - if Julia.Base.getindex( right_divide, 1 ) = false then + if Julia.Base.getindex( right_divide_pair, 1 ) = false then return fail; fi; - right_divide := Julia.Nemo.transpose( Julia.Base.getindex( right_divide, 2 ) ); + right_divide := Julia.Nemo.transpose( Julia.Base.getindex( right_divide_pair, 2 ) ); return NemoVectorSpaceMorphism( Source( alpha ), right_divide, @@ -330,15 +330,15 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, ## AddCokernelProjection( category, function( morphism ) - local cokernel_proj, cokernel_obj; + local cokernel_proj_pair, cokernel_obj, cokernel_proj; - cokernel_proj := Julia.Nemo.nullspace( UnderlyingMatrix( morphism ) ); + cokernel_proj_pair := Julia.Nemo.nullspace( UnderlyingMatrix( morphism ) ); - cokernel_obj := NemoVectorSpaceObject( Julia.Base.getindex( cokernel_proj, 1 ), + cokernel_obj := NemoVectorSpaceObject( Julia.Base.getindex( cokernel_proj_pair, 1 ), category ); - cokernel_proj := Julia.Base.getindex( cokernel_proj, 2 ); + cokernel_proj := Julia.Base.getindex( cokernel_proj_pair, 2 ); return NemoVectorSpaceMorphism( Range( morphism ), cokernel_proj, cokernel_obj ); @@ -347,18 +347,18 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, ## AddColift( category, function( alpha, beta ) - local left_divide; + local left_divide_pair, left_divide; - left_divide := Julia.Hecke.can_solve( UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ); + left_divide_pair := Julia.Hecke.can_solve( UnderlyingMatrix( alpha ), UnderlyingMatrix( beta ) ); ## tests if there is no solution - if Julia.Base.getindex( left_divide, 1 ) = false then + if Julia.Base.getindex( left_divide_pair, 1 ) = false then return fail; fi; - left_divide := Julia.Base.getindex( left_divide, 2 ); + left_divide := Julia.Base.getindex( left_divide_pair, 2 ); return NemoVectorSpaceMorphism( Range( alpha ), left_divide, From 8f0827eaf9b1960fc49523c7497624cff0dbd5dd Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 6 Jul 2020 17:03:43 +0200 Subject: [PATCH 4/8] Do not use "return Error(...);" --- gap/NemoLinearAlgebraForCAP.gi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gap/NemoLinearAlgebraForCAP.gi b/gap/NemoLinearAlgebraForCAP.gi index afba075..817e0de 100644 --- a/gap/NemoLinearAlgebraForCAP.gi +++ b/gap/NemoLinearAlgebraForCAP.gi @@ -408,9 +408,9 @@ InstallMethodWithCache( NemoVectorSpaceObject, local vector_space_object; if dimension < 0 then - - return Error( "first argument must be a non-negative integer" ); - + + Error( "first argument must be a non-negative integer" ); + fi; vector_space_object := rec( ); @@ -441,9 +441,9 @@ InstallMethod( NemoVectorSpaceMorphism, category := CapCategory( source ); if not IsIdenticalObj( category, CapCategory( range ) ) then - - return Error( "source and range are not defined over identical categories" ); - + + Error( "source and range are not defined over identical categories" ); + fi; vector_space_morphism := rec( ); From bb90abe2d8f9d3f414da076a32a13a7198311759 Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 6 Jul 2020 17:19:00 +0200 Subject: [PATCH 5/8] Apply hcat and vcat to multiple arguments at once --- gap/NemoLinearAlgebraForCAP.gi | 37 ++++++---------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/gap/NemoLinearAlgebraForCAP.gi b/gap/NemoLinearAlgebraForCAP.gi index 817e0de..a2726c1 100644 --- a/gap/NemoLinearAlgebraForCAP.gi +++ b/gap/NemoLinearAlgebraForCAP.gi @@ -200,14 +200,8 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, dim_factor := Dimension( object_list[ projection_number ] ); projection_in_factor := - Julia.Nemo.zero_matrix( nemo_field, dim_pre, dim_factor ); - - projection_in_factor := - Julia.Nemo.vcat( projection_in_factor, - Julia.Nemo.identity_matrix( nemo_field, dim_factor ) ); - - projection_in_factor := - Julia.Nemo.vcat( projection_in_factor, + Julia.Nemo.vcat( Julia.Nemo.zero_matrix( nemo_field, dim_pre, dim_factor ), + Julia.Nemo.identity_matrix( nemo_field, dim_factor ), Julia.Nemo.zero_matrix( nemo_field, dim_post, dim_factor ) ); return NemoVectorSpaceMorphism( direct_sum_object, projection_in_factor, object_list[ projection_number ] ); @@ -219,14 +213,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( diagram, sink, direct_sum ) local underlying_matrix_of_universal_morphism, morphism; - underlying_matrix_of_universal_morphism := UnderlyingMatrix( sink[1] ); - - for morphism in sink{ [ 2 .. Length( sink ) ] } do - - underlying_matrix_of_universal_morphism := - Julia.Nemo.hcat( underlying_matrix_of_universal_morphism, UnderlyingMatrix( morphism ) ); - - od; + underlying_matrix_of_universal_morphism := CallFuncList( Julia.Nemo.hcat, List( sink, s -> UnderlyingMatrix( s ) ) ); return NemoVectorSpaceMorphism( Source( sink[1] ), underlying_matrix_of_universal_morphism, direct_sum ); @@ -245,14 +232,9 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, dim_cofactor := Dimension( object_list[ injection_number ] ); - injection_of_cofactor := Julia.Nemo.zero_matrix( nemo_field, dim_cofactor, dim_pre ); - - injection_of_cofactor := - Julia.Nemo.hcat( injection_of_cofactor, - Julia.Nemo.identity_matrix( nemo_field, dim_cofactor ) ); - injection_of_cofactor := - Julia.Nemo.hcat( injection_of_cofactor, + Julia.Nemo.hcat( Julia.Nemo.zero_matrix( nemo_field, dim_cofactor, dim_pre ), + Julia.Nemo.identity_matrix( nemo_field, dim_cofactor ), Julia.Nemo.zero_matrix( nemo_field, dim_cofactor, dim_post ) ); return NemoVectorSpaceMorphism( object_list[ injection_number ], injection_of_cofactor, coproduct ); @@ -264,14 +246,7 @@ InstallGlobalFunction( INSTALL_FUNCTIONS_FOR_NEMO_MATRIX_CATEGORY, function( diagram, sink, coproduct ) local underlying_matrix_of_universal_morphism, morphism; - underlying_matrix_of_universal_morphism := UnderlyingMatrix( sink[1] ); - - for morphism in sink{ [ 2 .. Length( sink ) ] } do - - underlying_matrix_of_universal_morphism := - Julia.Nemo.vcat( underlying_matrix_of_universal_morphism, UnderlyingMatrix( morphism ) ); - - od; + underlying_matrix_of_universal_morphism := CallFuncList( Julia.Nemo.vcat, List( sink, s -> UnderlyingMatrix( s ) ) ); return NemoVectorSpaceMorphism( coproduct, underlying_matrix_of_universal_morphism, Range( sink[1] ) ); From 3598581c46cc92c50bde29f6c72fff62b34b849e Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 6 Jul 2020 17:13:29 +0200 Subject: [PATCH 6/8] Use CompilerForCAP (if available) The compiler is used to compose Julia function calls in Julia instead of GAP. --- PackageInfo.g | 4 +- gap/CompilerLogic.gi | 157 +++++++++++++++++++++++++++++++++ gap/NemoLinearAlgebraForCAP.gi | 27 +++--- read.g | 8 +- 4 files changed, 177 insertions(+), 19 deletions(-) create mode 100644 gap/CompilerLogic.gi diff --git a/PackageInfo.g b/PackageInfo.g index 9543dd4..d01e1fc 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -76,7 +76,9 @@ Dependencies := rec( [ "MonoidalCategories", ">= 2019.01.16" ], ], SuggestedOtherPackages := [ ], - ExternalConditions := [ ], + ExternalConditions := [ + [ "CompilerForCAP", ">= 2020.07.06" ], + ], ), AvailabilityTest := function() diff --git a/gap/CompilerLogic.gi b/gap/CompilerLogic.gi new file mode 100644 index 0000000..b556da5 --- /dev/null +++ b/gap/CompilerLogic.gi @@ -0,0 +1,157 @@ +BindGlobal( "CAP_JIT_INTERNAL_GET_JULIA_MODULE_AND_OPERATION_OF_FUNCCALL", function( tree ) + + if tree.type = "EXPR_FUNCCALL" then + + if tree.funcref.type = "EXPR_ELM_REC_EXPR" then + + if tree.funcref.expression.type = "EXPR_STRING" and tree.funcref.record.type = "EXPR_ELM_REC_NAME" then + + if tree.funcref.record.record.type = "EXPR_REF_GVAR" and tree.funcref.record.record.gvar = "Julia" then + + return [ tree.funcref.record.name, tree.funcref.expression.value ]; + + fi; + + fi; + + fi; + + if tree.funcref.type = "EXPR_ELM_REC_NAME" then + + if tree.funcref.record.type = "EXPR_ELM_REC_NAME" then + + if tree.funcref.record.record.type = "EXPR_REF_GVAR" and tree.funcref.record.record.gvar = "Julia" then + + return [ tree.funcref.record.name, tree.funcref.name ]; + + fi; + + fi; + + fi; + + fi; + + return fail; + +end ); + +BindGlobal( "CAP_JIT_GLOBAL_JULIA_VARIABLE_COUNTER", 1 ); +MakeReadWriteGlobal( "CAP_JIT_GLOBAL_JULIA_VARIABLE_COUNTER" ); + +# composes Julia function calls in Julia instead of GAP +CapJitAddLogicFunction( function( tree, jit_args ) + local result_func; + + Info( InfoCapJit, 1, "####" ); + Info( InfoCapJit, 1, "Apply logic for Julia function calls." ); + + result_func := function( tree, result, additional_arguments ) + local julia_data, julia_module, julia_operation, arguments_julia_data, gap_call_args, julia_call_args, inner_julia_module, inner_julia_operation, inner_julia_call_args, julia_gvar, julia_function_args, julia_string, key, i; + + if IsList( result ) then + + return result; + + elif IsRecord( result ) then + + tree := ShallowCopy( tree ); + + for key in RecNames( result ) do + + tree.(key) := result.(key); + + od; + + julia_data := CAP_JIT_INTERNAL_GET_JULIA_MODULE_AND_OPERATION_OF_FUNCCALL( tree ); + + if julia_data <> fail then + + julia_module := julia_data[1]; + julia_operation := julia_data[2]; + + arguments_julia_data := List( tree.args, a -> CAP_JIT_INTERNAL_GET_JULIA_MODULE_AND_OPERATION_OF_FUNCCALL( a ) ); + + if ForAny( arguments_julia_data, a -> a <> fail ) then + + gap_call_args := []; + julia_call_args := []; + + for i in [ 1 .. Length( tree.args ) ] do + + if arguments_julia_data[i] = fail then + + Add( julia_call_args, Concatenation( "arg", String( Length( gap_call_args ) + 1 ) ) ); + + Add( gap_call_args, tree.args[i] ); + + else + + inner_julia_module := arguments_julia_data[i][1]; + inner_julia_operation := arguments_julia_data[i][2]; + + inner_julia_call_args := List( [ 1 .. Length( tree.args[i].args ) ], j -> Concatenation( "arg", String( Length( gap_call_args ) + j ) ) ); + + Add( julia_call_args, Concatenation( + inner_julia_module, ".:(", inner_julia_operation, ")(", + JoinStringsWithSeparator( inner_julia_call_args, ", " ), + ")" + ) ); + + gap_call_args := Concatenation( gap_call_args, tree.args[i].args ); + + fi; + + od; + + julia_gvar := Concatenation( "CAP_JIT_GLOBAL_JULIA_VARIABLE_", String( CAP_JIT_GLOBAL_JULIA_VARIABLE_COUNTER ) ); + CAP_JIT_GLOBAL_JULIA_VARIABLE_COUNTER := CAP_JIT_GLOBAL_JULIA_VARIABLE_COUNTER + 1; + + julia_function_args := List( [ 1 .. Length( gap_call_args ) ], i -> Concatenation( "arg", String( i ) ) ); + + julia_string := Concatenation( + "@inline function ", julia_gvar,"(", + JoinStringsWithSeparator( julia_function_args, ", " ), + ")\n", + " return ", julia_module, ".:(", julia_operation, ")(", + JoinStringsWithSeparator( julia_call_args, ", " ), + ");\n", + "end;" + ); + + JuliaEvalString( julia_string ); + + return rec( + type := "EXPR_FUNCCALL", + funcref := rec( + type := "EXPR_ELM_REC_NAME", + name := julia_gvar, + record := rec( + type := "EXPR_ELM_REC_NAME", + name := "Main", + record := rec( + type := "EXPR_REF_GVAR", + gvar := "Julia", + ), + ), + ), + args := gap_call_args, + ); + + fi; + + fi; + + return tree; + + else + + Error( "this should never happen" ); + + fi; + + end; + + return CapJitIterateOverTree( tree, ReturnFirst, result_func, ReturnTrue, true ); + +end ); diff --git a/gap/NemoLinearAlgebraForCAP.gi b/gap/NemoLinearAlgebraForCAP.gi index a2726c1..b52f74d 100644 --- a/gap/NemoLinearAlgebraForCAP.gi +++ b/gap/NemoLinearAlgebraForCAP.gi @@ -380,20 +380,16 @@ InstallMethodWithCache( NemoVectorSpaceObject, [ IsInt, IsCapCategory ], function( dimension, category ) - local vector_space_object; - + #% CAP_JIT_RESOLVE_FUNCTION + if dimension < 0 then Error( "first argument must be a non-negative integer" ); fi; - vector_space_object := rec( ); - - ObjectifyObjectForCAPWithAttributes( vector_space_object, category, - Dimension, dimension ); - - return vector_space_object; + return ObjectifyObjectForCAPWithAttributes( rec(), category, + Dimension, dimension ); end ); @@ -411,7 +407,8 @@ InstallMethod( NemoVectorSpaceMorphism, [ IsNemoVectorSpaceObject, IsJuliaObject, IsNemoVectorSpaceObject ], function( source, matrix, range ) - local vector_space_morphism, homalg_field, category; + local category; + #% CAP_JIT_RESOLVE_FUNCTION category := CapCategory( source ); @@ -421,16 +418,12 @@ InstallMethod( NemoVectorSpaceMorphism, fi; - vector_space_morphism := rec( ); - - ObjectifyMorphismForCAPWithAttributes( vector_space_morphism, category, - Source, source, - Range, range, - UnderlyingMatrix, matrix + return ObjectifyMorphismWithSourceAndRangeForCAPWithAttributes( rec(), category, + source, + range, + UnderlyingMatrix, matrix ); - return vector_space_morphism; - end ); #################################### diff --git a/read.g b/read.g index d4417fa..bc38382 100644 --- a/read.g +++ b/read.g @@ -3,4 +3,10 @@ # # Reading the implementation part of the package. # -ReadPackage( "NemoLinearAlgebraForCAP", "gap/NemoLinearAlgebraForCAP.gi"); +ReadPackage( "NemoLinearAlgebraForCAP", "gap/NemoLinearAlgebraForCAP.gi" ); + +if IsPackageMarkedForLoading( "CompilerForCAP", ">= 2020.07.06" ) then + + ReadPackage( "NemoLinearAlgebraForCAP", "gap/CompilerLogic.gi" ); + +fi; From 416be2b78741c04b68bd6f2206342d5130b4da93 Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 6 Jul 2020 17:23:51 +0200 Subject: [PATCH 7/8] Add .gitignore --- .gitignore | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40c1952 --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +/maketest.g +/tst/nemolinearalgebraforcap*.tst +/doc/*.xml + +/doc/chap*.html +/doc/chap*.txt +/doc/*.css +/doc/*.js +/doc/chooser.html +/doc/*.aux +/doc/*.bbl +/doc/*.blg +/doc/*.brf +/doc/*.idx +/doc/*.ilg +/doc/*.ind +/doc/*.lab +/doc/*.log +/doc/*.out +/doc/*.pnr +/doc/*.six +/doc/*.tex +/doc/*.toc +/doc/manual.pdf + +.deps/ +.dirstamp +.libs/ + +/aclocal.m4 +/autom4te.cache/ +/bin/ +/cnf +/config.log +/config.status +/configure +/lib/ +/libtool +/m4/libtool.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 +/m4/lt~obsolete.m4 +/Makefile +/Makefile.in +/src/pkgconfig.h +/src/stamp-h1 + +*.la +src/*.lo + +/tmp/ +/gh-pages/ + +stats +coverage.json From e0338fdcb7a70c66ec7f81ac6b48227e2bbb3f29 Mon Sep 17 00:00:00 2001 From: Fabian Zickgraf Date: Mon, 7 Feb 2022 16:52:18 +0100 Subject: [PATCH 8/8] ENHANCED_SYNTAX_TREE_CODE_JULIA --- examples/PrecompileNemoMatrixCategory.gi | 125 +++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 examples/PrecompileNemoMatrixCategory.gi diff --git a/examples/PrecompileNemoMatrixCategory.gi b/examples/PrecompileNemoMatrixCategory.gi new file mode 100644 index 0000000..0b3d3c7 --- /dev/null +++ b/examples/PrecompileNemoMatrixCategory.gi @@ -0,0 +1,125 @@ +#! @Chapter Examples and Tests + +#! @Section Tests + +#! @Example + +LoadPackage( "NemoLinearAlgebraForCAP", false );; +#! true + +QQ := Julia.Nemo.QQ;; + +category_constructor := nemo_field -> NemoMatrixCategory( nemo_field );; +given_arguments := [ QQ ];; +compiled_category_name := +"NemoMatrixCategoryPrecompiled";; +package_name := "NemoLinearAlgebraForCAP";; + +operations := ListPrimitivelyInstalledOperationsOfCategory( NemoMatrixCategory( QQ ) ); + +CapJitPrecompileCategoryAndCompareResult( + category_constructor, + given_arguments, + package_name, + compiled_category_name : + operations := operations +); + +ReadPackage( "NemoLinearAlgebraForCAP", "gap/precompiled_categories/NemoMatrixCategoryPrecompiled.gi" ); + +cat := NemoMatrixCategoryPrecompiled( QQ ); + +julia_core := Concatenation( """#!/usr/bin/julia + +CAP_OPERATION_NAMES = [ + """, "\"", JoinStringsWithSeparator( operations, "\",\n \"" ), "\",", """ +] + +for operation_name in CAP_OPERATION_NAMES + eval(Meta.parse(operation_name * " = (cat, args...) -> cat.operations[\"" * operation_name * "\"](cat, args...)")) +end + +# CapCategory +struct CapCategory + name::String + attributes::Dict + operations::Dict +end + +CapCategory(name) = CapCategory(name, Dict(), Dict()) +CapCategory() = CapCategory("A CAP category") + +function Base.show(io::IO, cat::CapCategory) + print(io, cat.name) +end + +# CapCategoryObject +struct CapCategoryObject + cat::CapCategory + object_datum::Any +end + +function Base.show(io::IO, obj::CapCategoryObject) + print(io, "An object in " * obj.cat.name) +end + +# CapCategoryMorphism +struct CapCategoryMorphism + cat::CapCategory + source::CapCategoryObject + morphism_datum::Any + range::CapCategoryObject +end + +function Base.show(io::IO, obj::CapCategoryMorphism) + print(io, "A morphism in " * obj.cat.name) +end + +""" ); + + +output_string := ""; + +output_string := Concatenation( output_string, julia_core ); + +#for func in CAP_JIT_JULIA_GLOBAL_FUNCTIONS do +# +# output_string := Concatenation( output_string, func, "\n" ); +# +#od; + +output_string := Concatenation( output_string, "\n" ); + +arguments_names := List( [ 1 .. Length( given_arguments ) ], i -> Concatenation( "category_attribute_", String( i ) ) ); + +output_string := Concatenation( output_string, compiled_category_name, " = function(", JoinStringsWithSeparator( arguments_names, ", " ), ")\n\ncat = CapCategory(\"", Name( cat ), "\")\n" ); + +for name in arguments_names do + + output_string := Concatenation( output_string, "cat.attributes[\"", name, "\"] = ", name, ";\n" ); + +od; + +output_string := Concatenation( output_string, "\n" ); + +for name in operations do + + func := Last( cat!.added_functions.(name) )[1]; + + Display( func ); + + tree := ENHANCED_SYNTAX_TREE( func ); + + code := ENHANCED_SYNTAX_TREE_CODE_JULIA( tree ); + + output_string := Concatenation( output_string, "cat.operations[\"", name, "\"] = ", code, ";\n\n" ); + +od; + +output_string := Concatenation( output_string, "return cat;\n\nend;\n" ); + +WriteFileInPackageForHomalg( package_name, Concatenation( "precompiled_categories/", compiled_category_name, ".jl" ), output_string ); + +#! @EndExample + +#! @EndChunk