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

Use EventLogFormat.h from upstream (GHC) #27

Open
mboes opened this issue May 27, 2017 · 17 comments
Open

Use EventLogFormat.h from upstream (GHC) #27

mboes opened this issue May 27, 2017 · 17 comments

Comments

@mboes
Copy link

mboes commented May 27, 2017

The project currently has its own copy of EventLogFormat.h that ships with GHC. This strikes me as an unfortunate situation: if the upstream version of that file as found in GHC is to be considered the authoritative definition of what events are supported, then we shouldn't be forking our own copy.

Now, the trouble with switching to the upstream version is that it is a lot smaller. Many long ago deprecated events have been removed entirely. The Mercury events are not defined. Neither are the Eden events. But at least this way we know for sure that GHC and ghc-events agree about event definitions because they share the exact same interface file.

Further, this looks like a good opportunity to remove support for events that are no longer supported. Should we really still be aiming for compatibility all the way to 6.12.* along with the funny quirks we encounter in those compilers? Does Mercury really still use ghc-events? Is Eden still an active project?

Another point is that if we use whatever EventLogFormat.h we find in the currently installed GHC, then the resulting ghc-events binary is tuned for that installed GHC version and only that GHC version. But that's a feature. Some of the complexity in the existing code base stems from having a single binary support eventlogs produced by any version of GHC, past present and future. Which makes sense in a pre project environments world, which both cabal-install and Stack now support. But with cabal-install and Stack projects, it makes sense to have a project local ghc-events that is guaranteed to work well with the eventlogs that are created as part of that project and the GHC version used in that project.

@maoe
Copy link
Member

maoe commented May 29, 2017

I agree that it would be great if we could just use the upstream version. It was a bit painful to update the header file in #29. I'm not sure what Eden or Mercury people think though.

As to support older versions of GHCs, I feel we can drop support for pre-7 GHCs and just support the latest three released versions of GHC as with the established convention for Haskell packages.

I'm afraid I disagree with the idea of ghc-events being tied to a specific GHC. The eventlog framework in GHC is designed to be extensible so that old tools should be able to parse new versions of the format and new tools are able to understand old log files. Also it would be inconvenient if I had to rebuild ghc-events (or threadscope) every time I switched GHC.

@simonmar
Copy link
Member

ghc-events was specifically designed to be forwards and backwards compatible as far as possible. Otherwise, you have to build a specific ThreadScope binary that works with the version of GHC you're using, you need multiple ThreadScope binaries lying around, it becomes hard (or impossible) to work with old eventlog files, and so on. I can't tell you how many times I've found that I'm really glad we did it this way - it's really hard to build ThreadScope, but I can "apt-get install" it on any Linux system and it works with whatever GHC version I'm using. The level of version mismatch might lead to some missing features or degraded capabilities, but it works.

Possibly we can drop support for 6.12, but the main argument for doing so would be that it's hard to test it. So long as we can test old versions I think we should continue to support them. (this argues against keeping the Eden support, but I think the responsibility for maintaining that lies with @jberthold, it's not a big deal for us to keep it.)

@simonmar
Copy link
Member

Oh, and BTW testing support for old versions really just means keeping around old eventlog files, we don't necessarily need access to a working GHC.

@jberthold
Copy link
Contributor

Thanks @simonmar for making the point about compatibility with older formats. Dropping it means dropping a feature. I don't think it is hard to keep a single header file full of numbers in sync with GHC versions (sometimes there is a lot more to do to keep GHC-internal code in sync...). The design was chosen for a reason, it should not be thrown overboard for minor reasons.

For the 6.12.* versions, I do think it would be acceptable to drop support (and bump the major version). This might simplify the code going forward. However, that simplification might not be a big win either so I don't see a pressing need to slash down working code.

I cannot speak for Mercury but I believe the event definitions are useful. Would be great to have some documentation about them.
For Eden, I do not have enough time to care about tracing clients and rather focus on the parallel GHC fork itself, but I know the current version would work, and was very happy to have it merged in.
Did not have contact with people from Marburg recently who would be in charge of the clients. @dieterle might know something.

@mboes
Copy link
Author

mboes commented May 31, 2017

So how do we reconcile this:

@maoe writes

I agree that it would be great if we could just use the upstream version. It was a bit painful to update the header file in #29. I'm not sure what Eden or Mercury people think though.

and this

@simonmar writes

it's really hard to build ThreadScope, but I can "apt-get install" it on any Linux system and it works with whatever GHC version I'm using. The level of version mismatch might lead to some missing features or degraded capabilities, but it works.

Which is the authoritative document for defining events? Is it the EventLogFormat.h included here, or is it the one in GHC? Whichever it is, shouldn't all eventlog parsing tools (of which ghc-events is potentially just one) use the same definition from somewhere for maximum functionality? If GHC stops removing definitions for deprecated events, and if GHC accepts defining the Mercury and the Eden events (as they were defined historically), i.e. if the information in GHC's EventLogFormat.h always just monotonically increases, then ghc-event could stop duplicating this header file without loss of functionality to anyone.

Further, the header file has this to say:

  • Old event type ids are never re-used; just take a new identifier.

It sounds to me like the only reliable way to do so is to never remove old events.

As an aside, for me Stack has taken over managing my GHC version, my ThreadScope version along with everything else, so I never apt-get install any Haskell tool. And therefore having multiple ThreadScope's, multiple ghc-events etc isn't a problem. However, certainly not everyone works that way. So given that, does restoring old events in GHC sound like the right way forward to remove the "pain" that @maoe speaks of? Of course, this does mean some #ifdef'ing in the binary (de)serializer so that ghc-events can compile with older GHC's. But if we're limiting support to 3 major GHC versions (as @maoe suggests), then there wouldn't be much of that. And we don't need to #ifdef the events themselves.

If GHC doesn't want to define Eden and Mercury events for some reason, we could always define those in local header files, while still including the GHC events from GHC itself.

@simonmar
Copy link
Member

simonmar commented Jun 1, 2017

So how do we reconcile this:

Unfortunately there's a cost to backwards compatibility, and in this case it's the extra work in maintaining the library that works with multiple versions of the eventlog format.

Which is the authoritative document for defining events? Is it the EventLogFormat.h included here, or is it the one in GHC?

The one in GHC is authoritative for that version of GHC, whereas the one in ghc-events covers all versions and tools that generate event logs. It's the union of all the GHC versions that we support.

Whichever it is, shouldn't all eventlog parsing tools (of which ghc-events is potentially just one) use the same definition from somewhere for maximum functionality?

So this is why we have the ghc-events library, so that all clients can use a single API. I didn't imagine that we would need to have other tools that implement their own parsers for eventlog files - do we have any of those? Why wouldn't they use ghc-events?

If GHC stops removing definitions for deprecated events, and if GHC accepts defining the Mercury and the Eden events (as they were defined historically), i.e. if the information in GHC's EventLogFormat.h always just monotonically increases, then ghc-event could stop duplicating this header file without loss of functionality to anyone.

Yes, that would be another way to do it. However, it's not as good:

  • The event log format that ghc-events parses would be dependent on the GHC version it is compiled with, not the version of ghc-events itself. So not all builds of ghc-events-0.6.0 are created equal.
  • we don't have any tests in GHC to test whether these definitions make sense, whereas we do in ghc-events.

So I argue that the EventLogFormat.h in ghc-events should define the events that the library understands, and we should merge new events into it from upstream GHC when there's a new GHC release.

@kvelicka
Copy link
Contributor

kvelicka commented Jun 1, 2017

FWIW I'm on @simonmar's side on this one.

@maoe
Copy link
Member

maoe commented Jun 2, 2017

I see two extreme camps here

  • ghc-events should maintain a header file that contains entire history of GHC's one and Eden's and Mercury's.
  • ghc-events should just take the header file from the GHC that builds the library.

And both have their shortcomings, namely:

  • It's a bit tiresome and error-prone to maintain such a header file.
  • It's (very; IMO) inconvenient if we drop the forward/backward compatibility.

I think there is a sweet spot between the two.

  • GHC never drops deprecated events. It keeps them forever but just stops using them.
  • When GHC changes the header file, we copy it to ghc-events.
  • For Eden/Mercury, we move all these events into separate header files and include them where needed.

This way we can just take the authoritative definitions from GHC while keeping the very nice backward/forward compatibility. Also GHC doesn't need to know about Eden/Mercury.

Obviously we need to revive the deprecated events in GHC and convince GHC devs to follow this convention, though.

@mboes @simonmar What do you think?

@simonmar
Copy link
Member

simonmar commented Jun 2, 2017

If that would be easier from your perspective it's OK to have the source of truth be the GHC sources. Just one thing: we have to keep the Eden and Mercury events together with the GHC events, to prevent us accidentally reusing event IDs that are taken by Eden and Mercury events. We'd have to carefully document the reason that this code is in GHC, and how to test it.

@maoe
Copy link
Member

maoe commented Jun 2, 2017

we have to keep the Eden and Mercury events together with the GHC events, to prevent us accidentally reusing event IDs that are taken by Eden and Mercury events.

@simonmar Why is this necessary? Currently GHC doesn't maintain Eden/Mercury events and just has comments like this:

/* Range 60 - 80 is used by eden for parallel tracing
 * see http://www.mathematik.uni-marburg.de/~eden/
 */

/* Range 100 - 139 is reserved for Mercury. */

My idea doesn't change these comments at all.

What I'm proposing here is that we

  • move the Eden/Mercury/Perf events from ghc-event's header file to a separate file
  • remove the #if 0 condition in the GHC's header. Document the new workflow in this file.
  • then copy the GHC's header file to ghc-events.

I don't see the reason(s) why we have to keep Eden/Mercury events in GHC's header file. Could you elaborate?

@jberthold
Copy link
Contributor

If I understand your proposal correctly, the "new workflow" is to never remove definitions from the GHC header file, by way of

remove the #if 0 condition

That makes perfect sense to me. Given the event numbers are reserved once and then fixed, no holes should result (and it is just a few numbers after all).
For the part about keeping the definitions, I think @simonmar already explained the reason why at least the comments have to be kept:

to prevent us accidentally reusing event IDs that are taken by Eden and Mercury events.

Again, if I understand your proposal correctly, this question only comes up because you wish to copy the file from GHC to this library, because this library will always have to have the full definition.
The current EventLogFormat.h in ghc-events is the one place to go to when picking new numbers.
Its copy in the GHC sources is a subset with comments replacing the event ID definitions that GHC does not require, but it must remain a subset of the one in ghc-events to keep everything working as originally designed.

Therefore I would argue that it is not helpful to split the file in this project. Unrecoverable mistakes might result if somebody is not aware of the full picture and uses a reserved number in a GHC version that reaches a release.

It is great that this common resource has been maintained for meanwhile 8 years, and things are in working state. Great that you guys take responsibility on this library, so please do not take it wrong if I argue for some points differently from what you propose.
To make this discussion progress again, could you elaborate a bit more on what motivates the proposal, from a technical perspective? (because if the motivation is "housekeeping", I think the house is in fair shape, and I did not see the technical need for it yet).

@maoe
Copy link
Member

maoe commented Jun 3, 2017

For the part about keeping the definitions, I think @simonmar already explained the reason why at least the comments have to be kept:

@jberthold Sure, I didn't propose to delete the comments about the Eden/Mercury/Perf events. We definitely should keep them to avoid event conflicts.

Unrecoverable mistakes might result if somebody is not aware of the full picture and uses a reserved number in a GHC version that reaches a release.

What I didn't get is this point. We don't need to list every Eden/Mercury/whatever events in the GHC's header file to avoid conflicts. We just need to comment the event ID regions that are reserved for external projects and this is, I believe, how GHC devs have been doing so far. When a new region needs to be reserved for a project, a developer from the project needs to talk with GHC devs and reserve a region by adding a comment line in the GHC's header, not the one in ghc-events. The full picture is always kept in GHC.

So in short, I don't see how factoring out the external events into a separate file leads to event conflicts.

To make this discussion progress again, could you elaborate a bit more on what motivates the proposal, from a technical perspective? (because if the motivation is "housekeeping", I think the house is in fair shape, and I did not see the technical need for it yet).

I'm not sure what @mboes thinks but here is my reasoning:

The motivation is really about "housekeeping". Yes, I agree that the house is in fair shape but that's at the cost of maintenance.

While I integrated the new heap profiling events (#29) from GHC 8.2, I thought the workflow was more cumbersome and error-prone than it should be. I had to manually resolve conflicts. The source of conflicts is not only the external events but also the events that are deprecated.

Probably it's okay if the header file in question changes very infrequently. This was the case in the past but there was a change in 8.2 and I expect more in the near future as I'm planning to extend the heap profiling support and I guess @bgamari may or may not extend the framework to support the DWARF based statistical profiling.

Does this answer the question?

@jberthold
Copy link
Contributor

jberthold commented Jun 3, 2017 via email

@mboes
Copy link
Author

mboes commented Jun 3, 2017

@maoe yup, sounds good to me.

@simonmar
Copy link
Member

simonmar commented Jun 3, 2017

I don't see the reason(s) why we have to keep Eden/Mercury events in GHC's header file. Could you elaborate?

Ok, if we block out the reserved parts of the range with comments in the GHC source, then that's fine. I was just concerned that we might re-use an Eden or a Mercury event ID in GHC by mistake.

@maoe
Copy link
Member

maoe commented Jun 3, 2017

There is no guarantee that it will remain complete in GHC so nobody should be encouraged to rely on the GHC version of the file.

(which is the essence of my concern; "just" a risk, not a mistake)

@jberthold Sorry I still don't get this part. What is the risk that increases in the new workflow?

I think people should use the latest GHC's header (assuming GHC follows the new workflow) and nobody should use ghc-events as the primary source of event definitions as it can be (and actually is now) out-of-date and may not contain new events.

We can put a big caution message in the README encouraging people who consider adding new events consult GHC devs.

my GHC fork has a version of the file which is more similar to the ghc-events version.

I guess this is because you use the ghc-events version as the source of definitions, right? I think you can #include the separate header file as you said.

Sure: In the end, I may as well just #include a separate header file for Eden events in my GHC version as well (the same file as in ghc-events; not much more work.

Yup. I think that's a great idea.

@BinderDavid
Copy link

GHC now uses a python script to generate the header files: https://gitlab.haskell.org/ghc/ghc/-/blob/master/rts/gen_event_types.py
Maybe this python script could be generalized to also replace ghc-event's use of its own EventLogFormat.h file.

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

No branches or pull requests

6 participants