Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove JuliaFunction and a bunch of C code #1047

Merged
merged 1 commit into from
Sep 20, 2024
Merged
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
2 changes: 1 addition & 1 deletion pkg/JuliaExperimental/ipynb/GAPJulia_Singular_car.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
}
],
"source": [
"i:= JuliaFunction( \"Matrix\", \"Singular\" )( I );"
"i:= Julia.Singular.Matrix( I );"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion pkg/JuliaExperimental/tst/singular_blog.tst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ gap> M:= Julia.Singular.syz( I );
x*gen(3)-2*x*gen(2)+y*gen(3)-y*gen(2)-z*gen(2)
y^2*gen(3)-y^2*gen(2)-y*z*gen(2)-y*gen(1)+z*gen(1)-gen(3)+2*gen(2)
x*y*gen(2)-x*gen(1)-y*gen(1)+gen(2)>
gap> JuliaFunction( "Matrix", "Singular" )( M );
gap> Julia.Singular.Matrix( M );
<Julia: [0, -y+z, -x-y
-2*x-y-z, -y^2-y*z+2, x*y+1
x+y, y^2-1, 0]>
Expand Down
23 changes: 4 additions & 19 deletions pkg/JuliaInterface/example/function_perform.gi
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,17 @@ dirs:= DirectoriesPackageLibrary( "JuliaInterface", "example" );

JuliaIncludeFile( Filename( dirs, "function_perform.jl" ) );

typed_func := JuliaFunction("typed_func", "GapFunctionPerform");
typed_funcNoConv := _JuliaFunctionByModule("typed_func", "GapFunctionPerform");

untyped_func := JuliaFunction("untyped_func");
untyped_funcNoConv := _JuliaFunction("untyped_func");
return_first := Julia.GapFunctionPerform.return_first;

GASMAN("collect"); ListX([1..10^5], [1..10], {i,j} -> i);; time;
GASMAN("collect"); ListX([1..10^5], [1..10], ReturnFirst);; time;
GASMAN("collect"); ListX([1..10^5], [1..10], typed_func);; time;
GASMAN("collect"); ListX([1..10^5], [1..10], untyped_func);; time;
GASMAN("collect"); ListX([1..10^5], [1..10], typed_funcNoConv);; time;
GASMAN("collect"); ListX([1..10^5], [1..10], untyped_funcNoConv);; time;

GASMAN("collect"); ListX([1..10^5], [1..10], return_first);; time;

GASMAN("collect"); ListX("0123456789", [1..10^5], {i,j} -> i);; time;
GASMAN("collect"); ListX("0123456789", [1..10^5], ReturnFirst);; time;
GASMAN("collect"); ListX("0123456789", [1..10^5], typed_func);; time;
GASMAN("collect"); ListX("0123456789", [1..10^5], untyped_func);; time;
GASMAN("collect"); ListX("0123456789", [1..10^5], typed_funcNoConv);; time;
GASMAN("collect"); ListX("0123456789", [1..10^5], untyped_funcNoConv);; time;

GASMAN("collect"); ListX("0123456789", [1..10^5], return_first);; time;

input:=ListWithIdenticalEntries(10^5,fail);;
GASMAN("collect"); ListX("0123456789", input, {i,j} -> i);; time;
GASMAN("collect"); ListX("0123456789", input, ReturnFirst);; time;
GASMAN("collect"); ListX("0123456789", input, typed_func);; time;
GASMAN("collect"); ListX("0123456789", input, untyped_func);; time;
GASMAN("collect"); ListX("0123456789", input, typed_funcNoConv);; time;
GASMAN("collect"); ListX("0123456789", input, untyped_funcNoConv);; time;
GASMAN("collect"); ListX("0123456789", input, return_first);; time;
22 changes: 2 additions & 20 deletions pkg/JuliaInterface/example/function_perform.jl
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
module GapFunctionPerform

import GAP: GapObj

function typed_func(a::GapObj, b::GapObj)
return a
end

function typed_func(a::GapObj, b::Int64)
return a
end

function typed_func(a::Int64, b::GapObj)
function return_first(a, b)
return a
end

function typed_func(a::Int64, b::Int64)
return a
end

end

function untyped_func(a, b)
return a
end
end
4 changes: 1 addition & 3 deletions pkg/JuliaInterface/example/orbits.gi
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ end;
example_dirs := DirectoriesPackageLibrary( "JuliaInterface", "example" );
JuliaIncludeFile( Filename( example_dirs, "orbits.jl" ) );

bahn_jl := JuliaFunction( "bahn" );

grp := SymmetricGroup( 10000 );
gens := GeneratorsOfGroup( grp );;

bahn(1, gens, OnPoints);;time;
bahn_jl(1, gens, OnPoints);;time;
Julia.bahn(1, gens, OnPoints);;time;
46 changes: 1 addition & 45 deletions pkg/JuliaInterface/gap/JuliaInterface.gd
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ DeclareAttribute( "JuliaPointer", IsJuliaWrapper );
#! true
#! gap> Julia.GAP.julia_to_gap;
#! <Julia: julia_to_gap>
#! gap> JuliaFunction( "julia_to_gap", "GAP" ); # the same function
#! <Julia: julia_to_gap>
#! @EndExampleSession
DeclareCategory( "IsJuliaModule", IsJuliaWrapper and IsRecord );

Expand Down Expand Up @@ -246,47 +244,6 @@ DeclareGlobalFunction( "JuliaImportPackage" );

#! @Section Access to &Julia; objects

#! @Arguments function_name[, module_name]
#! @Returns a function
#! @Description
#! Returns a &GAP; function that wraps the &Julia; function with identifier
#! <A>function_name</A> from the module <A>module_name</A>.
#! Both arguments must be strings.
#! If <A>module_name</A> is not given,
#! the function is taken from &Julia;'s <C>Main</C> module.
#!
#! @BeginExampleSession
#! gap> fun:= JuliaFunction( "sqrt" );
#! <Julia: sqrt>
#! gap> Print( fun );
#! function ( arg... )
#! <<kernel code>> from Julia:sqrt
#! end
#! gap> IsFunction( fun );
#! true
#! gap> IsJuliaObject( fun );
#! false
#! @EndExampleSession
#!
#! Alternatively, one can access &Julia; functions also via the global object
#! <Ref Var="Julia"/>, as follows.
#!
#! @BeginExampleSession
#! gap> Julia.sqrt;
#! <Julia: sqrt>
#! @EndExampleSession
#!
#! Note that each call to <Ref Func="JuliaFunction"/> and each component
#! access to <Ref Var="Julia"/> create a <E>new</E> &GAP; object.
#!
#! @BeginExampleSession
#! gap> IsIdenticalObj( JuliaFunction( "sqrt" ), JuliaFunction( "sqrt" ) );
#! false
#! gap> IsIdenticalObj( Julia.sqrt, Julia.sqrt );
#! false
#! @EndExampleSession
DeclareGlobalFunction( "JuliaFunction" );

#! @Description
#! This global variable represents the &Julia; module <C>Main</C>,
#! see <Ref Filt="IsJuliaModule" Label="for IsJuliaWrapper and IsRecord"/>.
Expand Down Expand Up @@ -411,8 +368,7 @@ DeclareGlobalFunction( "CallJuliaFunctionWithKeywordArguments" );
#! <Julia: 1.4142135623730951>
#! @EndExampleSession
#! In fact, there are slightly different kinds of function calls.
#! A &Julia; function such as <C>Julia.sqrt</C>
#! (or equivalently <C>JuliaFunction( "sqrt" )</C>) is represented by
#! A &Julia; function such as <C>Julia.sqrt</C> is represented by
#! a &GAP; function object,
#! and calls to it are executed on the C level,
#! using &Julia;'s <C>jl_call</C>.
Expand Down
36 changes: 13 additions & 23 deletions pkg/JuliaInterface/gap/JuliaInterface.gi
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,9 @@
# Implementations
#

InstallGlobalFunction( JuliaFunction,
function( arglist... )
if Length( arglist ) = 1 and IsString( arglist[ 1 ] ) then
return _JuliaFunction( arglist[ 1 ] );
elif Length( arglist ) = 2 and ForAll( arglist, IsString ) then
return _JuliaFunctionByModule( arglist[1], arglist[2] );
fi;
Error( "arguments must be strings function_name[,module_name]" );
end );

BindGlobal( "_JULIA_MODULE_TYPE", _JuliaGetGlobalVariable( "Module" ) );
BindGlobal( "_JULIA_FUNCTION_TYPE", _JuliaGetGlobalVariable( "Function" ) );
BindGlobal( "_JULIA_ISA", JuliaFunction( "isa" ) );
BindGlobal( "_JULIA_MODULE_TYPE", _JuliaGetGlobalVariableByModule( "Module", "Core" ) );
BindGlobal( "_JULIA_FUNCTION_TYPE", _JuliaGetGlobalVariableByModule( "Function", "Core" ) );
BindGlobal( "_JULIA_ISA", _WrapJuliaFunction( _JuliaGetGlobalVariableByModule( "isa", "Core" ) ) );

BindGlobal( "_WrapJuliaModule",
function( name, julia_pointer )
Expand Down Expand Up @@ -44,27 +34,27 @@ InstallMethod( ViewString,
InstallMethod( \.,
[ "IsJuliaModule", "IsPosInt" ],
function( module, rnum )
local rnam, global_variable;
local rnam, var;

if IsBound\.( module!.storage, rnum ) then
return \.(module!.storage, rnum );
fi;

rnam := NameRNam( rnum );

global_variable := _JuliaGetGlobalVariableByModule( rnam, JuliaPointer( module ) );
if global_variable = fail then
var := _JuliaGetGlobalVariableByModule( rnam, JuliaPointer( module ) );
if var = fail then
Error( rnam, " is not bound in Julia" );
fi;

if _JULIA_ISA( global_variable, _JULIA_FUNCTION_TYPE ) then
global_variable := _JuliaFunction( global_variable );
elif _JULIA_ISA( global_variable, _JULIA_MODULE_TYPE ) then
global_variable := _WrapJuliaModule( rnam, global_variable );
\.\:\=( module!.storage, rnum, global_variable );
if _JULIA_ISA( var, _JULIA_FUNCTION_TYPE ) then
var := _WrapJuliaFunction( var );
elif _JULIA_ISA( var, _JULIA_MODULE_TYPE ) then
var := _WrapJuliaModule( rnam, var );
\.\:\=( module!.storage, rnum, var );
fi;

return global_variable;
return var;
end );

InstallMethod( \.\:\=,
Expand Down Expand Up @@ -93,7 +83,7 @@ function( obj )
return JuliaToGAP( IsList, Julia.GAP.get_symbols_in_module( JuliaPointer( obj ) ), true );
end);

InstallValue( Julia, _WrapJuliaModule( "Main", _JuliaGetGlobalVariable( "Main" ) ) );
InstallValue( Julia, _WrapJuliaModule( "Main", _JuliaGetGlobalVariableByModule( "Main", "Main" ) ) );

InstallGlobalFunction( "JuliaIncludeFile",
function( filename, module_name... )
Expand Down
72 changes: 6 additions & 66 deletions pkg/JuliaInterface/src/JuliaInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,63 +129,21 @@ Obj NewJuliaObj(jl_value_t * v)
}


jl_function_t * get_function_from_obj_or_string(Obj func)
{
jl_function_t * f = NULL;
BEGIN_GAP_SYNC();
if (IS_JULIA_OBJ(func)) {
f = (jl_function_t *)GET_JULIA_OBJ(func);
}
else if (IsStringConv(func)) {
// jl_get_function is a thin wrapper for jl_get_global and never
// throws an exception
f = jl_get_function(jl_main_module, CONST_CSTR_STRING(func));
if (f == 0) {
ErrorMayQuit("Function is not defined in julia", 0, 0);
}
}
else
ErrorMayQuit("argument is not a julia object or string", 0, 0);
END_GAP_SYNC();
return f;
}


void ResetUserHasQUIT(void)
{
STATE(UserHasQUIT) = 0;
}


/*
* Returns the function from the Object <func>
* or the function with name <func> from
* the Julia main module.
* Wrap Julia object <func> into a GAP function.
*/
static Obj Func_JuliaFunction(Obj self, Obj func)
static Obj Func_WrapJuliaFunction(Obj self, Obj func)
{
jl_function_t * f = get_function_from_obj_or_string(func);
return WrapJuliaFunc(f);
}
if (!IS_JULIA_OBJ(func))
ErrorMayQuit("argument is not a julia object", 0, 0);

/*
* Returns the function with name <funcName> from the Julia module with
* name <moduleName>.
*/
static Obj Func_JuliaFunctionByModule(Obj self, Obj funcName, Obj moduleName)
{
BEGIN_GAP_SYNC();
RequireStringRep("_JuliaFunctionByModule", funcName);
RequireStringRep("_JuliaFunctionByModule", moduleName);

jl_module_t * m = get_module(CONST_CSTR_STRING(moduleName));
// jl_get_function is a thin wrapper for jl_get_global and never throws
// an exception
jl_function_t * f = jl_get_function(m, CONST_CSTR_STRING(funcName));
if (f == 0)
ErrorMayQuit("Function %g.%g is not defined in julia",
(Int)moduleName, (Int)funcName);
END_GAP_SYNC();
jl_function_t * f = (jl_function_t *)GET_JULIA_OBJ(func);
return WrapJuliaFunc(f);
}

Expand Down Expand Up @@ -233,22 +191,6 @@ static int gap_jl_boundp(jl_module_t * m, jl_sym_t * var)
#endif
}

// Returns the julia object GAP object that holds a pointer to the value
// currently bound to the julia identifier <name>.
static Obj Func_JuliaGetGlobalVariable(Obj self, Obj name)
{
BEGIN_GAP_SYNC();
RequireStringRep("_JuliaGetGlobalVariable", name);

jl_sym_t * symbol = jl_symbol(CONST_CSTR_STRING(name));
END_GAP_SYNC();
if (!gap_jl_boundp(jl_main_module, symbol)) {
return Fail;
}
jl_value_t * value = jl_get_global(jl_main_module, symbol);
return gap_julia(value);
}

// Returns the julia object GAP object that holds a pointer to the value
// currently bound to the julia identifier <moduleName>.<name>.
static Obj Func_JuliaGetGlobalVariableByModule(Obj self, Obj name, Obj module)
Expand Down Expand Up @@ -309,11 +251,9 @@ static void MarkJuliaObject(Bag bag)

// Table of functions to export
static StructGVarFunc GVarFuncs[] = {
GVAR_FUNC(_JuliaFunction, 1, "string"),
GVAR_FUNC(_JuliaFunctionByModule, 2, "funcName, moduleName"),
GVAR_FUNC(_WrapJuliaFunction, 1, "juliafunc"),
GVAR_FUNC(IS_JULIA_FUNC, 1, "obj"),
GVAR_FUNC(JuliaEvalString, 1, "string"),
GVAR_FUNC(_JuliaGetGlobalVariable, 1, "name"),
GVAR_FUNC(_JuliaGetGlobalVariableByModule, 2, "name, module"),
GVAR_FUNC(JuliaSymbol, 1, "name"),
GVAR_FUNC(_JuliaGetGapModule, 0, ""),
Expand Down
Loading
Loading