Bug #1247

Problem with reduction when inheriting pure virtual functions

Added by Robert Steinke almost 3 years ago. Updated almost 3 years ago.

Target version:
Start date:
Due date:
% Done:



I have a group that inherits from a base class that has pure virtual functions.
This group uses a reduction as a barrier. When I try to do the reduction I get a seg fault.
If there is only one PE the code works. It only seg faults on two or more PEs.
If I remove the pure virtual functions from the base class the code works.

I've pared it down to a minimal example in the attached files and a.cpp.

As is, it seg faults. If you comment out line 14 of a.cpp "virtual int aFunction() = 0;" then it runs just fine.

a.cpp View (327 Bytes) Robert Steinke, 10/05/2016 12:37 PM (453 Bytes) Robert Steinke, 10/05/2016 12:37 PM


#1 Updated by Eric Bohm almost 3 years ago

  • Assignee set to Nitin Bhat

#2 Updated by Robert Steinke almost 3 years ago

I discovered that if I switch the order in which the base classes are declared it works. I guess that will change the order in which their constructors are called.

class B : public CBase_B , public C {

#3 Updated by Phil Miller almost 3 years ago

Is C truly a stand-alone class, with no connection to any kind of chare entity? Inheritance form chare types works fine whens specified in the .ci file, so that the generated declarations have the CBase class inheriting appropriately, and able to pass through constructor arguments. I'm less certain about that structure when used to inherit from a non-chare.

#4 Updated by Robert Steinke almost 3 years ago

Yes, C is a standalone non-chare class that inherits from nothing. The reason we have things set up this way is that we want to have a version of our code that uses charm, and a separate version that uses only MPI, so C has the common behavior, and B is the charm version.

But aside from how I'm using it for my current problem, your answer makes me have some more general comments and questions. I think you do want to be able to support the case where the other base class isn't a chare. It seems like normal C++ code that lots of charm uses might try to do and get really frustrated if it's not allowed. If you need some extra declarations in the .ci file that's okay, but then it needs to be well documented because it wasn't obvious at all what was wrong.

If C were a chare, what would be the correct syntax for that? Is that syntax documented anywhere? Something like this?

in .ci file:

group C { ...

group B : public group C { ...

in .cpp file

class C : public CBase_C { ...

class B : public CBase_B { ...

#5 Updated by Phil Miller almost 3 years ago

If C were a chare, the syntax would be

// .ci file:
group B : C { // . . . 

// .cpp file:
class C : public CBase_C { // . . . 

class B : public CBase_B { // . . . 

So, the 'interesting' inheritance gets declared in the .ci file, and the CBase class provides a pass-through. If C's constructor takes arguments, B::B(...) can pass them to CBase_B(...), which will forward them to C::C(...).

For the particular case you're describing, where the chare type B isn't participating in an application-domain type hierarchy as such (AFAICT), the easiest thing to do is probably to prefer composition over inheritance, and simply have a member of type C in chare class B.

I'll let Nitin follow up on debugging what exactly went wrong, and correcting/elaborating on documentation.

I am curious to know what compiler you observed this failure on, though? In particular, is it by chance GCC 6.x? If so, have a look at bug #1045, and try the additional compiler flag -fno-lifetime-dse for both the runtime and your application code.

Also available in: Atom PDF