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

575 event registry bugs #576

Merged
merged 12 commits into from
Nov 25, 2019
Merged

575 event registry bugs #576

merged 12 commits into from
Nov 25, 2019

Conversation

pnstickne
Copy link
Contributor

@pnstickne pnstickne commented Nov 19, 2019

"Works better". Pre-work to make #554 easier, as in 'not going to run into these issues'.

This will be part of #554 and as it contains trace-related bugs still.

  • fixed (apparent?) initialization ordering issue where events add during initialization could not be found later in certain cases (differed by example project).
  • fixed cross-access of iterators
  • a bunch of updates for consistency, responsibility hiding, etc.

Fixes #575

// Use static template initialization pattern to deal with ordering issues with
// auto-registry
template <typename = void>
// Container types are created-as-needed, which occurs during
Copy link
Contributor Author

Choose a reason for hiding this comment

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

"After making these changes, events are found in the programs that don't crash". As such, I suspect it's due to an initialization ordering issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(Where 'these changes' are specifically related to returning a new'ed pointer instead of a reference to a static object created during initialization somewhere..)

Copy link
Collaborator

Choose a reason for hiding this comment

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

With your changes, is all this still happening at static init time? It must execute then for correctness, except for the user's override setTraceName, if the user desires to override the given name.

src/vt/trace/trace.cc Outdated Show resolved Hide resolved
@pnstickne pnstickne requested review from nmm0 and uhetmaniuk November 19, 2019 17:50
@pnstickne pnstickne marked this pull request as ready for review November 21, 2019 03:45
// Use static template initialization pattern to deal with ordering issues with
// auto-registry
template <typename = void>
// Container types are created-as-needed, which occurs during
Copy link
Collaborator

Choose a reason for hiding this comment

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

With your changes, is all this still happening at static init time? It must execute then for correctness, except for the user's override setTraceName, if the user desires to override the given name.

class TraceContainers {
public:
static TraceContainerEventClassType& getEventTypeContainer(){
return event_type_container;
static TraceContainerEventClassType* getEventTypeContainer(){
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the motivation of hoisting this to a pointer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This could probably also be done with initialization of a non-pointer type (and separate variable capturing initialization state). Main change is it allows detection of initialization.

Copy link
Contributor Author

@pnstickne pnstickne Nov 22, 2019

Choose a reason for hiding this comment

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

if (not event_container_intiailized_) {
    event_container_ = EventContainerType{}; // explicit creation ordering
    event_container_intiailized_ = true;
}
return event_container_;

Copy link
Contributor Author

@pnstickne pnstickne Nov 22, 2019

Choose a reason for hiding this comment

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

However, even then my concern was it (event_container_) might be re-initialized later on if it was ordered after handlers during dynamic initialization.


namespace vt { namespace trace {

/*static*/ TraceContainerEventClassType*
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you should initialize this variable to nullptr

Copy link
Contributor Author

@pnstickne pnstickne Nov 22, 2019

Choose a reason for hiding this comment

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

Without the assignment it's guaranteed to be assigned all-zeros in the STATIC initialization. It's not until C++17 that assignment (in certain cases) is done during static initialization - and I wanted to be sure of not dynamic-overwrites-static initialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I had it first assigning to nullptr and then removed it - a comment would probably be useful.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lifflander It looks like a unique_ptr would still work with the default ctor (as it is constexpr); don't quite know what C++ level guarantees constexpr as static non-local initialization. Would still be returned as a raw ptr, accessed from get to usages.

Copy link
Contributor Author

@pnstickne pnstickne Nov 22, 2019

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Constant initialization is performed after (until C++14)instead of (since C++14) zero initialization of the static and thread-local objects and before all other initialization. Only the following variables are constant initialized:

  1. .. Static or thread-local object of class type that is initialized by a constructor call, if the constructor is constexpr ..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also then a shared_ptr: constexpr shared_ptr() noexcept;.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if (deliver) {
EventType event = no_event;

sendMsgBytesWithPut(dest, base, msg_size, send_tag);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there was a bug here before, or maybe the code change. I thought that sendMsgBytesWithPut should return an event. I think the code was refactored a long time ago not to, but this code didn't get updated.

} else {
return false;
}
return ArgType::vt_trace
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice cleanup!

return event_type_container;
static TraceContainerEventClassType* getEventTypeContainer(){
if (not event_type_container_)
event_type_container_ = new TraceContainerEventClassType();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see any delete almost sure that this leaks memory. Why are you using a manually allocated object? I would steer away from this. Ideally, C++ code should never include a new

Copy link
Contributor Author

@pnstickne pnstickne Nov 22, 2019

Choose a reason for hiding this comment

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

Never deleted. Global statics used in when writing the trace at the end of the program. Used when events are written - could update the naming to reflect that it's purposeful, or add a comment. (In all likeliness, this is only/almost exclusively updated during DYNAMIC initialization, with the exception of setTrace..)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

static_lifetime_events_ (eg.)

@nlslatt
Copy link
Collaborator

nlslatt commented Nov 25, 2019

@lifflander I don't know if it's related to this PR or not (I'm using beta.4 plus this PR on Mutrino), but I'm seeing an entry method hidden by Projections because there are no tracing events associated with it, even though it should have run many times. I'm specifically talking about Frontend::requestFields, which is called unconditionally by Backend::updateFieldSolutions (which itself does appear in the traces many times).

@lifflander
Copy link
Collaborator

@lifflander I don't know if it's related to this PR or not (I'm using beta.4 plus this PR on Mutrino), but I'm seeing an entry method hidden by Projections because there are no tracing events associated with it, even though it should have run many times. I'm specifically talking about Frontend::requestFields, which is called unconditionally by Backend::updateFieldSolutions (which itself does appear in the traces many times).

Was this also happening before 575 was being used?

- Cause an assert validation soon instead of writing to log file
  on process exit.. so the culprits can be better targeted.
- This will make future work simpler. Also no point dragging along
  even tiny costs through other TUs.
- An event ID of 0 has meaning of "no event" in various contexts.
  While unlikely this COULD result in missed traces.

  (Does not address the issue of duplicate trace ID's being possible.)
pnstickne added a commit that referenced this pull request Mar 31, 2020
- A little bit of shifting now to help a little bit
  more in the future.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- All banner, no runtime logic.
  Now has it's own little home.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- One function doing too much and mixing stuff.

- Also fixes code to return 'exit code';
  ie. 0 = success, other = exit.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- All arguments must be accounted for and correctly parsed.
  This mitigates "oops" cases when arguments are not correctly
  handled by appropriate domain.

  To supply MPI_Init args, use:
    `--vt_mpi_args mpiarg1 mpiarg2..`
  To supply user args (returned up through initialize):
    `-- userarg1 userarg2 ..`
  To switch back to VT args, use `--vt_args`

- Also supports 'auto pass-through' args for historic reasons.
  That is, any arguments before a "--vt_*" arg or "--help"
  are automatically classified as a pass-through arguments.

    `1 2 3 --vt_no_color` is the same as
    `--vt_no_color -- 1 2 3` while
    `--vt_no_color 1 2 3` is invalid (left in vt-arg context).

   Most notable, short vt args like '-c' or '-q' do NOT initiate
   vt-arg mode and will subject to pass-through behavior.

args mergeup
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- VT now terminates immediately on non-accounted-for arguments;
  and when --help is requested.

  Before args could be 'like whatever' and the help
  banner just flew through the terminal.

- Mitigates / controls some of arg-ref behavior,
  builds a clean MPI_Init argument set, and removes
  confusing user_argc/user_argv.

- Uses the new exposed prog_name which is also guaranteed
  to no contain extra pathing info..
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Banner message includes additional useful information about
  arguments that are passed downsteam.

  Arguments passed downsteam are not used by VT and coupled
  with the stricter argument checking.. should be more friendly!

- Banner includes the program name (just-file-name and any
  more complete path passed down from mpirun).
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- A little bit of shifting now to help a little bit
  more in the future.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- All calls now go through sync(), instead of some through
  there and some through MPI_Barrier.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- If any more is added, it should be skipped as parsing has been
  trivially rejected at the lower level.

  (In the future there may be more immediate post-parsing actions.)
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Now generates an MPI_Init/MPI_Abort sandwich to ensure
  basic contract of MPI. Output is only emitted during
  these times; the programs still terminate immediately
  thereafter.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Help is now "--vt_help"

- Removed short -c/-n/-q options for output.
  Use the full names like "--vt_quiet" instead.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- To avoid excessive spam, only the first node now emits a message.
  The responsibility is also pushed out.

  If the abort was caused by "help" the message is now written to
  stdout (instead of stderr) and the result code is 0.
  This is more uniform with many CLI utilities as the displaying
  of the help message, which was requested, is successful.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Now the parsing and configuration are separate
  types, even if still sharing the same cc file for declarations.

  The primary reason is to reduce header-bleed of implementation
  related types (such as vector<int,string>). This also
  force uniform access to ArgConfig for all..

  Also makes future non-static conversion of ArgParse
  much more.. lucrative. (eg. supply result message as
  member instead of returning outward)
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Added description and synopsis covering argument modes,
  switching between modes, and usages of such..

- Also unifies naming including that in banner messages.
  - "VT args" - used by VT configuration; --vt_*
  - "Application args" - supplied down-stream as argv
  - "MPI args" - used for MPI Init
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- std::_Exit is a little more 'abrupt' than C's exit
  in that it does less flushing and will not call registered
  at-exit's.. I guess, consistency is better? Maybe.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- All banner, no runtime logic.
  Now has it's own little home.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- One function doing too much and mixing stuff.

- Also fixes code to return 'exit code';
  ie. 0 = success, other = exit.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- All arguments must be accounted for and correctly parsed.
  This mitigates "oops" cases when arguments are not correctly
  handled by appropriate domain.

  To supply MPI_Init args, use:
    `--vt_mpi_args mpiarg1 mpiarg2..`
  To supply user args (returned up through initialize):
    `-- userarg1 userarg2 ..`
  To switch back to VT args, use `--vt_args`

- Also supports 'auto pass-through' args for historic reasons.
  That is, any arguments before a "--vt_*" arg or "--help"
  are automatically classified as a pass-through arguments.

    `1 2 3 --vt_no_color` is the same as
    `--vt_no_color -- 1 2 3` while
    `--vt_no_color 1 2 3` is invalid (left in vt-arg context).

   Most notable, short vt args like '-c' or '-q' do NOT initiate
   vt-arg mode and will subject to pass-through behavior.

args mergeup
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- VT now terminates immediately on non-accounted-for arguments;
  and when --help is requested.

  Before args could be 'like whatever' and the help
  banner just flew through the terminal.

- Mitigates / controls some of arg-ref behavior,
  builds a clean MPI_Init argument set, and removes
  confusing user_argc/user_argv.

- Uses the new exposed prog_name which is also guaranteed
  to no contain extra pathing info..
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Banner message includes additional useful information about
  arguments that are passed downsteam.

  Arguments passed downsteam are not used by VT and coupled
  with the stricter argument checking.. should be more friendly!

- Banner includes the program name (just-file-name and any
  more complete path passed down from mpirun).
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- A little bit of shifting now to help a little bit
  more in the future.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- All calls now go through sync(), instead of some through
  there and some through MPI_Barrier.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- If any more is added, it should be skipped as parsing has been
  trivially rejected at the lower level.

  (In the future there may be more immediate post-parsing actions.)
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Now generates an MPI_Init/MPI_Abort sandwich to ensure
  basic contract of MPI. Output is only emitted during
  these times; the programs still terminate immediately
  thereafter.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Help is now "--vt_help"

- Removed short -c/-n/-q options for output.
  Use the full names like "--vt_quiet" instead.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- To avoid excessive spam, only the first node now emits a message.
  The responsibility is also pushed out.

  If the abort was caused by "help" the message is now written to
  stdout (instead of stderr) and the result code is 0.
  This is more uniform with many CLI utilities as the displaying
  of the help message, which was requested, is successful.
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Now the parsing and configuration are separate
  types, even if still sharing the same cc file for declarations.

  The primary reason is to reduce header-bleed of implementation
  related types (such as vector<int,string>). This also
  force uniform access to ArgConfig for all..

  Also makes future non-static conversion of ArgParse
  much more.. lucrative. (eg. supply result message as
  member instead of returning outward)
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- Added description and synopsis covering argument modes,
  switching between modes, and usages of such..

- Also unifies naming including that in banner messages.
  - "VT args" - used by VT configuration; --vt_*
  - "Application args" - supplied down-stream as argv
  - "MPI args" - used for MPI Init
lifflander pushed a commit that referenced this pull request Jun 11, 2020
- std::_Exit is a little more 'abrupt' than C's exit
  in that it does less flushing and will not call registered
  at-exit's.. I guess, consistency is better? Maybe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Events not found (and causing crash on trace write)
3 participants