Skip to content

Commit 406e31b

Browse files
authored
Merge pull request #659 from zickgraf/CapJitPrecompileCategory
Add CapJitPrecompileCategory
2 parents 653d23b + 5fbd990 commit 406e31b

25 files changed

+1145
-88
lines changed

CAP/gap/CAP.gd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,24 @@ DeclareAttribute( "MorphismFilter",
232232
DeclareAttribute( "TwoCellFilter",
233233
IsCapCategory );
234234

235+
#! @Description
236+
#! The argument is a category $C$.
237+
#! The output is the GAP type of objects of $C$.
238+
#! Only available after calling `AddObjectRepresentation`.
239+
#! @Arguments C
240+
#! @Returns a GAP type
241+
DeclareAttribute( "ObjectType",
242+
IsCapCategory );
243+
244+
#! @Description
245+
#! The argument is a category $C$.
246+
#! The output is the GAP type of morphisms of $C$.
247+
#! Only available after calling `AddMorphismRepresentation`.
248+
#! @Arguments C
249+
#! @Returns a GAP type
250+
DeclareAttribute( "MorphismType",
251+
IsCapCategory );
252+
235253
#! @Description
236254
#! The argument is a category $C$ which is expected to lie in the
237255
#! filter <C>IsLinearCategoryOverCommutativeRing</C>.

CAP/gap/CategoryMorphisms.gi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ InstallMethod( AddMorphismRepresentation,
255255

256256
category!.morphism_representation := representation;
257257
category!.morphism_type := NewType( TheFamilyOfCapCategoryMorphisms, representation and MorphismFilter( category ) and IsCapCategoryMorphismRep and HasSource and HasRange and HasCapCategory );
258+
SetMorphismType( category, category!.morphism_type );
258259

259260
end );
260261

@@ -286,7 +287,7 @@ InstallGlobalFunction( ObjectifyMorphismWithSourceAndRangeForCAPWithAttributes,
286287
#% CAP_JIT_RESOLVE_FUNCTION
287288

288289
arg_list := Concatenation(
289-
[ morphism, category!.morphism_type, CapCategory, category, Source, source, Range, range ], additional_arguments_list
290+
[ morphism, MorphismType( category ), CapCategory, category, Source, source, Range, range ], additional_arguments_list
290291
);
291292

292293
objectified_morphism := CallFuncList( ObjectifyWithAttributes, arg_list );

CAP/gap/CategoryObjects.gi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ InstallMethod( AddObjectRepresentation,
224224

225225
category!.object_representation := representation;
226226
category!.object_type := NewType( TheFamilyOfCapCategoryObjects, representation and ObjectFilter( category ) and IsCapCategoryObjectRep and HasCapCategory );
227+
SetObjectType( category, category!.object_type );
227228

228229
end );
229230

@@ -241,7 +242,7 @@ InstallGlobalFunction( ObjectifyObjectForCAPWithAttributes,
241242
#% CAP_JIT_RESOLVE_FUNCTION
242243

243244
arg_list := Concatenation(
244-
[ object, category!.object_type, CapCategory, category ], additional_arguments_list
245+
[ object, ObjectType( category ), CapCategory, category ], additional_arguments_list
245246
);
246247

247248
return CallFuncList( ObjectifyWithAttributes, arg_list );

CompilerForCAP/doc/Usage.autodoc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,33 @@ If `enable_compilation` is set to `true`, any basic operation will be compiled w
8080
If `enable_compilation` is a list of strings, compilation will only happen if the function name
8181
of the basic operation appears in this list.
8282

83+
@Section Giving hints to the compiler
84+
@SectionLabel CompilerHints
85+
86+
You can give hints to the compiler to improve the result of the compilation. Compiler hints are attached to the category by making
87+
`category!.compiler_hints` a record with one or more of the following keys:
88+
* `category_attributes_names`: a list of names of attributes of the category. If a global variable in the compiled code has the same value
89+
as one of the given attributes of the category, the global variable is replaced by the attribute getter applied to the category.
90+
Background: During the compilation, the compiler resolves attributes occuring in the code and stores them in global variables
91+
called `CAP_JIT_INTERNAL_GLOBAL_VARIABLE_n` (for integers `n` starting from 1). If these variables cannot be replaced,
92+
the resulting code is only valid in the current session.
93+
* `source_and_range_attributes_from_morphism_attribute`: a record with keys `object_attribute_name`, `morphism_attribute_name`, `source_attribute_getter_name`,
94+
and `range_attribute_getter_name`. Replaces the attribute `object_attribute_name` of the source (resp. range)
95+
of a morphism by `source_attribute_getter_name` (resp. `range_attribute_getter_name`) applied to
96+
the attribute `morphism_attribute_name` of the morphism. Can be used if objects and morphisms can be
97+
easily created from the morphism datum anyway. Note: Some simple expressions like integers are NOT replaced.
98+
99+
Note: The compiler can only discover the hints if the category is the first argument of the function.
100+
83101
@Section Stopping the compiler at a certain level
84102

85103
You can use `StopCompilationAtCategory` to prevent the compiler from inlining and optimizing code of a given category.
86104
You can revert this decision using `ContinueCompilationAtCategory`.
87105

106+
@Section Precompiling categories
107+
108+
You can compile categories and store the result in a file for later use.
109+
88110
@Section Getting information about the compilation process
89111

90112
You can increase the info level of `InfoCapJit` to get information about the compilation process.

CompilerForCAP/examples/CAP_JIT_NEXT_FUNCCALL_DOES_NOT_RETURN_FAIL.g

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,20 @@ compiled_func := CapJitCompiledFunction(
1818
MyKernelLift,
1919
[ rows, ZeroMorphism( V, V ), IdentityMorphism( V ) ]
2020
);;
21-
tree := SYNTAX_TREE( compiled_func );;
22-
# check that the fail has been compiled away,
23-
# that is, we simply return a CAP morphism
24-
Length( tree.stats.statements ) = 1;
25-
#! true
26-
tree.stats.statements[1].type = "STAT_RETURN_OBJ";
27-
#! true
28-
StartsWith( tree.stats.statements[1].obj.type, "EXPR_FUNCCALL" );
29-
#! true
30-
tree.stats.statements[1].obj.funcref.type = "EXPR_REF_GVAR";
31-
#! true
32-
tree.stats.statements[1].obj.funcref.gvar = "ObjectifyWithAttributes";
33-
#! true
21+
Display( compiled_func );
22+
#! function ( cat, mor, test_morphism )
23+
#! local cap_jit_morphism_attribute;
24+
#! cap_jit_morphism_attribute
25+
#! := RightDivide( UnderlyingMatrix( test_morphism ),
26+
#! SyzygiesOfRows( UnderlyingMatrix( mor ) ) );
27+
#! return ObjectifyWithAttributes( rec(
28+
#! ), MorphismType( cat ), CapCategory, cat, Source,
29+
#! Source( test_morphism ), Range, ObjectifyWithAttributes( rec(
30+
#! ), ObjectType( cat ), CapCategory, cat, Dimension,
31+
#! NrColumns( cap_jit_morphism_attribute ), UnderlyingFieldForHomalg,
32+
#! UnderlyingRing( cat ) ), UnderlyingFieldForHomalg,
33+
#! UnderlyingRing( cat ), UnderlyingMatrix, cap_jit_morphism_attribute );
34+
#! end
3435

3536
func1 := function( x )
3637
#% CAP_JIT_RESOLVE_FUNCTION

CompilerForCAP/examples/LinearAlgebraForCAP.g

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22

33
#! @Section Examples
44

5-
LoadPackage( "LinearAlgebra" );
5+
LoadPackage( "LinearAlgebraForCAP" );
66

77
#! @Example
88

99
Q := HomalgFieldOfRationals();;
10-
vec := MatrixCategory( Q :
11-
enable_compilation := [ "MorphismBetweenDirectSums" ]
12-
);;
10+
vec := MatrixCategory( Q : enable_compilation := true );;
1311

1412
V := VectorSpaceObject( 2, Q );;
1513
alpha := ZeroMorphism( V, V );;
@@ -32,9 +30,8 @@ Display( SYNTAX_TREE_CODE( tree1 ) );
3230
#! return ZeroMorphism( S, T );
3331
#! else
3432
#! return ObjectifyWithAttributes( rec(
35-
#! ), CAP_JIT_INTERNAL_GLOBAL_VARIABLE_3, CapCategory,
36-
#! CAP_JIT_INTERNAL_GLOBAL_VARIABLE_1, Source, S, Range, T,
37-
#! UnderlyingFieldForHomalg, CAP_JIT_INTERNAL_GLOBAL_VARIABLE_2,
33+
#! ), MorphismType( cat ), CapCategory, cat, Source, S, Range, T,
34+
#! UnderlyingFieldForHomalg, UnderlyingRing( cat ),
3835
#! UnderlyingMatrix,
3936
#! UnionOfRows( List( morphism_matrix, function ( row )
4037
#! return UnionOfColumns( List( row, UnderlyingMatrix ) );
@@ -57,9 +54,8 @@ Display( SYNTAX_TREE_CODE( tree2 ) );
5754
#! return ZeroMorphism( S, T );
5855
#! else
5956
#! return ObjectifyWithAttributes( rec(
60-
#! ), CAP_JIT_INTERNAL_GLOBAL_VARIABLE_3, CapCategory,
61-
#! CAP_JIT_INTERNAL_GLOBAL_VARIABLE_1, Source, S, Range, T,
62-
#! UnderlyingFieldForHomalg, CAP_JIT_INTERNAL_GLOBAL_VARIABLE_2,
57+
#! ), MorphismType( cat ), CapCategory, cat, Source, S, Range, T,
58+
#! UnderlyingFieldForHomalg, UnderlyingRing( cat ),
6359
#! UnderlyingMatrix,
6460
#! UnionOfRows( List( morphism_matrix, function ( row )
6561
#! return UnionOfColumns( List( row, function ( s )
@@ -70,4 +66,20 @@ Display( SYNTAX_TREE_CODE( tree2 ) );
7066
#! return;
7167
#! end
7268

69+
KernelEmbedding( alpha );;
70+
Display( Last( vec!.compiled_functions.KernelEmbedding ) );
71+
#! function ( cat, morphism )
72+
#! local cap_jit_morphism_attribute;
73+
#! cap_jit_morphism_attribute
74+
#! := SyzygiesOfRows( UnderlyingMatrix( morphism ) );
75+
#! return ObjectifyWithAttributes( rec(
76+
#! ), MorphismType( cat ), CapCategory, cat, Source,
77+
#! ObjectifyWithAttributes( rec(
78+
#! ), ObjectType( cat ), CapCategory, cat, Dimension,
79+
#! NrRows( cap_jit_morphism_attribute ), UnderlyingFieldForHomalg,
80+
#! UnderlyingRing( cat ) ), Range, Source( morphism ),
81+
#! UnderlyingFieldForHomalg, UnderlyingRing( cat ), UnderlyingMatrix,
82+
#! cap_jit_morphism_attribute );
83+
#! end
84+
7385
#! @EndExample
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#! @Chapter Examples and tests
2+
3+
#! @Section Examples
4+
5+
LoadPackage( "LinearAlgebraForCAP" );
6+
7+
#! @Example
8+
9+
QQ := HomalgFieldOfRationals( );;
10+
11+
# be careful not to use `MatrixCategory` because attributes are not supported
12+
category_constructor := field -> MATRIX_CATEGORY( field );;
13+
given_arguments := [ QQ ];;
14+
compiled_category_name := "MatrixCategoryPrecompiled";;
15+
package_name := "LinearAlgebraForCAP";;
16+
operations := [
17+
"AdditionForMorphisms",
18+
"PreCompose",
19+
"KernelEmbedding",
20+
];;
21+
22+
filepath := "precompiled_categories/MatrixCategoryPrecompiled.gi";;
23+
old_file_content := ReadFileFromPackageForHomalg( package_name, filepath );;
24+
25+
CapJitPrecompileCategory(
26+
category_constructor,
27+
given_arguments,
28+
package_name,
29+
compiled_category_name :
30+
operations := operations
31+
);
32+
33+
new_file_content := ReadFileFromPackageForHomalg( package_name, filepath );;
34+
35+
old_file_content = new_file_content;
36+
#! true
37+
38+
MatrixCategoryPrecompiled( QQ );
39+
#! Category of matrices over Q
40+
41+
#! @EndExample

CompilerForCAP/gap/CompilerForCAP.gi

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ InstallGlobalFunction( CapJitCompiledFunction, function ( func, jit_args )
191191

192192
od;
193193

194+
if Length( jit_args ) > 0 and IsCapCategory( jit_args[1] ) then
195+
196+
if debug then
197+
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );
198+
Display( compiled_func );
199+
Display( "apply CapJitAppliedCompilerHints" );
200+
fi;
201+
202+
tree := CapJitAppliedCompilerHints( tree, jit_args[1] );
203+
204+
fi;
205+
194206
if debug then
195207

196208
compiled_func := ENHANCED_SYNTAX_TREE_CODE( tree );

CompilerForCAP/gap/CompilerHints.gd

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# SPDX-License-Identifier: GPL-2.0-or-later
2+
# CompilerForCAP: Speed up computations in CAP categories
3+
#
4+
# Declarations
5+
#
6+
#! @Chapter Improving and extending the compiler
7+
8+
#! @Section Compilation steps
9+
10+
#! @Description
11+
#! Applies all compiler hints (see <Ref Sect="Section_CompilerHints" />) to <A>tree</A>.
12+
#! @Returns a record
13+
#! @Arguments tree, category
14+
DeclareGlobalFunction( "CapJitAppliedCompilerHints" );
15+
16+
#! @Description
17+
#! Applies the compiler hint `category_attribute_names` (see <Ref Sect="Section_CompilerHints" />) to <A>tree</A>.
18+
#! Assumes that <A>category</A> is the first argument of the function defined by <A>tree</A>.
19+
#! @Returns a record
20+
#! @Arguments tree, category
21+
DeclareGlobalFunction( "CapJitReplacedGlobalVariablesByCategoryAttributes" );
22+
23+
#! @Description
24+
#! Applies the compiler hint `source_and_range_attributes_from_morphism_attribute` (see <Ref Sect="Section_CompilerHints" />) to <A>tree</A>.
25+
#! @Returns a record
26+
#! @Arguments tree, category
27+
DeclareGlobalFunction( "CapJitReplacedSourceAndRangeAttributes" );

0 commit comments

Comments
 (0)