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

Mpi omp support #336

Open
wants to merge 322 commits into
base: master
Choose a base branch
from
Open

Mpi omp support #336

wants to merge 322 commits into from

Conversation

hiker
Copy link
Collaborator

@hiker hiker commented Aug 21, 2024

This PR adds configuration settings that enable/disable MPI and OpenMP to BuildConfig.

This means that an application can now specify that it should be compiled with OpenMP, without having to specify compiler-specific OpenMP flags - the Compiler object will get the information from the BuildConfig if it should add the flag or not.

Similarly, if an MPI build is requested, the tool repository will return an MPI enabled compiler (but the user can always overwrite this by hand-selecting a compiler explicitly).

Note that the MPI compiler wrapper added here will get a nicer (decorator-based) implementation in the next PR, I just tried to keep the PRs small. This PR is still quite big, but that's because I made the MPI and OpenMP settings mandatory (imho it makes sense to get the user to specify what exactly they want). The CLI defaults both to False. Additionally, I started to fix the line length (according to the discussion in #323

hiker and others added 30 commits April 20, 2024 01:23
…ccept a function that can return file-specific transformation scripts
@hiker
Copy link
Collaborator Author

hiker commented Aug 28, 2024

Forgot to request a review sigh

Copy link
Collaborator

@MatthewHambley MatthewHambley left a comment

Choose a reason for hiding this comment

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

The reformatting does add many extra changes but it needs to be done so I'm content with including it.

I think this change takes is in the right direction, my primary concern is the fact that tools for which "MPI" and "OpenMP" have no meaning have gained arguments for them.

Please give this some consideration. If tackling this issue would be a considerable amount of work I'm happy for you to raise an issue for it and link that to this change.

Comment on lines 45 to 46
mpi: bool,
openmp: bool,
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 is an argument for making these optional with a default to False but that is not an argument we need to have now. It's always possible to make an interface more permissive.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As discussed in our meeting, I've made False the default, and updated tests and run_configs.

Comment on lines 43 to 52
def __init__(self, project_label: str,
tool_box: ToolBox,
multiprocessing: bool = True, n_procs: Optional[int] = None,
mpi: bool,
openmp: bool,
multiprocessing: bool = True,
n_procs: Optional[int] = None,
reuse_artefacts: bool = False,
fab_workspace: Optional[Path] = None, two_stage=False,
verbose=False):
fab_workspace: Optional[Path] = None,
two_stage: bool = False,
verbose: bool = False):
Copy link
Collaborator

Choose a reason for hiding this comment

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

A general observation that this argument list is getting pretty unwieldy. Something to consider at a future date.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well, that seems unavoidable - in a complex build systems there are a lot of things to be defined :) Now that mpi/openmp are optional, it might be better? Also, this mostly will be handled by the command line tool in the end, which should have an appropriate man page/help command.

:param mpi: whether the project uses MPI or not. This is used to
pick a default compiler (if not explicitly set in the ToolBox),
and controls PSyclone parameters.
:param openmp: whether the project should use OpenMP or not.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This argument presumably has the same caveats as the previous one. Is there a way to cover this without repeating boiler plate? Either group them and have some group documentation or with suitable wording.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, it doesn't. We looked at all compiolers to be reasonably expected to be used (intel-classic, intel-llvm, gnu, clang, cray, nvidia) all of which support openmp.

Comment on lines +61 to +65
# TODO: Should we test if the compiler has MPI support if
# required? The original LFRic setup compiled files without
# MPI support (and used an mpi wrapper at link time), so for
# now we don't raise an exception here to ease porting - but
# we probably should raise one tbh.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Part of this would presumably also involve support for OpenMP. i.e. Adding an openmp argument to the method and ensuring the compiler supported it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same as above. I believe nowadays we can assume that compiler support openmp

Comment on lines +134 to +140
def get_default(self, category: Category,
mpi: Optional[bool] = None):
'''Returns the default tool for a given category. For most tools
that will be the first entry in the list of tools. The exception
are compilers and linker: in this case it must be specified if
MPI support is required or not. And the default return will be
the first tool that either supports MPI or not.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Your comment raises an important point. The concept of "MPI" makes no sense for most tools. We may need to rethink this whole API but maybe not for this change.

Can the MPI-ness be made part of the category? Something like tool_repo.get_default(FortranCompiler(mpi=True)).

Copy link
Collaborator Author

@hiker hiker Sep 2, 2024

Choose a reason for hiding this comment

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

@MatthewHambley
Fair point, I have half a dozen alternatives, here the few that I think are actually sensible:

  1. We add separate get_compiler/get_linker methods (which take mpi as parameter), nothing else does.
  2. We abort if a value for mpi is specified for any non-compiler/linker too. Or we turn this into kargs, meaning we can add tool-specific flags in the future, and for now only accept MPI for compiler/linker.
  3. We add the BuildConfig as argument instead of mpi only. We can access the mpi status this way, and whatever any tool might need in the future could be done (admittedly I can't think of anything useful here :) ... maybe, and I am clutching at straws here, a tool could access the number of cores to use in a build, if a tool itself can run in parallel??)

Would one of these solution work for you? Or do you have a better idea?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@MatthewHambley That's the question I need your preference so that I can update this.

Comment on lines +89 to +90
compiler, flags_config = handle_compiler_args(config, common_flags,
path_flags)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not using the MPI flag. Is that a problem? Is there a risk of a compiler other than the one returned with MPI flag being returned? If so the setup may not match the compiler which ends up being used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The MPI flag is used when picking the compiler, so at this stage we already have an MPI-enabled compiler (if required).



# ============================================================================
class MpiGcc(Gcc):
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm looking at this and I wonder if we need to more closely model the reality of the situation.

We can't simply have an "MPI compiler" which calls the "mpixxx" wrapper script because we need to pass command line arguments correct to the compiler being wrapped. But maybe we have an MPI compiler which takes (and wraps) a concrete compiler.

class MpiC(CCompiler):
    def __init__(self, compiler: CCompiler...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That was done in the next PR (I split this to make the individual PRs smaller and hopefully easier to review).
See e.g.
https://github.com/hiker/fab_new/blob/e5dd7c9dd0400b0f24d798539d50439a59fcb45e/source/fab/tools/compiler_wrapper.py#L31

Comment on lines 32 to 33
return BuildConfig('proj', ToolBox(), mpi=False, openmp=False,
fab_workspace=tmp_path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This highlights an issue. Why does a test of Git functionality have to care about MPI and OpenMP?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is that not another argument to having mpi and openmp optional arguments (that default to "False"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@hiker
Copy link
Collaborator Author

hiker commented Sep 2, 2024

The reformatting does add many extra changes but it needs to be done so I'm content with including it.

Yes. How did you do #323? Just running black with certain option? If you give us the option, we can do this between our upcoming PRs, to get it out of the way once. And I really appreciate not merging #323 in, as you can see, that will potentially cause us quite a bit of headache in terms of possible conflicts :(

@MatthewHambley
Copy link
Collaborator

Yes. How did you do #323? Just running black with certain option?

I did it by hand, directed by flake8.

@hiker
Copy link
Collaborator Author

hiker commented Oct 21, 2024

OK, I'll just declare this ready for next review after giving mpi/openmp a default, to avoid the confusion about there his PR is at :)

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

Successfully merging this pull request may close these issues.

5 participants