Skip to content

Commit

Permalink
#900 pmpi- wrappers generate collective events
Browse files Browse the repository at this point in the history
  • Loading branch information
pnstickne committed Jul 14, 2020
1 parent 945017d commit f1c2ab0
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 35 deletions.
126 changes: 94 additions & 32 deletions src/vt/pmpi/generate_mpi_wrappers.pl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
die "Incorrect usage: missing parameters";
}

# MPI definitions that should always be ignored.
# The most reasonable reason for being in this list is that they do
# not exist on all platforms or are inconsitently implemented as macros, etc.
# - MPI_Aint_(add|diff) - in OpenMPI 1.10 as macros
# - MPI_File_(iwrite|iread)_(all|at_all) - missing in OpenMPI 1.10
my @never_include_patterns = qw(
MPI_Aint_(add|diff)
MPI_File_(iwrite|iread)_(all|at_all)
);

# Extract MPI function definitions.
# It's a very rudimentary extractor that relies on definitions being on one line.
sub extract_defs {
Expand Down Expand Up @@ -51,23 +61,23 @@ sub extract_defs {
});
} @deflines;

@deflines = grep {
my $name = $_->{name};
not grep { $name =~ m/^$_$/; } @never_include_patterns;
} @deflines;

return @deflines;
}

# MPI calls that can be 'safely' used without being guarded
# or are otherwise excluded due to minimal benefit, compatibility issues, etc.
# MPI calls that can be 'safely' used without being guarded.
# - Common idempotent 'get' calls
# - MPI_Aint_(add|diff) - in OpenMPI 1.10 as macros
# - MPI_File_(iwrite|iread)_(all|at_all) - missing in OpenMPI 1.10
my @no_guard_patterns = qw(
MPI_Comm_get_.*
MPI_Comm_rank
MPI_Comm_size
MPI_Get.*(?<!_accumulate)
MPI_Wtime
MPI_Wtick
MPI_Aint_(add|diff)
MPI_File_(iwrite|iread)_(all|at_all)
);

sub should_guard_call {
Expand All @@ -77,35 +87,78 @@ sub should_guard_call {
} @no_guard_patterns;
}

sub declare_event {
my ($name) = @_;
say " static vt::trace::UserEventIDType event_${name} = vt::trace::no_user_event_id;";
}

sub register_event {
my ($name) = @_;
say " event_${name} = theTrace()->registerUserEventColl(\"${name}\");";
}

sub log_event {
my ($name) = @_;
say <<LOG;
auto scopedEvent = vt::trace::TraceScopedEventHash{"${name}_called"};
LOG
say "#if backend_check_enabled(trace_enabled)";
say " auto scopedEvent = vt::trace::TraceScopedEvent(event_${name});";
say "#endif";
}

# Special actions.
# Keys are patterns, values are hashrefs to subrefs.
my %call_actions = (
qr/MPI_\w?send/i => {
before => \&log_event
},
qr/MPI_\w?recv/i => {
before => \&log_event
},
# Form is {
# include => pattern,
# exclude? => pattern,
# declareEvent? => subref,
# registerEvent? => subref,
# beforeCall? => subref
# }
my @call_actions = (
{
include => qr/.*/,
exclude => qr/MPI_Wtime/,
declareEvent => \&declare_event,
registerEvent => \&register_event,
beforeCall => \&log_event
}
);

# Returns the action associated with the name, if any.
# Only the first matching action is returned.
sub get_call_action {
my ($name) = @_;
while (my ($p, $s) = each %call_actions) {
if ($name =~ m/^$p$/) {
return $s;
foreach (@call_actions) {
my $i = $_->{include};
my $x = $_->{exclude} || qr//;
# Matches include and does not match exclude.
if ($name =~ m/^${i}$/ && !($name =~ m/^${x}$/)) {
return $_;
}
}
return undef;
}

sub invoke_action_for_all_defs {
my ($action_name) = @_;

foreach my $def (extract_defs $mpidef_file) {

my $name = $def->{name};

unless ($name) {
next;
}

my $action = get_call_action $name;

unless ($action and $action->{$action_name}) {
next;
}

my $s = $action->{$action_name};
&$s($name);
}
}

open(my $out, '>', $output_file)
or die "Could not open file '$output_file': $!";
select $out;
Expand All @@ -119,8 +172,11 @@ sub emit_prologue {
say <<PROLOGUE;
#include "vt/config.h"
#include "vt/runtime/mpi_access.h"
#if backend_check_enabled(trace_enabled)
#include "vt/trace/trace.h"
#include "vt/trace/trace_user.h" // TraceScopedEventHash
#include "vt/trace/trace_user.h" // TraceScopedEvent
#endif
#include <mpi.h>
Expand All @@ -131,10 +187,6 @@ sub emit_prologue {
#include "vt/pmpi/pmpi_component.h"
void vt::pmpi::PMPIComponent::registerEventHandlers() {
// TODO
}
PROLOGUE
}

Expand Down Expand Up @@ -167,6 +219,21 @@ sub emit_call_original {

emit_prologue;

# Declarations.
say "#if backend_check_enabled(trace_enabled)";
invoke_action_for_all_defs 'declareEvent';
say "#endif";

# Event registrations.
say "";
say "void vt::pmpi::PMPIComponent::registerEventHandlers() {";
say "#if backend_check_enabled(trace_enabled)";
invoke_action_for_all_defs 'registerEvent';
say "#endif";
say "}";

# PMPI wrappers.

foreach my $def (extract_defs $mpidef_file) {
my $name = $def->{name};
my $should_guard = should_guard_call $name;
Expand All @@ -182,18 +249,13 @@ sub emit_call_original {
emit_guard $def->{name};
}

if ($action and $action->{before}) {
my $s = $action->{before};
if ($action and $action->{beforeCall}) {
my $s = $action->{beforeCall};
&$s($name);
}

emit_call_original $def->{name}, $def->{callargs}, $def->{ret};

if ($action and $action->{after}) {
my $s = $action->{after};
&$s($name);
}

say "}";
}

Expand Down
6 changes: 3 additions & 3 deletions src/vt/runtime/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -601,9 +601,9 @@ void Runtime::initializeComponents() {
# if backend_check_enabled(mpi_access_guards)
p_->registerComponent<pmpi::PMPIComponent>(
&thePMPI, Deps<
trace::Trace, // For scheduler-related trace events
messaging::ActiveMessenger, // Sends message for event registration (shouldn't be needed)..
sched::Scheduler // ..which are queued in the scheduler.
# if backend_check_enabled(trace_enabled)
trace::Trace // For PMPI tracing, if tracing is enabled.
# endif
>{}
);
#endif
Expand Down

0 comments on commit f1c2ab0

Please sign in to comment.