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 a 'hook' framework #2773

Merged
merged 1 commit into from
Feb 28, 2017
Merged

Add a 'hook' framework #2773

merged 1 commit into from
Feb 28, 2017

Conversation

jjhursey
Copy link
Member

Add a hook static framework to the ompi layer.

Among other uses, this framework is useful as one mechanism for licensing. For licensing it is important that components have the option to be built statically, and not allow the user to force it to be unloaded. The two commits here do just that.

This includes a demo component that provides an example of how the framework might be used.

The framework allows for static components, dynamic components, and dynamic registration of 'hooks' by components in other frameworks. The latter enhancement has proven useful in components that need to know if the application is between MPI_Init and MPI_Finalize.

/*
* Some functions are specially marked. See decoder below.
*
* *** Static Only (Allways) ***
Copy link
Member Author

Choose a reason for hiding this comment

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

SP: always

@jjhursey
Copy link
Member Author

jjhursey commented Jan 25, 2017

Comments from Open MPI face-to-face meeting:

  • Concern that we are putting in a feature upstream for a component that is not upstream (i.e., licensing example)
  • By adding this option we are misleading the user when they say -mca fwk foo but component bar is marked as always-consider then they are actually getting foo,bar
    • Need to allow the user to know that this is happening. Maybe add a help message to be displayed letting them know that we forced bar to be included.
    • Concern about allowing this to be applied to all frameworks.
      • Move the flag to be a hook framework selection only flag?
  • Use cases mentioned in the room for the always-consider flag: licensing, btl/self, coll/self
    • Push back on all but the licensing case

Resolution:

  • Required / Mandatory flag : Put flag in base, but enforcement in ompi/mca/hook/base, Requires staticly built/linked component.
  • Suggested / Recommended flag : btl/self, coll/self - Separate PR to add this option.
  • Disabled flag : Separate PR to add this option

@jjhursey
Copy link
Member Author

If the user tries to avoid a required component then a mess like the following is printed just before MPI_Init fails out.

--------------------------------------------------------------------------
Error: A request was made to exclude a hook component from consideration that
is required to be included. This component (noted below) can -not- be excluded
from consideration. The program will fail at this time.
 
Framework: hook
Component: demo
--------------------------------------------------------------------------

@jjhursey
Copy link
Member Author

@jsquyres I'm going to ask you to review, if you have time. We'd like to get this into the v2.x series if at all possible.

#

# we only want one :)
#m4_define(MCA_ompi_hook_CONFIGURE_MODE, STOP_AT_FIRST)
Copy link
Member

Choose a reason for hiding this comment

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

I think you need the delete the above 2 lines.


void ompi_hook_demo_mpi_initialized_top(int *flag)
{
DEBUG_OUTPUT( mpi_initialized_top );
Copy link
Member

Choose a reason for hiding this comment

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

Did you not want to use __func__ for some reason?

Copy link
Member Author

Choose a reason for hiding this comment

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

No reason. I suppose I just wanted to make work for myself. :) I'll clean that up on the next iteration.

opal/mca/mca.h Outdated
breaking older components. */
char reserved[32];
breaking older components.
NTH/JJH: reduced by 4 bytes for mca_component_flags */
Copy link
Member

Choose a reason for hiding this comment

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

This comment should likely either be explained further or moved to the commit message. I.e., if you look at this comment 12 months from now, will it still be relevant? Or stale? Do we need to know in the code that the padding was reduced by 4? Or only when spelunking through old commits? (I'm guessing the latter)

* If the framework has not been opened, then we can only use the static components.
*
* Otherwise we would need to initialize opal outside of ompi_mpi_init and possibly
* after ompi_mpi_finalize which gets messy (especially when tring to cleanup).
Copy link
Member

Choose a reason for hiding this comment

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

tring -> trying

* 2) dynamic components
* 3) 'registered' components (those registered by ompi_hook_base_register_callbacks)
*/
#define HOOK_CALL_COMMON_IN_MPI(fn_name, ...) \
Copy link
Member

Choose a reason for hiding this comment

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

This name (and HOOK_CALL_COMMON_NOT_IN_MPI) is misleading. You call this macro (or the other one) depending on whether the hook framework has been initialized -- not whether we are in MPI or not.

This may be nit-picky, but it also could apply to OSHMEM someday.



/**
* Register another component to be called
Copy link
Member

Choose a reason for hiding this comment

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

Can you put a little more explanation of this functionality here?

.hookm_mpi_init_bottom = ompi_hook_demo_extra_mpi_init_bottom,
};

static int ompi_hook_demo_component_open(void)
Copy link
Member

Choose a reason for hiding this comment

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

Since this is a demo component, can you add some verbose comments here explaining the use of this extra component and the extra registration / deregistration?


#include "ompi_config.h"

#include "hook_demo.h"
Copy link
Member

Choose a reason for hiding this comment

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

Should probably also include opal_output.h in here, since you call opal_output().


#include "ompi_config.h"

#include "hook_demo.h"
Copy link
Member

Choose a reason for hiding this comment

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

Should probably also include opal_output.h in here, since you call opal_output().


void ompi_hook_demo_extra_mpi_init_bottom(int argc, char **argv, int requested, int *provided)
{
DEBUG_OUTPUT( mpi_init_bottom (extra) );
Copy link
Member

Choose a reason for hiding this comment

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

I could not find where mpi_init_bottom was defined, nor extra..., but yet this file still compiled for me. Whaaa...? I have to run now and can't investigate further...

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the macro was masking it by interpreting it as a string. It was a leftover from an older version - I'll clean that out.

@jsquyres
Copy link
Member

Also, given that this framework will almost certainly be used with out of tree components, there should definitely be thought given to versioning of the components and modules, and also how to expand the component and or module without screwing out-of-tree components.

@jsquyres
Copy link
Member

One last thought: can you put a README[.md] in the demo component? It would be good to explain a few things to someone who is coming in cold to the hook framework.

 * Include a 'demo' component that shows some of the features.
 * Currently has hooks for:
   - MPI_Initialized
     - top, bottom
   - MPI_Init_thread
     - top, bottom
   - MPI_Finalized
     - top, bottom
   - MPI_Init
     - top (pre-opal_init), top (post-opal_init), error, bottom
   - MPI_Finalize
     - top, bottom
 * Other places in ompi can 'register' to hook into any one of these places
   by passing back a component structure filled with function pointers.
 * Add a `MCA_BASE_COMPONENT_FLAG_REQUIRED` flag to the MCA structure that
   is checked by the `hook` framework. If a required, static component has
   been excluded then the `hook` framework will fail to initialize.
   - See note in `opal/mca/mca.h` as to why this is checked in the `hook`
     framework and not in `opal/mca/base/mca_base_component_find.c`

Signed-off-by: Joshua Hursey <jhursey@us.ibm.com>
@jjhursey
Copy link
Member Author

@jsquyres I just pushed an update that I think addresses all of your comments except the demo/Readme.md. I can try to add that today if you think it's still necessary.

This was delayed a bit because I was experimenting with how best to support forwards compatible components. I have enough of a solution (outside of this PR on a side branch) to feel comfortable moving forward.

@jjhursey
Copy link
Member Author

@jsquyres Thanks for the review!

@jjhursey jjhursey merged commit 0006f0d into open-mpi:master Feb 28, 2017
@jjhursey jjhursey deleted the topic/hook-fwk branch February 28, 2017 18:29
@jjhursey jjhursey mentioned this pull request Mar 6, 2017
6 tasks
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.

None yet

3 participants