Skip to content

Commit

Permalink
Merge pull request #724 from zickgraf/misc
Browse files Browse the repository at this point in the history
Miscellaneous changes
  • Loading branch information
zickgraf authored Oct 15, 2021
2 parents 0de157b + 151c1a1 commit 7379063
Show file tree
Hide file tree
Showing 20 changed files with 820 additions and 190 deletions.
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 computations in CAP categories",
Version := "2021.10-02",
Version := "2021.10-03",
Date := Concatenation( "01/", ~.Version{[ 6, 7 ]}, "/", ~.Version{[ 1 .. 4 ]} ),
License := "GPL-2.0-or-later",

Expand Down
89 changes: 89 additions & 0 deletions CompilerForCAP/examples/CapJitDeduplicatedExpressions.g
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#! @Chapter Examples and tests

#! @Section Tests

#! @Example

LoadPackage( "CompilerForCAP", false );
#! true

##
# duplicate code inside a function
func := function( x )
return List( [ 1 .. 9 ], y -> (y + (x + 1)) + (y + (x + 1)) ); end;;

tree := ENHANCED_SYNTAX_TREE( func );;
tree := CapJitDeduplicatedExpressions( tree );;
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );;
Display( compiled_func );
#! function ( x_1 )
#! return List( [ 1 .. 9 ], function ( y_2 )
#! local cap_jit_deduplicated_expression_1_2;
#! cap_jit_deduplicated_expression_1_2 := y_2 + (x_1 + 1);
#! return cap_jit_deduplicated_expression_1_2
#! + cap_jit_deduplicated_expression_1_2;
#! end );
#! end

##
# duplicate code inside duplicate code
func := function( x, y )
return (y + (x + 1) + (x + 1)) + (y + (x + 1) + (x + 1)); end;;

tree := ENHANCED_SYNTAX_TREE( func );;
tree := CapJitDeduplicatedExpressions( tree );;
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );;
Display( compiled_func );
#! function ( x_1, y_1 )
#! local cap_jit_deduplicated_expression_1_1,
#! cap_jit_deduplicated_expression_2_1;
#! cap_jit_deduplicated_expression_2_1 := x_1 + 1;
#! cap_jit_deduplicated_expression_1_1
#! := y_1 + cap_jit_deduplicated_expression_2_1
#! + cap_jit_deduplicated_expression_2_1;
#! return cap_jit_deduplicated_expression_1_1
#! + cap_jit_deduplicated_expression_1_1;
#! end

##
# don't deduplicate code accross functions
func := function( )
return [ [ x -> (x + 1) + 2 ], [ x -> (x + 1) + 3 ] ]; end;;

tree := ENHANCED_SYNTAX_TREE( func );;
tree := CapJitDeduplicatedExpressions( tree );;
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );;
Display( compiled_func );
#! function ( )
#! return [ [ function ( x_2 )
#! return x_2 + 1 + 2;
#! end ], [ function ( x_2 )
#! return x_2 + 1 + 3;
#! end ] ];
#! end

##
# duplicate code inside duplicate code at different function levels
func := {} ->
y -> [ [ y, x -> (x + 1) + (x + 1) ], [ y, x -> (x + 1) + (x + 1) ] ];;

tree := ENHANCED_SYNTAX_TREE( func );;
tree := CapJitDeduplicatedExpressions( tree );;
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );;
Display( compiled_func );
#! function ( )
#! return function ( y_2 )
#! local cap_jit_deduplicated_expression_1_2;
#! cap_jit_deduplicated_expression_1_2 := [ y_2, function ( x_3 )
#! local cap_jit_deduplicated_expression_2_3;
#! cap_jit_deduplicated_expression_2_3 := x_3 + 1;
#! return cap_jit_deduplicated_expression_2_3
#! + cap_jit_deduplicated_expression_2_3;
#! end ];
#! return
#! [ cap_jit_deduplicated_expression_1_2,
#! cap_jit_deduplicated_expression_1_2 ];
#! end;
#! end

#! @EndExample
24 changes: 24 additions & 0 deletions CompilerForCAP/examples/CapJitIsEqualForEnhancedSyntaxTrees.g
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#! @Chapter Examples and tests

#! @Section Tests

#! @Example

LoadPackage( "CompilerForCAP", false );
#! true

# test that `CAP_JIT_NOT_RESOLVABLE` does not cause errors when comparing
# syntax trees
DeclareOperation( "MyNonResolvableOperation", [ ] );

func := { } -> MyNonResolvableOperation( );;

tree := ENHANCED_SYNTAX_TREE( func );;

tree2 := StructuralCopy( tree );;
tree2.bindings.BINDING_RETURN_VALUE.funcref.CAP_JIT_NOT_RESOLVABLE := true;;

CapJitIsEqualForEnhancedSyntaxTrees( tree, tree2 );
#! true

#! @EndExample
16 changes: 9 additions & 7 deletions CompilerForCAP/examples/LinearAlgebraForCAP.g
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ tree1 := SYNTAX_TREE(
);;
Display( SYNTAX_TREE_CODE( tree1 ) );
#! function ( cat_1, S_1, diagram_S_1, morphism_matrix_1, diagram_T_1, T_1 )
#! local cap_jit_hoisted_expression_1_1;
#! cap_jit_hoisted_expression_1_1 := UnderlyingRing( cat_1 );
#! local cap_jit_hoisted_expression_1_1, cap_jit_deduplicated_expression_1_1;
#! cap_jit_deduplicated_expression_1_1 := UnderlyingRing( cat_1 );
#! cap_jit_hoisted_expression_1_1 := cap_jit_deduplicated_expression_1_1;
#! return ObjectifyMorphismWithSourceAndRangeForCAPWithAttributes( rec(
#! ), cat_1, S_1, T_1, UnderlyingMatrix,
#! UnionOfRows( UnderlyingRing( cat_1 ), Dimension( T_1 ),
#! UnionOfRows( cap_jit_deduplicated_expression_1_1, Dimension( T_1 ),
#! ListN( diagram_S_1, List( morphism_matrix_1, function ( row_2 )
#! return List( row_2, UnderlyingMatrix );
#! end ), function ( source_2, row_2 )
Expand All @@ -52,11 +53,12 @@ tree2 := SYNTAX_TREE( CapJitCompiledFunction(
) );;
Display( SYNTAX_TREE_CODE( tree2 ) );
#! function ( cat_1, S_1, diagram_S_1, morphism_matrix_1, diagram_T_1, T_1 )
#! local cap_jit_hoisted_expression_1_1;
#! cap_jit_hoisted_expression_1_1 := UnderlyingRing( cat_1 );
#! local cap_jit_hoisted_expression_1_1, cap_jit_deduplicated_expression_1_1;
#! cap_jit_deduplicated_expression_1_1 := UnderlyingRing( cat_1 );
#! cap_jit_hoisted_expression_1_1 := cap_jit_deduplicated_expression_1_1;
#! return ObjectifyMorphismWithSourceAndRangeForCAPWithAttributes( rec(
#! ), cat_1, S_1, T_1, UnderlyingMatrix,
#! UnionOfRows( UnderlyingRing( cat_1 ), Dimension( T_1 ),
#! ), cat_1, S_1, T_1, UnderlyingMatrix,
#! UnionOfRows( cap_jit_deduplicated_expression_1_1, Dimension( T_1 ),
#! ListN( diagram_S_1, morphism_matrix_1,
#! function ( logic_new_func_x_2, logic_new_func_y_2 )
#! return UnionOfColumns( cap_jit_hoisted_expression_1_1,
Expand Down
103 changes: 97 additions & 6 deletions CompilerForCAP/examples/LogicTemplates.g
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ Display( applied_logic_template_to_func( func, template, [ ] ) );
#! end

# general example not returning a value
template := StructuralCopy( template );;
template.src_template :=
Concatenation( "return ", template.src_template, ";" );;
template.dst_template :=
Concatenation( "return ", template.dst_template, ";" );;
template.returns_value := false;;
# we have to work hard to not write semicolons so AutoDoc
# does not begin a new statement
template := EvalString( ReplacedString( """rec(
variable_names := [ "variable" ],
src_template := "return x -> x + variable + x - x@",
dst_template := "return x -> x + variable + 0@",
returns_value := false,
)""", "@", ";" ) );;

Display( applied_logic_template_to_func( func, template, [ ] ) );
#! function ( a_1 )
Expand Down Expand Up @@ -84,6 +86,70 @@ Display( applied_logic_template_to_func( func, template, [ [ ], [ ] ] ) );
#! end );
#! end

# check that template is not executed if variable filters but not enough
# jit_args are given
template := rec(
variable_names := [ "L1", "L2", "func" ],
variable_filters := [ "IsList", IsList, IsFunction ],
src_template := "Concatenation( List( L1, func ), List( L2, func ) )",
dst_template := "List( Concatenation( L1, L2 ), func )",
returns_value := true,
);;

func := function ( L1, L2 )
return Concatenation( List( L1, x -> x ), List( L2, x -> x ) ); end;;

Display( applied_logic_template_to_func( func, template, [ ] ) );
#! function ( L1_1, L2_1 )
#! return Concatenation( List( L1_1, function ( x_2 )
#! return x_2;
#! end ), List( L2_1, function ( x_2 )
#! return x_2;
#! end ) );
#! end

# check that template is only applied if filters match
template := rec(
variable_names := [ "value" ],
variable_filters := [ IsInt ],
src_template := "Sum( [ value ] )",
dst_template := "value",
returns_value := true,
);;

func := { x } -> Sum( [ x ] );;

Display( applied_logic_template_to_func( func, template, [ 1/2 ] ) );
#! function ( x_1 )
#! return Sum( [ x_1 ] );
#! end
Display( applied_logic_template_to_func( func, template, [ 1 ] ) );
#! function ( x_1 )
#! return x_1;
#! end

# check that template is skipped if values cannot be determined from jit_args
template := EvalString( ReplacedString( """rec(
variable_names := [ "value1", "value2" ],
variable_filters := [ IsInt, IsObject ],
src_template := "if 1 <> 1 then return value1@ else return value2@ fi@",
dst_template := "return value2@",
returns_value := false,
)""", "@", ";" ) );;

func := function ( )
if 1 <> 1 then return 1; else return 1; fi; end;;

Display( applied_logic_template_to_func( func, template, [ ] ) );
#! function ( )
#! if 1 <> 1 then
#! return 1;
#! else
#! return 1;
#! fi;
#! return;
#! end

# check that functions can be used multiple times in dst_template
# add a nonsense template
template := rec(
Expand Down Expand Up @@ -143,4 +209,29 @@ Display( applied_logic_template_to_func( func, template, [ ] ) );
#! end );
#! end

# check that values are pulled out iff
# they are independent of local variables
template := rec(
variable_names := [ "list", "value" ],
src_template := "List( list, l -> value * l )",
dst_template := "value * List( list, l -> l )",
returns_value := true,
);;

func := L -> List( L, l -> l * l );;
Display( applied_logic_template_to_func( func, template, [ ] ) );
#! function ( L_1 )
#! return List( L_1, function ( l_2 )
#! return l_2 * l_2;
#! end );
#! end

func := L -> List( L, l -> 2 * l );;
Display( applied_logic_template_to_func( func, template, [ ] ) );
#! function ( L_1 )
#! return 2 * List( L_1, function ( l_2 )
#! return l_2;
#! end );
#! end

#! @EndExample
10 changes: 10 additions & 0 deletions CompilerForCAP/gap/CompilerForCAP.gi
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,16 @@ InstallGlobalFunction( CapJitCompiledFunctionAsEnhancedSyntaxTree, function ( fu

tree := CapJitHoistedExpressions( tree );

if debug then
# COVERAGE_IGNORE_BLOCK_START
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );
Display( compiled_func );
Error( "apply CapJitDeduplicatedExpressions" );
# COVERAGE_IGNORE_BLOCK_END
fi;

tree := CapJitDeduplicatedExpressions( tree );

if debug then

# COVERAGE_IGNORE_BLOCK_START
Expand Down
14 changes: 14 additions & 0 deletions CompilerForCAP/gap/DeduplicateExpressions.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# CompilerForCAP: Speed up computations in CAP categories
#
# Declarations
#
#! @Chapter Improving and extending the compiler

#! @Section Compilation steps

#! @Description
#! Deduplicates expressions occuring at least twice in the enhanced syntax tree <A>tree</A>.
#! @Returns a record
#! @Arguments tree
DeclareGlobalFunction( "CapJitDeduplicatedExpressions" );
Loading

0 comments on commit 7379063

Please sign in to comment.