Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion PackageInfo.g
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ Dependencies := rec(
[ "MonoidalCategories", ">= 2019.01.16" ],
],
SuggestedOtherPackages := [ ],
ExternalConditions := [ ],
ExternalConditions := [
[ "CompilerForCAP", ">= 2020.07.06" ],
],
),

AvailabilityTest := function()
Expand Down
125 changes: 125 additions & 0 deletions examples/PrecompileNemoMatrixCategory.gi
Original file line number Diff line number Diff line change
@@ -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
157 changes: 157 additions & 0 deletions gap/CompilerLogic.gi
Original file line number Diff line number Diff line change
@@ -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 );
Loading