Skip to content

Commit

Permalink
Cache precompiled functions without irreversible optimizations for fu…
Browse files Browse the repository at this point in the history
…ture use
  • Loading branch information
zickgraf committed Oct 17, 2024
1 parent 1df67dc commit 4aa6d76
Show file tree
Hide file tree
Showing 12 changed files with 3,947 additions and 86 deletions.
2 changes: 2 additions & 0 deletions CAP/gap/CAP.gi
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ InstallGlobalFunction( "CreateCapCategoryWithDataTypes", FunctionWithNamedArgume

obj!.input_sanity_check_functions := rec( );

obj!.cached_precompiled_functions := rec( );

# convenience for Julia lists
if IsPackageMarkedForLoading( "JuliaInterface", ">= 0.2" ) then

Expand Down
7 changes: 7 additions & 0 deletions CAP/gap/InstallAdds.gi
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ InstallMethod( AddCapOperation,

Add( category!.added_functions.( function_name ), func_to_install );

# if a function for which a cached precompiled function exists is overwritten, drop the cached precompiled function
if IsBound( category!.cached_precompiled_functions.( function_name ) ) then

Unbind( category!.cached_precompiled_functions.( function_name ) );

fi;

replaced_filter_list := CAP_INTERNAL_REPLACED_STRINGS_WITH_FILTERS( record.filter_list, category );

## Nr arguments sanity check
Expand Down
10 changes: 9 additions & 1 deletion CompilerForCAP/gap/CompileCAPOperation.gi
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ InstallGlobalFunction( "CapJitCompiledCAPOperationAsEnhancedSyntaxTree", functio

if not IsBound( cat!.compiled_functions_trees.(operation_name) ) then

function_to_compile := cat!.operations.(operation_name).func;
if IsBound( cat!.cached_precompiled_functions.(operation_name) ) then

function_to_compile := cat!.cached_precompiled_functions.(operation_name);

else

function_to_compile := cat!.operations.(operation_name).func;

fi;

if IsOperation( function_to_compile ) or IsKernelFunction( function_to_compile ) then

Expand Down
60 changes: 38 additions & 22 deletions CompilerForCAP/gap/CompilerForCAP.gi
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,20 @@ InstallGlobalFunction( CAP_JIT_INTERNAL_COMPILED_ENHANCED_SYNTAX_TREE, function

end );

InstallGlobalFunction( CAP_JIT_INTERNAL_POST_PROCESSED_TREE, function ( tree, category )
local changed, pre_func, domains, additional_arguments_func;
InstallGlobalFunction( CAP_JIT_INTERNAL_POST_PROCESSED_TREE, function ( tree, category, args... )
local apply_irreversible_optimizations, changed, pre_func, domains, additional_arguments_func;

Assert( 0, Length( args ) in [ 0, 1 ] );

if Length( args ) = 0 then

apply_irreversible_optimizations := true;

else

apply_irreversible_optimizations := args[1];

fi;

if CAP_JIT_INTERNAL_DEBUG_LEVEL >= 1 then

Expand Down Expand Up @@ -509,7 +521,7 @@ InstallGlobalFunction( CAP_JIT_INTERNAL_POST_PROCESSED_TREE, function ( tree, ca

fi;

tree := CapJitAppliedCompilerHints( tree, category );
tree := CapJitAppliedCompilerHints( tree, category, apply_irreversible_optimizations );

if CAP_JIT_INTERNAL_DEBUG_LEVEL >= 2 then

Expand All @@ -526,27 +538,31 @@ InstallGlobalFunction( CAP_JIT_INTERNAL_POST_PROCESSED_TREE, function ( tree, ca
# do not hoist/deduplicate expressions in proof assistant mode
if not CAP_JIT_PROOF_ASSISTANT_MODE_ENABLED then

# CapJitExtractedExpensiveOperationsFromLoops

if CAP_JIT_INTERNAL_DEBUG_LEVEL >= 2 then
if apply_irreversible_optimizations then

# COVERAGE_IGNORE_BLOCK_START
Print( "#### Continue post-processing of\n" );
Print( "# ", tree.name, "\n" );
Print( "# apply CapJitExtractedExpensiveOperationsFromLoops\n" );
# COVERAGE_IGNORE_BLOCK_END
# CapJitExtractedExpensiveOperationsFromLoops

fi;

tree := CapJitExtractedExpensiveOperationsFromLoops( tree );

if CAP_JIT_INTERNAL_DEBUG_LEVEL >= 2 then
if CAP_JIT_INTERNAL_DEBUG_LEVEL >= 2 then

# COVERAGE_IGNORE_BLOCK_START
Print( "#### Continue post-processing of\n" );
Print( "# ", tree.name, "\n" );
Print( "# apply CapJitExtractedExpensiveOperationsFromLoops\n" );
# COVERAGE_IGNORE_BLOCK_END

fi;

# COVERAGE_IGNORE_BLOCK_START
Print( "# result:\n" );
Display( CapJitPrettyPrintFunction( ENHANCED_SYNTAX_TREE_CODE( tree ) ) );
Print( "\n" );
# COVERAGE_IGNORE_BLOCK_END
tree := CapJitExtractedExpensiveOperationsFromLoops( tree );

if CAP_JIT_INTERNAL_DEBUG_LEVEL >= 2 then

# COVERAGE_IGNORE_BLOCK_START
Print( "# result:\n" );
Display( CapJitPrettyPrintFunction( ENHANCED_SYNTAX_TREE_CODE( tree ) ) );
Print( "\n" );
# COVERAGE_IGNORE_BLOCK_END

fi;

fi;

Expand Down Expand Up @@ -651,7 +667,7 @@ InstallGlobalFunction( CAP_JIT_INTERNAL_POST_PROCESSED_TREE, function ( tree, ca
# However, in this case we might not want to apply the simplification.
# Note: In the case of a single enclosing domain which is equal to the domain, this would more or less correspond to the traditional concept of loop fusion.
# That is why we call it "generalized loop fusion".
while true do
while true and apply_irreversible_optimizations do

changed := false;

Expand Down
5 changes: 3 additions & 2 deletions CompilerForCAP/gap/CompilerHints.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
#! @Section Compilation steps

#! @Description
#! Applies all compiler hints (see <Ref Sect="Section_CompilerHints" />) to <A>tree</A>.
#! Applies compiler hints (see <Ref Sect="Section_CompilerHints" />) to <A>tree</A>.
#! Depending on <A>apply_irreversible_optimizations</A>, only reversible optimizations or all optimizations are applied.
#! @Returns a record
#! @Arguments tree, category
#! @Arguments tree, category, apply_irreversible_optimizations
DeclareGlobalFunction( "CapJitAppliedCompilerHints" );

#! @Description
Expand Down
8 changes: 6 additions & 2 deletions CompilerForCAP/gap/CompilerHints.gi
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
# Implementations
#

InstallGlobalFunction( CapJitAppliedCompilerHints, function ( tree, category )
InstallGlobalFunction( CapJitAppliedCompilerHints, function ( tree, category, apply_irreversible_optimizations )

tree := CapJitReplacedSourceAndRangeAttributes( tree, category );
if apply_irreversible_optimizations then

tree := CapJitReplacedSourceAndRangeAttributes( tree, category );

fi;

# call this at the end because previous functions might want to access the global variables
tree := CapJitReplacedGlobalVariablesByCategoryAttributes( tree, category );
Expand Down
68 changes: 50 additions & 18 deletions CompilerForCAP/gap/PrecompileCategory.gi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Implementations
#
InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_constructor, given_arguments, package_name, compiled_category_name )
local cat1, cat2, cat, transitively_needed_other_packages, operations, diff, source_attribute_getter_name, range_attribute_getter_name, output_string, package_info, parameters, current_string, compiled_tree, compiled_func, function_string, number_of_occurrences_in_string, weight, IsPrecompiledDerivation_string, function_name, current_rec;
local cat1, cat2, cat, transitively_needed_other_packages, operations, diff, source_attribute_getter_name, range_attribute_getter_name, output_string, package_info, parameters, current_string, compiled_tree, reversibly_compiled_tree, reversibly_compiled_func, reversibly_compiled_func_string, fully_compiled_tree, fully_compiled_func, fully_compiled_func_string, number_of_occurrences_in_string, weight, IsPrecompiledDerivation_string, function_name, current_rec;

if IsOperation( category_constructor ) or IsKernelFunction( category_constructor ) then

Expand Down Expand Up @@ -143,23 +143,38 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

compiled_tree := CapJitCompiledCAPOperationAsEnhancedSyntaxTree( cat, function_name );

compiled_tree := CAP_JIT_INTERNAL_POST_PROCESSED_TREE( compiled_tree, cat );
# post-processing only reversible optimizations
reversibly_compiled_tree := CAP_JIT_INTERNAL_POST_PROCESSED_TREE( compiled_tree, cat, false );

# change names of arguments
compiled_tree := CAP_JIT_INTERNAL_REPLACED_FVARS_FUNC_ID(
compiled_tree,
compiled_tree.id,
Concatenation( current_rec.input_arguments_names, compiled_tree.nams{[ compiled_tree.narg + 1 .. Length( compiled_tree.nams ) ]} )
reversibly_compiled_tree := CAP_JIT_INTERNAL_REPLACED_FVARS_FUNC_ID(
reversibly_compiled_tree,
reversibly_compiled_tree.id,
Concatenation( current_rec.input_arguments_names, reversibly_compiled_tree.nams{[ reversibly_compiled_tree.narg + 1 .. Length( reversibly_compiled_tree.nams ) ]} )
);

compiled_func := ENHANCED_SYNTAX_TREE_CODE( compiled_tree );
reversibly_compiled_func := ENHANCED_SYNTAX_TREE_CODE( reversibly_compiled_tree );

function_string := CapJitPrettyPrintFunction( compiled_func );
reversibly_compiled_func_string := CapJitPrettyPrintFunction( reversibly_compiled_func );

if PositionSublist( function_string, "CAP_JIT_INTERNAL_GLOBAL_VARIABLE_" ) <> fail then
# post-processing with irreversible optimizations
fully_compiled_tree := CAP_JIT_INTERNAL_POST_PROCESSED_TREE( compiled_tree, cat, true );

# change names of arguments
fully_compiled_tree := CAP_JIT_INTERNAL_REPLACED_FVARS_FUNC_ID(
fully_compiled_tree,
fully_compiled_tree.id,
Concatenation( current_rec.input_arguments_names, fully_compiled_tree.nams{[ fully_compiled_tree.narg + 1 .. Length( fully_compiled_tree.nams ) ]} )
);

fully_compiled_func := ENHANCED_SYNTAX_TREE_CODE( fully_compiled_tree );

fully_compiled_func_string := CapJitPrettyPrintFunction( fully_compiled_func );

if PositionSublist( fully_compiled_func_string, "CAP_JIT_INTERNAL_GLOBAL_VARIABLE_" ) <> fail then

# COVERAGE_IGNORE_NEXT_LINE
Error( "Could not get rid of all global variables, see <function_string>. You should use compiler_hints.category_attribute_names." );
Error( "Could not get rid of all global variables, see <fully_compiled_func_string>. You should use compiler_hints.category_attribute_names." );

fi;

Expand All @@ -168,7 +183,7 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

if not IsEmpty(
CAP_INTERNAL_FIND_APPEARANCE_OF_SYMBOL_IN_FUNCTION(
compiled_func,
fully_compiled_func,
RecNames( CAP_INTERNAL_METHOD_NAME_RECORD ),
2,
CAP_INTERNAL_METHOD_RECORD_REPLACEMENTS,
Expand All @@ -194,14 +209,14 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

if current_rec.return_type = "bool" then

if number_of_occurrences_in_string( function_string, "CreateCapCategoryObjectWithAttributes" ) + number_of_occurrences_in_string( function_string, "AsCapCategoryObject" ) > 0 then
if number_of_occurrences_in_string( fully_compiled_func_string, "CreateCapCategoryObjectWithAttributes" ) + number_of_occurrences_in_string( fully_compiled_func_string, "AsCapCategoryObject" ) > 0 then

# COVERAGE_IGNORE_NEXT_LINE
Display( Concatenation( "WARNING: Could not eliminate `CreateCapCategoryObjectWithAttributes` or `AsCapCategoryObject` while precompiling ", function_name, "." ) );

fi;

if number_of_occurrences_in_string( function_string, "CreateCapCategoryMorphismWithAttributes" ) + number_of_occurrences_in_string( function_string, "AsCapCategoryMorphism" ) > 0 then
if number_of_occurrences_in_string( fully_compiled_func_string, "CreateCapCategoryMorphismWithAttributes" ) + number_of_occurrences_in_string( fully_compiled_func_string, "AsCapCategoryMorphism" ) > 0 then

# COVERAGE_IGNORE_NEXT_LINE
Display( Concatenation( "WARNING: Could not eliminate `CreateCapCategoryMorphismWithAttributes` or `AsCapCategoryMorphism` while precompiling ", function_name, "." ) );
Expand All @@ -212,7 +227,7 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

if current_rec.return_type = "object" and ValueOption( "number_of_objectified_objects_in_data_structure_of_object" ) <> fail then

if number_of_occurrences_in_string( function_string, "CreateCapCategoryObjectWithAttributes" ) + number_of_occurrences_in_string( function_string, "AsCapCategoryObject" ) > ValueOption( "number_of_objectified_objects_in_data_structure_of_object" ) then
if number_of_occurrences_in_string( fully_compiled_func_string, "CreateCapCategoryObjectWithAttributes" ) + number_of_occurrences_in_string( fully_compiled_func_string, "AsCapCategoryObject" ) > ValueOption( "number_of_objectified_objects_in_data_structure_of_object" ) then

# COVERAGE_IGNORE_NEXT_LINE
Display( Concatenation( "WARNING: Found more than the expected number of occurrences of `CreateCapCategoryObjectWithAttributes` or `AsCapCategoryObject` while precompiling ", function_name, "." ) );
Expand All @@ -223,7 +238,7 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

if current_rec.return_type = "object" and ValueOption( "number_of_objectified_morphisms_in_data_structure_of_object" ) <> fail then

if number_of_occurrences_in_string( function_string, "CreateCapCategoryMorphismWithAttributes" ) + number_of_occurrences_in_string( function_string, "AsCapCategoryMorphism" ) > ValueOption( "number_of_objectified_morphisms_in_data_structure_of_object" ) then
if number_of_occurrences_in_string( fully_compiled_func_string, "CreateCapCategoryMorphismWithAttributes" ) + number_of_occurrences_in_string( fully_compiled_func_string, "AsCapCategoryMorphism" ) > ValueOption( "number_of_objectified_morphisms_in_data_structure_of_object" ) then

# COVERAGE_IGNORE_NEXT_LINE
Display( Concatenation( "WARNING: Found more than the expected number of occurrences of `CreateCapCategoryMorphismWithAttributes` or `AsCapCategoryMorphism` while precompiling ", function_name, "." ) );
Expand All @@ -234,7 +249,7 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

if current_rec.return_type = "morphism" and ValueOption( "number_of_objectified_objects_in_data_structure_of_morphism" ) <> fail then

if number_of_occurrences_in_string( function_string, "CreateCapCategoryObjectWithAttributes" ) + number_of_occurrences_in_string( function_string, "AsCapCategoryObject" ) > ValueOption( "number_of_objectified_objects_in_data_structure_of_morphism" ) then
if number_of_occurrences_in_string( fully_compiled_func_string, "CreateCapCategoryObjectWithAttributes" ) + number_of_occurrences_in_string( fully_compiled_func_string, "AsCapCategoryObject" ) > ValueOption( "number_of_objectified_objects_in_data_structure_of_morphism" ) then

# COVERAGE_IGNORE_NEXT_LINE
Display( Concatenation( "WARNING: Found more than the expected number of occurrences of `CreateCapCategoryObjectWithAttributes` or `AsCapCategoryObject` while precompiling ", function_name, "." ) );
Expand All @@ -245,7 +260,7 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct

if current_rec.return_type = "morphism" and ValueOption( "number_of_objectified_morphisms_in_data_structure_of_morphism" ) <> fail then

if number_of_occurrences_in_string( function_string, "CreateCapCategoryMorphismWithAttributes" ) + number_of_occurrences_in_string( function_string, "AsCapCategoryMorphism" ) > ValueOption( "number_of_objectified_morphisms_in_data_structure_of_morphism" ) then
if number_of_occurrences_in_string( fully_compiled_func_string, "CreateCapCategoryMorphismWithAttributes" ) + number_of_occurrences_in_string( fully_compiled_func_string, "AsCapCategoryMorphism" ) > ValueOption( "number_of_objectified_morphisms_in_data_structure_of_morphism" ) then

# COVERAGE_IGNORE_NEXT_LINE
Display( Concatenation( "WARNING: Found more than the expected number of occurrences of `CreateCapCategoryMorphismWithAttributes` or `AsCapCategoryMorphism` while precompiling ", function_name, "." ) );
Expand Down Expand Up @@ -281,13 +296,30 @@ InstallGlobalFunction( "CapJitPrecompileCategory", function ( category_construct
" Add", function_name, "( cat,\n",
" \n",
"########\n",
function_string, "\n",
fully_compiled_func_string, "\n",
"########\n",
" \n",
" , ", String( weight ), IsPrecompiledDerivation_string, " );\n"
);
output_string := Concatenation( output_string, current_string );

if fully_compiled_func_string <> reversibly_compiled_func_string then

current_string := Concatenation(
" \n",
" ##\n",
" cat!.cached_precompiled_functions.", function_name, " :=\n",
" \n",
"########\n",
reversibly_compiled_func_string, "\n",
"########\n",
" \n",
" ;\n"
);
output_string := Concatenation( output_string, current_string );

fi;

od;

parameters := NamesLocalVariablesFunction( category_constructor ){[ 1 .. NumberArgumentsFunction( category_constructor ) ]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,46 @@ end

, 100 );

##
cat!.cached_precompiled_functions.InterpretMorphismFromDistinguishedObjectToHomomorphismStructureAsMorphism :=

########
function ( cat_1, source_1, range_1, alpha_1 )
local hoisted_1_1, hoisted_3_1, deduped_5_1, hoisted_6_1, deduped_9_1, deduped_10_1, deduped_11_1, deduped_12_1, deduped_13_1, deduped_14_1;
deduped_14_1 := BasisOfRingOverBaseFieldAsColumnVector( cat_1 );
deduped_13_1 := UnderlyingRing( cat_1 );
deduped_12_1 := RankOfObject( source_1 );
deduped_11_1 := RankOfObject( range_1 );
deduped_10_1 := [ 1 .. deduped_11_1 ];
deduped_9_1 := Length( EntriesOfHomalgColumnVector( deduped_14_1 ) );
deduped_5_1 := [ 1 .. deduped_12_1 ];
hoisted_3_1 := UnderlyingMatrix( alpha_1 );
hoisted_1_1 := deduped_12_1 * deduped_9_1;
hoisted_6_1 := List( deduped_10_1, function ( j_2 )
return List( deduped_5_1, function ( s_3 )
local hoisted_1_3, hoisted_2_3, deduped_3_3;
deduped_3_3 := (s_3 - 1) * deduped_9_1;
hoisted_2_3 := deduped_3_3 + deduped_9_1;
hoisted_1_3 := deduped_3_3 + 1;
return List( deduped_10_1, function ( j_4 )
local deduped_1_4;
deduped_1_4 := (j_4 - 1) * hoisted_1_1;
return CertainColumns( hoisted_3_1, [ deduped_1_4 + hoisted_1_3 .. deduped_1_4 + hoisted_2_3 ] );
end )[j_2];
end );
end );
return CreateCapCategoryMorphismWithAttributes( cat_1, source_1, range_1, UnderlyingMatrix, HomalgMatrixListList( List( deduped_10_1, function ( j_2 )
local hoisted_1_2;
hoisted_1_2 := hoisted_6_1[j_2];
return List( deduped_5_1, function ( s_3 )
return EntriesOfHomalgMatrix( CoercedMatrix( deduped_13_1, hoisted_1_2[s_3] ) * deduped_14_1 )[1];
end );
end ), deduped_11_1, deduped_12_1, deduped_13_1 ) );
end
########

;

##
AddIsColiftable( cat,

Expand Down
Loading

0 comments on commit 4aa6d76

Please sign in to comment.