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

Add C++ support to kernel; use it to reduce code duplication in permutat.c, objfgelm.c and others #2667

Merged
merged 37 commits into from
Sep 27, 2018

Conversation

fingolfin
Copy link
Member

@fingolfin fingolfin commented Jul 30, 2018

This is an incomplete proof of concept (POC) to show how using C++ code could be used to simplify some kernel code. For now, my main goal is to reduce code duplication, which is why I started with permutat.c. This modest PR already removes about a thousand lines of code.

It was mentioned that not everybody who works (or wants to work) on the kernel is fluent in C++. Thus we should be careful about which features we use, and avoid overly complicated or intransparent / "magical" code, and add sufficient comments. Consider this PR as a first opportunity to get an idea of what the result of such a conversion to C++ code might look like, and please point out anything you don't understand, dislike (or like), etc.

Some things which still need to be done (assuming this PR gets a green light):

  • Ensure this PR passes the GAP test suite.
  • Require C++ compiler in configure, and abort (with a helpful message) if none is found.
  • Update the README and other documentation to mention that a C++ compilers is required
  • Optional: teach gac to compile .cc files
  • Decide which C++ standard to allow (and enable, via compiler flags): for now, I restricted myself to C++98; but we could use C++11, which was added in GCC 4.8.1, which is e.g. available in Ubunutu 14.04 LTS (and thus also on Travis)
  • document which subset of C++ we allow for now? E.g. we likely want to avoid the C++ runtime (so no exceptions, no standard C++ library, no RTTI, no global constructors, ...?). I guess in the end, we can just forbid some things, explicitly allow some others, and for the rest, rely on PR reviews to determine what we want and what not
  • ...

Other places that could benefit from a similar use of C++ templates:

  • more functions in permutat.cc could actually be treated, the remaining ones each simply require a bit more work than the ones I already converted, so I didn't want to spend that effort for a proof of concept
  • pperm.c: very similar to permutat.c
  • trans.c: very similar to permutat.c
  • objccoll-impl.h and objscoll-impl.h implement "poor man's template's" by abusing the C preprocessor, and are included multiple times by objscoll.c for that
  • similarly, sortbase.h is included multiple times by listfunc.c
  • objfgelm.c: contains 8, 16 and 32 bit variants of many functions, e.g.: Func8Bits_ExponentSums3, Func16Bits_ExponentSums3, Func32Bits_ExponentSums3
  • objpcgel.c: contains 8, 16 and 32 bit variants of many functions

@fingolfin fingolfin added do not merge PRs which are not yet ready to be merged (e.g. submitted for discussion, or test results) topic: build system topic: kernel labels Jul 30, 2018
@fingolfin fingolfin added request for comments kind: discussion discussions, questions, requests for comments, and so on labels Jul 30, 2018
return (const T *)(CONST_ADDR_OBJ(perm) + 1);
}

template<typename TL, typename TR> struct ResultType { typedef UInt4 type; };
Copy link
Contributor

Choose a reason for hiding this comment

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

Very low-level comment, might want to give this another name before merging because I imagine we'll have other similar types. However, the same thing can be used for perms, trans and pperms.. not sure of a good name.

{
return sizeof(Obj) + deg * sizeof(T);
}

This comment was marked as resolved.

@fingolfin
Copy link
Member Author

Actually, another major caveat I forgot about is that in HPC-GAP mode, we still are using ward, which knows nothing about C++ and templates. So we either need to teach it about templates, or get rid of it. Of course considering that ward still is broken, I'd kind of prefer the latter (perhaps @rbehrends will pick up his work on unward, or perhaps some of us can sit down and take care of it without unward).

@ssiccha
Copy link
Contributor

ssiccha commented Jul 31, 2018

Looks nice. I like the idea. 👍

@sebasguts
Copy link
Member

This PR looks really nice, and I really like the way it it cleans up the code.

Two opinions here:

  • I think we should go with C++11. It is available on every recent Linux Distro, and has a lot of features one would really like to use, and for which there is no reason to forbid them:
    • auto and decltype: Specially useful when working with templates
    • lambdas
  • Allowing stuff: I think we should at first only allow a certain subset. Forbidding some stuff seems to have the caveat that C++ is so large that you easily forget something. But do we even want to try to not use the C++ runtime? Many things might be useful, specially exceptions and STL. Plus, several packages already load it anyway.

@stevelinton
Copy link
Contributor

I like the simplification of permutat.c a lot, and I'd be happy to see use of C++ templates of this level of sophistication. Essentially it's just a better C pre-processor. I'd want to move very slowly with things like the C++ runtime or use of the STL for two reasons:

  1. because of possible interactions with gasman/libGAP/the existing GAP error and exception handling and so on.
  2. because I'd like to still be able to read, understand and modify the code. My knowledge of C++ is rudimentary at best and I'm pretty sure I'm not the only developer in that position.

@frankluebeck
Copy link
Member

I completely agree with the previous comment by @stevelinton.

@frankluebeck
Copy link
Member

With respect to the content: Wouldn't it be easy and sensible to introduce a type T_PERM1 with the simplified code in permutat.cc? I guess "most" permutations in "most" GAP sessions would fit in a T_PERM1?

@fingolfin
Copy link
Member Author

@frankluebeck Adding a T_PERM1 indeed should be a relatively easy thing to do; this is a nice bonus effect of the proposed change. However, first the rest of the code in permutat.cc should be turned into templates

And I acknowledge the reservations about adding too much C++. While I personally am completely comfortable with using C++, I agree we should be careful about using it too much. Thus any PR that would add more C++ usage should be carefully reviewed for that (and I personally think we should strive to make sure that people with concerns about C++ usage, like Frank and Steve, get a chance to comment on whether they are comfortable with it).

That said, there are a few things beyond basic templates which I think we could benefit from; but let's discuss those if and once we get there (and then ideally again based on a concrete PR to showcase what is intended).

For now, the HPC-GAP problem with ward remains...

@fingolfin fingolfin force-pushed the mh/cxx branch 3 times, most recently from 0c15969 to 008e1b7 Compare August 6, 2018 07:33
@fingolfin fingolfin changed the title POC/WIP: Add C++ support to kernel, use to simplify permutat.cc (DO NOT MERGE) Add C++ support to kernel; use it to reduce code duplication in permutat.c, objfgelm.c and others Sep 27, 2018
@ChrisJefferson
Copy link
Contributor

I'm going to go for the merge once tests pass, then investigate the cygwin issue if it isn't cleared up.

@fingolfin
Copy link
Member Author

@ChrisJefferson tests passed now

@markuspf markuspf merged commit 2646281 into gap-system:master Sep 27, 2018
@fingolfin fingolfin deleted the mh/cxx branch September 28, 2018 07:20
@olexandr-konovalov
Copy link
Member

The windows issue described above is not happening in the master branch. I suspect there is a bug somewhere in paths in scripts from Jenkins jobs to build and tests PRs on Windows.

However, there are new Windows issues which seem to be cause by this PR. I've reported them in #2890.

Finally, when this PR was tested on Windows, the directory for the binaries had name bin/i686-pc-cygwin-default32-kv5, but in the master branch the name is bin/i686-pc-cygwin-default32-kv5. I had to adjust Windows Jenkins script to add -kv5.

@fingolfin fingolfin added release notes: added PRs introducing changes that have since been mentioned in the release notes and removed release notes: to be added PRs introducing changes that should be (but have not yet been) mentioned in the release notes labels Apr 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: discussion discussions, questions, requests for comments, and so on release notes: added PRs introducing changes that have since been mentioned in the release notes topic: build system topic: kernel
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants