Skip to content

Commit

Permalink
Merge pull request #1694 from zickgraf/master
Browse files Browse the repository at this point in the history
Simplify `Finalize`
  • Loading branch information
zickgraf authored Sep 26, 2024
2 parents dd6f803 + d147c44 commit 6bbb7db
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 140 deletions.
2 changes: 1 addition & 1 deletion CAP/PackageInfo.g
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SetPackageInfo( rec(

PackageName := "CAP",
Subtitle := "Categories, Algorithms, Programming",
Version := "2024.09-26",
Version := "2024.09-28",
Date := (function ( ) if IsBound( GAPInfo.SystemEnvironment.GAP_PKG_RELEASE_DATE ) then return GAPInfo.SystemEnvironment.GAP_PKG_RELEASE_DATE; else return Concatenation( ~.Version{[ 1 .. 4 ]}, "-", ~.Version{[ 6, 7 ]}, "-01" ); fi; end)( ),
License := "GPL-2.0-or-later",

Expand Down
15 changes: 1 addition & 14 deletions CAP/gap/CAP.gi
Original file line number Diff line number Diff line change
Expand Up @@ -288,20 +288,7 @@ InstallGlobalFunction( "CreateCapCategoryWithDataTypes", FunctionWithNamedArgume

obj!.is_computable := CAP_NAMED_ARGUMENTS.is_computable;

#= comment for Julia
if ValueOption( "disable_derivations" ) = true then

# use an empty derivation graph
obj!.derivations_weight_list := MakeOperationWeightList( obj, MakeDerivationGraph( Operations( CAP_INTERNAL_DERIVATION_GRAPH ) ) );

else
# =#

obj!.derivations_weight_list := MakeOperationWeightList( obj, CAP_INTERNAL_DERIVATION_GRAPH );

#= comment for Julia
fi;
# =#
obj!.derivations_weight_list := MakeOperationWeightList( obj, CAP_INTERNAL_DERIVATION_GRAPH );

obj!.caches := rec( );

Expand Down
206 changes: 90 additions & 116 deletions CAP/gap/Finalize.gi
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,10 @@ InstallMethod( Finalize,
FunctionWithNamedArguments(
[
[ "FinalizeCategory", true ],
[ "disable_derivations", false ],
],
function( CAP_NAMED_ARGUMENTS, category )
local derivation_list, weight_list, current_install, current_final_derivation, op_name, new_weight, current_weight, old_weights, properties_with_logic, property, i, derivation, operation, property_name, installed_operations_of_homomorphism_structure, original_REORDER_METHODS_SUSPENSION_LEVEL;
local derivation_list, weight_list, current_install, current_final_derivation, op_name, new_weight, current_weight, properties_with_logic, property, i, derivation, operation, property_name, installed_operations_of_homomorphism_structure, original_REORDER_METHODS_SUSPENSION_LEVEL;

if IsFinalized( category ) then

Expand All @@ -306,142 +307,126 @@ InstallMethod( Finalize,

fi;

#= comment for Julia
if ValueOption( "disable_derivations" ) = true then
if not CAP_NAMED_ARGUMENTS.disable_derivations then

derivation_list := [ ];
weight_list := category!.derivations_weight_list;

else
# =#

derivation_list := ShallowCopy( CAP_INTERNAL_FINAL_DERIVATION_LIST );

#= comment for Julia
fi;
# =#

weight_list := category!.derivations_weight_list;

InstallDerivationsUsingOperation( weight_list, "none" );

for op_name in SortedList( RecNames( weight_list!.operation_weights ) ) do
# ordinary derivations
InstallDerivationsUsingOperation( weight_list, "none" );

if weight_list!.operation_weights.(op_name) <> infinity and weight_list!.operation_derivations.(op_name) = fail then
for op_name in SortedList( RecNames( weight_list!.operation_weights ) ) do

InstallDerivationsUsingOperation( weight_list, op_name );
if weight_list!.operation_weights.(op_name) <> infinity and weight_list!.operation_derivations.(op_name) = fail then

InstallDerivationsUsingOperation( weight_list, op_name );

fi;

fi;

od;

while true do
od;

current_install := fail;
# final derivations
derivation_list := ShallowCopy( CAP_INTERNAL_FINAL_DERIVATION_LIST );

for i in [ 1 .. Length( derivation_list ) ] do
while true do

current_final_derivation := derivation_list[ i ];
current_install := fail;

# check if all conditions for installing the final derivation are met

if not IsApplicableToCategory( current_final_derivation.dummy_derivation, category ) then
for i in [ 1 .. Length( derivation_list ) ] do

continue;
current_final_derivation := derivation_list[ i ];

fi;

if ForAny( current_final_derivation.cannot_compute, operation_name -> CurrentOperationWeight( weight_list, operation_name ) < infinity ) then
# check if all conditions for installing the final derivation are met

continue;
if not IsApplicableToCategory( current_final_derivation.dummy_derivation, category ) then

continue;

fi;

fi;

if OperationWeightUsingDerivation( weight_list, current_final_derivation.dummy_derivation ) = infinity then
if ForAny( current_final_derivation.cannot_compute, operation_name -> CurrentOperationWeight( weight_list, operation_name ) < infinity ) then

continue;

fi;

continue;
if OperationWeightUsingDerivation( weight_list, current_final_derivation.dummy_derivation ) = infinity then

continue;

fi;

fi;

# if we get here, everything matched
current_install := i;
break;

od;

if current_install = fail then

break;

else

current_final_derivation := Remove( derivation_list, current_install );

## call function before adding the method
# if we get here, everything matched
current_install := i;
break;

od;

if current_final_derivation.function_called_before_installation <> false then
if current_install = fail then

current_final_derivation.function_called_before_installation( category );
break;

fi;

for derivation in current_final_derivation.derivations do
else

op_name := TargetOperation( derivation );
new_weight := OperationWeightUsingDerivation( weight_list, derivation );
current_weight := CurrentOperationWeight( weight_list, op_name );
current_final_derivation := Remove( derivation_list, current_install );

Assert( 0, new_weight <> infinity );
## call function before adding the method

# When installing a final derivation bundle, the installation of the first operations in the bundle
# might trigger (normal) derivations of later operations it the bundle, which might be cheaper then
# the derivations provided in the bundle.
if new_weight <= current_weight then
if current_final_derivation.function_called_before_installation <> false then

Info( DerivationInfo, 1, Concatenation( "install(",
String( new_weight ),
") ",
op_name,
": ",
Description( derivation ), "\n" ) );
current_final_derivation.function_called_before_installation( category );

fi;

for derivation in current_final_derivation.derivations do

InstallDerivationForCategory( derivation, new_weight, category : IsFinalDerivation := true );
op_name := TargetOperation( derivation );
new_weight := OperationWeightUsingDerivation( weight_list, derivation );
current_weight := CurrentOperationWeight( weight_list, op_name );

weight_list!.operation_weights.( op_name ) := new_weight;
weight_list!.operation_derivations.( op_name ) := fail;
Assert( 0, new_weight <> infinity );

# if the weight has not changed, there is no need to re-trigger the chain of derivations
if new_weight <> current_weight then
# When installing a final derivation bundle, the installation of the first operations in the bundle
# might trigger (normal) derivations of later operations it the bundle, which might be cheaper then
# the derivations provided in the bundle.
if new_weight <= current_weight then

Info( DerivationInfo, 1, Concatenation( "install(",
String( new_weight ),
") ",
op_name,
": ",
Description( derivation ), "\n" ) );

InstallDerivationForCategory( derivation, new_weight, category : IsFinalDerivation := true );

InstallDerivationsUsingOperation( weight_list, op_name );
weight_list!.operation_weights.( op_name ) := new_weight;
weight_list!.operation_derivations.( op_name ) := fail;

# if the weight has not changed, there is no need to re-trigger the chain of derivations
if new_weight <> current_weight then

InstallDerivationsUsingOperation( weight_list, op_name );

fi;

fi;

fi;
od;

od;
fi;

fi;

od;

# TODO: remove once this check has passed the CI of all packages
# Check if reevaluation triggers new derivations. Derivations are installed recursively by `InstallDerivationsUsingOperation`, so this should never happen.
# See the WARNING below for possible causes why it still might happen.
old_weights := StructuralCopy( weight_list!.operation_weights );

Info( DerivationInfo, 1, "Starting reevaluation of derivation weight list of the category name \"", Name( category ), "\"\n" );

Reevaluate( weight_list );

Info( DerivationInfo, 1, "Finished reevaluation of derivation weight list of the category name \"", Name( category ), "\"\n" );

if weight_list!.operation_weights <> old_weights then
od;

Print( "WARNING: The installed derivations of the category named \"", Name( category ), "\" have changed by reevaluation, which is not expected at this point.\n" );
Print( "This might be due to one of the following reasons:\n" );
Print( "* The category might have gained a new setting like `supports_empty_limits` since adding the first function. Such settings should always be set before adding functions.\n" );
Print( "* The category filter of some derivation might not fulfill the specification.\n" );
Print( "For debugging, call `ActivateDerivationInfo( )`, retry, and look at the derivations between \"Starting reevaluation of ...\" and \"Finished reevaluation of ...\".\n" );
# actually install ordinary derivations
for operation in Operations( DerivationGraph( weight_list ) ) do

if DerivationOfOperation( weight_list, operation ) <> fail then

InstallDerivationForCategory( DerivationOfOperation( weight_list, operation ), CurrentOperationWeight( weight_list, operation ), category );

fi;

od;

fi;

Expand All @@ -463,17 +448,6 @@ InstallMethod( Finalize,

fi;

# actually install normal derivations
for operation in Operations( DerivationGraph( weight_list ) ) do

if DerivationOfOperation( weight_list, operation ) <> fail then

InstallDerivationForCategory( DerivationOfOperation( weight_list, operation ), CurrentOperationWeight( weight_list, operation ), category );

fi;

od;

SetIsFinalized( category, true );

if category!.overhead then
Expand Down
2 changes: 1 addition & 1 deletion CompilerForCAP/PackageInfo.g
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SetPackageInfo( rec(

PackageName := "CompilerForCAP",
Subtitle := "Speed up and verify categorical algorithms",
Version := "2024.09-05",
Version := "2024.09-06",
Date := (function ( ) if IsBound( GAPInfo.SystemEnvironment.GAP_PKG_RELEASE_DATE ) then return GAPInfo.SystemEnvironment.GAP_PKG_RELEASE_DATE; else return Concatenation( ~.Version{[ 1 .. 4 ]}, "-", ~.Version{[ 6, 7 ]}, "-01" ); fi; end)( ),
License := "GPL-2.0-or-later",

Expand Down
20 changes: 12 additions & 8 deletions CompilerForCAP/tst/generate_opposite_derivations.tst
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ gap> CAP_JIT_INTERNAL_COPY_OF_CATEGORY := fail;;
gap> BindGlobal( "GenerateOppositeDerivation", function ( derivation )
> local operation_name, dual_operation_name, list_of_operations_to_install, property_pair, properties, dummy, op, op_op, copy, info, input_arguments_names, filter_list, return_type, prepared_arguments_strings, recoercion_function_string, compiled_func;
>
> PushOptions( rec( disable_derivations := true, overhead := false ) );
> PushOptions( rec( overhead := false ) );
>
> operation_name := TargetOperation( derivation );
>
Expand All @@ -147,7 +147,9 @@ gap> BindGlobal( "GenerateOppositeDerivation", function ( derivation )
> name := Concatenation( "Dummy for ", dual_operation_name ),
> list_of_operations_to_install := list_of_operations_to_install,
> properties := properties,
> ) );
> ) : FinalizeCategory := false );
>
> Finalize( dummy : disable_derivations := true );
>
> StopCompilationAtPrimitivelyInstalledOperationsOfCategory( dummy );
>
Expand All @@ -156,13 +158,15 @@ gap> BindGlobal( "GenerateOppositeDerivation", function ( derivation )
>
> # trigger the derivation manually
> TryToInstallDerivation( op!.derivations_weight_list, derivation );
>
> Assert( 0, CanCompute( op, operation_name ) );
> InstallDerivationForCategory( derivation, CurrentOperationWeight( op!.derivations_weight_list, operation_name ), op );
>
> Finalize( op );
> Finalize( op : disable_derivations := true );
>
> # take the opposite again, where the dual operation is now available
> op_op := Opposite( op, Concatenation( "Double opposite of ", Name( dummy ) ) );
> op_op := Opposite( op, Concatenation( "Double opposite of ", Name( dummy ) ) : FinalizeCategory := false );
>
> Finalize( op_op : disable_derivations := true );
>
> Assert( 0, CanCompute( op_op, dual_operation_name ) );
>
Expand All @@ -180,7 +184,9 @@ gap> BindGlobal( "GenerateOppositeDerivation", function ( derivation )
> modeling_tower_object_datum := { copy, tower_object } -> Opposite( Opposite( tower_object ) ),
> modeling_tower_morphism_constructor := { copy, source, orig_morphism, range } -> MorphismConstructor( ModelingCategory( copy ), source, MorphismConstructor( OppositeCategory( ModelingCategory( copy ) ), Opposite( range ), orig_morphism, Opposite( source ) ), range ),
> modeling_tower_morphism_datum := { copy, tower_morphism } -> Opposite( Opposite( tower_morphism ) ),
> ) );
> ) : FinalizeCategory := false );
>
> Finalize( copy : disable_derivations := true );
>
> # to compute the dual operation in the original category, we coerce objects and morphism to the copy,
> # compute the dual operation there, and re-coerce the result back to the original category
Expand Down Expand Up @@ -280,12 +286,10 @@ gap> BindGlobal( "GenerateOppositeDerivation", function ( derivation )
> return_type
> );
>
> Assert( 0, ValueOption( "disable_derivations" ) = true );
> Assert( 0, ValueOption( "overhead" ) = false );
>
> PopOptions( );
>
> Assert( 0, ValueOption( "disable_derivations" ) = fail );
> Assert( 0, ValueOption( "overhead" ) = fail );
>
> return compiled_func;
Expand Down

0 comments on commit 6bbb7db

Please sign in to comment.