-
Notifications
You must be signed in to change notification settings - Fork 161
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
Add tracing and counting of built-in operations #3713
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a helpful function, I've missed it in the past, so I would be happy for it to go into GAP. I have a few suggestions, see above. Also, it would be nice to add tests before merging this.
1669403
to
b7cd46d
Compare
Thanks for the corrections. I've just put an explicit list of the "internal methods" which are traced, along with the name GAP gives them (which is the name of the internal variable, but might not be obvious so is worth explictly stating I think) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for implementing the changes, I am much happier with this now.
I've left 3 more comments. Also, I would leave it at changes requested
until there are tests so this doesn't get merged accidentally?
f28c182
to
c174c7a
Compare
lib/oper.g
Outdated
## gap> 3^(1,2,3);; | ||
## gap> GetTracedInternalMethodsCounts(); | ||
## rec( Pow := rec( integer := rec( ("permutation (small)") := 1 ) ), | ||
## Sum := rec( integer := rec( integer := 4 ), macfloat := rec( macfloat := 1 ) ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the compiled documentation, the last )
is outside of the rectangular box in which Examples are printed. Thus, it looks like a overfull hbox. Maybe you could insert another line break?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is tested by Travis etc, then Chris doesn't have any choice about how the output should look; if he adds arbitrary line breaks, then the tests will fail when the manual examples are tested. However I'm not sure where this is ever tested by Travis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh ok, I see. I guess I won't take the risk of a manual formatting now because it might be tested in the future and thing could break?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THis formatting was actually done by me, so I'll shorten/neaten it
Thanks @ChrisJefferson . Overall, I am happy with this now. If you could address the small points above I am happy to approve this and to get in merged. |
c174c7a
to
4ef72b4
Compare
@ChrisJefferson Tests are failing now. Maybe you could have a look at that? Also, while you're at it, could you change the documentation and change the |
2f20af0
to
560d652
Compare
560d652
to
dc30014
Compare
dc30014
to
e1d8612
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the changes @ChrisJefferson
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks sensible to me 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see this PR before, and just glancing at it, I wonder about several things, and thus would greatly prefer if this was not merged for now, until I have a chance to properly look at it (i.e., not while sitting in a train with a crappy internet connection).
@@ -875,6 +875,12 @@ static Obj FuncMakeImmutable(Obj self, Obj obj) | |||
return obj; | |||
} | |||
|
|||
static Obj FuncGET_TNAM_FROM_TNUM(Obj self, Obj obj) | |||
{ | |||
UInt tnum = GetBoundedInt("GET_TNAM_FROM_TNUM", obj, 0, 255); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
255 should have been NUM_TYPES - 1
## <Mark>LQuo</Mark><Item>The left-quotient operator</Item> | ||
## <Mark>Pow</Mark><Item>The operator <Ref Oper="\^"/></Item> | ||
## <Mark>Comm</Mark><Item>The operator <Ref Oper="Comm"/></Item> | ||
## <Mark>Mod</Mark><Item>The operator <Ref Oper="\mod"/></Item> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the above discussion rather confusing. It mixes up methods and operations: This text sounds as if Zero, ZeroMut, etc. are the "internal methods". But really, these are operations which have a special implementation such that before all regular methods, a special internal method is considered; and only if that is not applicable or fails or whatever, are other (regular) methods tried.
## As these methods can be called hundreds of thousands of times in simple GAP | ||
## code, there isn't a statement printed each time one is called. Instead, the | ||
## method <Ref Func="GetTraceInternalMethodsCounts"/> returns how many times | ||
## each operation has been applied to each type of variable (the type of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variables don't have a type in GAP, so "variable" should be changed to "object" here and in the next line (I can't make change suggestions on closed PRs, I am afraid).
## <Mark>Inv, InvMut</Mark><Item>Mutable and Immutable <Ref Attr="Inverse"/></Item> | ||
## <Mark>Sum</Mark><Item>The operator <Ref Oper="\+"/></Item> | ||
## <Mark>Diff</Mark><Item>The operator <C>-</C> operator</Item> | ||
## <Mark>Prod</Mark><Item>The operator <Ref Oper="\*"/></Item> | ||
## <Mark>Quo</Mark><Item>The operator <Ref Oper="\/"/></Item> | ||
## <Mark>LQuo</Mark><Item>The left-quotient operator</Item> | ||
## <Mark>Pow</Mark><Item>The operator <Ref Oper="\^"/></Item> | ||
## <Mark>Comm</Mark><Item>The operator <Ref Oper="Comm"/></Item> | ||
## <Mark>Mod</Mark><Item>The operator <Ref Oper="\mod"/></Item> | ||
## </List> | ||
## <P/> | ||
## <Ref Func="UntraceInternalMethods"/> turns tracing off. | ||
## As these methods can be called hundreds of thousands of times in simple GAP | ||
## code, there isn't a statement printed each time one is called. Instead, the | ||
## method <Ref Func="GetTraceInternalMethodsCounts"/> returns how many times | ||
## each operation has been applied to each type of variable (the type of a | ||
## variable can be found with the <C>TNAM_OBJ</C> method). | ||
## The return value for two argument operators is a record of records <C>r</C>, where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The return value of GetTraceInternalMethodsCounts for ..."
## <Func Name="TraceInternalMethods" Arg=''/> | ||
## <Func Name="UntraceInternalMethods" Arg=''/> | ||
## <Func Name="GetTraceInternalMethodsCounts" Arg=''/> | ||
## <Func Name="ClearTraceInternalMethodsCounts" Arg=''/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation says nothing about ClearTraceInternalMethodsCounts
tracking_active = 0; | ||
return 0; | ||
} | ||
static Obj FuncGET_TRACED_INTERNAL_METHODS_COUNTS(Obj self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add empty line above
|
||
// Store the list of operators which can have tracing enabled and disabled | ||
static voidfuncs controllers[64]; | ||
static int tracking_active; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we use CamelCase
and not snake_case
(nor lowerCamelCase
) for global variables (almost) everywhere else...
void InstallOpWrapper(voidfunc activate, voidfunc deactivate) | ||
{ | ||
int pos = 0; | ||
while (pos < 64 && controllers[pos].activate != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of hardcoding 64 here and elsewhere, it would be better to use ARRAYSIZE(controllers)
. Or use a global enum for the size. Or don't use a size at all, and instead use a PLIST to store this data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started switching to PLIST, but it doesn't really work as we have to store C function pointers
void InstallOpWrapper(voidfunc, voidfunc); | ||
|
||
|
||
// These are macros which make it simple to wrap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment looks as if it is incomplete? In any case, it is useless in the current form. Would be nice to have at least some comments explaining what those macros are and how to use them.
|
||
void ReportWrappedOperation1(const char *, Obj op); | ||
void ReportWrappedOperation2(const char *, Obj op1, Obj op2); | ||
void InstallOpWrapper(voidfunc, voidfunc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments explaining these functions and how/when to use them would be nice
This is some code I've had a branch of a long time, cleaned up.
Sometimes, for papers and general research it is interesting to know things like how many times + is applied to integers, or * or ^ is applied to permutations.
This can't be done by any of GAP's normal tracing functionality at present. Also, printing a message every time one of these functions is called would be far too much.
This adds
TraceInternalMethods
, which produces a record which contains how many times each operation is applied to each tnum (or each pair of tnums for 2-argument methods).This doesn't try to catch when kernel functions add integers, only when these operations are performed at the GAP level.
This still needs tests, but before I put more work into polishing I wanted to see if other people found it useful.