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

new macro @gapattribute #647

Merged
merged 2 commits into from
May 18, 2021

Conversation

ThomasBreuer
Copy link
Member

@ThomasBreuer ThomasBreuer commented May 5, 2021

This is intended to address oscar-system/Oscar.jl/issues/128. but it does not work as expected
Apparently something is wrong with the code: When I try to call the macro inside an Oscar source file then Julia crashes with a segmentation fault.

However, the following works.
Here is an example how to use the new macro.

  1. Create a file testmodule.jl with a Julia module that calls the macro in the way we want to use it.
module enclose
  
import GAP
import Oscar
GAP.@gapattribute isfinite(G::Oscar.GAPGroup) = GAP.Globals.IsFinite(G.X)
GAP.@gapattribute issolvable(G::Oscar.GAPGroup) = GAP.Globals.IsSolvableGroup(G.X)
end # module
  1. Use the functions created by the macro.
julia> using Oscar
[...]

julia> include( "testmodule.jl" )
Main.enclose

julia> g = symmetric_group(5);

julia> Main.enclose.hasissolvable(g)
false

julia> Main.enclose.issolvable(g)
false

julia> Main.enclose.hasissolvable(g)
true

julia> g = symmetric_group(5);

julia> Main.enclose.hasissolvable(g)
false

julia> Main.enclose.setissolvable(g, false)

julia> Main.enclose.hasissolvable(g)
true

@ThomasBreuer ThomasBreuer added the DO NOT MERGE DO NOT MERGE label May 5, 2021
@codecov
Copy link

codecov bot commented May 5, 2021

Codecov Report

Merging #647 (098b068) into master (17fffa5) will increase coverage by 0.12%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #647      +/-   ##
==========================================
+ Coverage   77.15%   77.28%   +0.12%     
==========================================
  Files          47       47              
  Lines        4102     4129      +27     
==========================================
+ Hits         3165     3191      +26     
- Misses        937      938       +1     
Impacted Files Coverage Δ
src/macros.jl 97.95% <100.00%> (-2.05%) ⬇️

Now the macro works, without segmentation faults.
@ThomasBreuer
Copy link
Member Author

ThomasBreuer commented May 5, 2021

With the second attempt (after a discussion with @fingolfin), the segmentation faults are avoided.
On the one hand, the new code is better because the aspects addressed by the two macros @gapwrap and @gapattribute are now separated; for the given situation, this is fine.
On the other hand, I find it strange that the "easy metaprogramming approach" from my first attempt runs into segmentation fault problems.
(As far as I understand, the segmentation faults are related to the problem discussed in JuliaLang/julia/issues/36770, but this issue is mainly about performance, not about crashes.)

@ThomasBreuer ThomasBreuer changed the title new macro @gapattribute (first attempt -- WIP) new macro @gapattribute May 5, 2021
@fingolfin
Copy link
Member

Note that with JuliaLang/julia#40852 at least there will be a somewhat helpful (?) error message instead of a crash when using GAP objects on the top level of package modules (where the precompilation code ends up trying to serialize them).

Copy link
Member

@fingolfin fingolfin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@ThomasBreuer ThomasBreuer removed the DO NOT MERGE DO NOT MERGE label May 18, 2021
@ThomasBreuer ThomasBreuer merged commit 092d3b8 into oscar-system:master May 18, 2021
@ThomasBreuer ThomasBreuer deleted the TB_macro_attributes branch May 18, 2021 15:33
fingolfin pushed a commit to oscar-system/Oscar.jl that referenced this pull request Jul 30, 2021
Use the macros `@gapattribute` and `@gapwrap` in order to get access
to GAP's "tester" and "setter" functions for its attributes.
This had been suggested in issue #128.

The code requires the changes from the pull request oscar-system/GAP.jl/pull/647.
The branch has the same name as that of the current pull request.

(There are more places where the macros can be applied.
First we should agree on the setup, see below.)

- The names of the tester/setter functions on the Julia side should
  perhaps be changed:
  Would `has_derived_subgroup` look better than `hasderived_subgroup`?
  (This is something to be changed in GAP.jl.)

- Some of the functions in `Oscar/src/Groups` (`conjugacy_classes`,
  `conjugacy_classes_subgroups`, `conjugacy_classes_maximal_subgroups`)
  cannot be handled by the current `@gapattribute`,
  because they involve several calls to some function in `GAP.Globals`.
  The point is that the names of the tester and setter are "guessed" from
  the body of the given (getter) function.
  If there is just one call to a function in `GAP.Globals` then this is safe,
  otherwise we have to find some heuristic that is easy to document.

- In a few cases (`exponent`), I have added individual `import` statements
  because the current `@gapattribute` does not strip module names from the
  beginning of the function name; we could change the macro in order to
  avoid these `import` statements.

- In order to keep the docstrings of the functions handled by `@gapattribute`,
  I did not see a better way than to move the code above the docstring.

- Another point for the documentation is how to document the testers and
  setters.  We could show three-line descriptions of the kind
```
    isperfect(G::Group)
    hasisperfect(G::Group)
    setisperfect(G::Group, val)
```
  in all relevant places, instead of just the first of these lines.
  Or would this become too long?

  (I have extended the `export` lists by the testers and setters.
  Is this o.k.?)

- I have changed the behaviour of the functions only in one place.
  Up to now, `trivial_subgroup` constructed just a group on the Julia side,
  without calling GAP's `GAP.Globals.TrivialSubgroup`, but now the attribute
  on the GAP side is called, due to `@gapattribute`.
  The side-effect is that now the return value of `trivial_subgroup` has
  an empty list of generators,
  whereas this list contained the identity element before.
  This change seems to be no problem for the tests,
  but perhaps it has to be documented that the result of `gens` may be empty.

  The conceptual question is whether we really want to change `trivial_subgroup`
  such that the corresponding GAP function gets called.

  We can take the viewpoint that the Julia side should better avoid work on
  the GAP side where possible (one can create a trivial subgroup in Oscar
  without "help from GAP"),
  or we can argue that the GAP side should better be kept informed about
  knowledge that has been computed on the Julia side.

  Note that in the cases of boolean values,
  the stored GAP attributes really serve as caches;
  but already for a group order stored in GAP,
  a conversion may be necessary before the value can be used on the Julia side.

  One "border case" is `ispgroup`:
  Its return value is a tuple not just the boolean value that is stored on the
  GAP side.
  Any access from Oscar's `ispgroup` creates a new Julia object.

- The following two inconsistencies should be dealt with in other pull requests:
  `center` and `ischaracteristic` are known in (and imported from) Hecke,
  but Oscar.Groups defines `centre` and `ischaracteristic_subgroup`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants