Skip to content

Commit

Permalink
Merge branch '1.0.0-689-tracing-spec-2' into 1.0.0-beta.5-proposed-up…
Browse files Browse the repository at this point in the history
…date
  • Loading branch information
lifflander committed Feb 19, 2020
2 parents acdc52e + b12afad commit 6c7f0e9
Show file tree
Hide file tree
Showing 13 changed files with 855 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ set(
objgroup
objgroup/proxy objgroup/holder objgroup/active_func objgroup/dispatch
objgroup/type_registry

trace
trace/file_spec
)
list(APPEND PROJECT_SUBDIRS_LIST ${TOP_LEVEL_SUBDIRS})

Expand Down
8 changes: 8 additions & 0 deletions src/vt/configs/arguments/args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ namespace vt { namespace arguments {
/*static*/ std::string ArgConfig::vt_trace_dir = "";
/*static*/ int32_t ArgConfig::vt_trace_mod = 0;
/*static*/ int32_t ArgConfig::vt_trace_flush_size = 0;
/*static*/ bool ArgConfig::vt_trace_spec = false;
/*static*/ std::string ArgConfig::vt_trace_spec_file = "";

/*static*/ bool ArgConfig::vt_lb = false;
/*static*/ bool ArgConfig::vt_lb_file = false;
Expand Down Expand Up @@ -231,20 +233,26 @@ namespace vt { namespace arguments {
auto tdir = "Name of directory for trace files";
auto tmod = "Output trace file if (node % vt_stack_mod) == 0";
auto tflushmod = "Flush output trace every (vt_trace_flush_size) trace records";
auto tspec = "Enable trace spec file (defines which phases tracing is on)";
auto tspecfile = "File containing trace spec; --vt_trace_spec to enable";
auto n = app.add_flag("--vt_trace", vt_trace, trace);
auto nm = app.add_flag("--vt_trace_mpi", vt_trace_mpi, trace_mpi);
auto o = app.add_option("--vt_trace_file", vt_trace_file, tfile, "");
auto p = app.add_option("--vt_trace_dir", vt_trace_dir, tdir, "");
auto q = app.add_option("--vt_trace_mod", vt_trace_mod, tmod, 1);
auto qf = app.add_option("--vt_trace_flush_size", vt_trace_flush_size,tflushmod,
0);
auto qza = app.add_flag("--vt_trace_spec", vt_trace_spec, tspec);
auto qzb = app.add_option("--vt_trace_spec_file", vt_trace_spec_file, tspecfile, "");
auto traceGroup = "Tracing Configuration";
n->group(traceGroup);
nm->group(traceGroup);
o->group(traceGroup);
p->group(traceGroup);
q->group(traceGroup);
qf->group(traceGroup);
qza->group(traceGroup);
qzb->group(traceGroup);

/*
* Flags for controlling debug print output at runtime
Expand Down
2 changes: 2 additions & 0 deletions src/vt/configs/arguments/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ struct ArgConfig {
static std::string vt_trace_dir;
static int32_t vt_trace_mod;
static int32_t vt_trace_flush_size;
static bool vt_trace_spec;
static std::string vt_trace_spec_file;

static bool vt_lb;
static bool vt_lb_file;
Expand Down
27 changes: 27 additions & 0 deletions src/vt/runtime/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,29 @@ void Runtime::printStartupBanner() {
auto f12 = opt_inverse("--vt_trace_flush_size", f11);
fmt::print("{}\t{}{}", vt_pre, f12, reset);
}
if (ArgType::vt_trace_spec) {
{
auto f11 = fmt::format("Using trace enable specification for phases");
auto f12 = opt_on("--vt_trace_spec", f11);
fmt::print("{}\t{}{}", vt_pre, f12, reset);
}
if (ArgType::vt_trace_spec_file == "") {
auto warn_trace_file = fmt::format(
"{}Warning:{} {}{}{} has no effect: no specification file given"
" option {}{}{} is empty{}\n", red, reset, magenta,
"--vt_trace_spec",
reset, magenta, "--vt_trace_spec_file", reset, reset
);
fmt::print("{}\t{}{}", vt_pre, warn_trace_file, reset);
} else {
auto f11 = fmt::format(
"Using trace specification file \"{}\"",
ArgType::vt_trace_spec_file
);
auto f12 = opt_inverse("--vt_trace_spec", f11);
fmt::print("{}\t{}{}", vt_pre, f12, reset);
}
}
}
#endif

Expand Down Expand Up @@ -976,6 +999,10 @@ void Runtime::setup() {
MPI_Barrier(theContext->getComm());
});

# if backend_check_enabled(trace_enabled)
theTrace->loadAndBroadcastSpec();
# endif

if (ArgType::vt_pause) {
pauseForDebugger();
}
Expand Down
2 changes: 1 addition & 1 deletion src/vt/runtime/runtime_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ struct RuntimeHolder {
}

void release() {
if (owner_ && rt_ && rt_->isFinializeble() && rt_->hasSchedRun()) {
if (owner_ && rt_ && rt_->isFinializeble() && rt_->hasSchedRun() && rt_->isTerminated()) {
rt_->finalize();
}
rt_ = nullptr;
Expand Down
250 changes: 250 additions & 0 deletions src/vt/trace/file_spec/spec.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
/*
//@HEADER
// *****************************************************************************
//
// spec.cc
// DARMA Toolkit v. 1.0.0
// DARMA/vt => Virtual Transport
//
// Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC
// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
// Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact [email protected]
//
// *****************************************************************************
//@HEADER
*/

#include "vt/config.h"
#include "vt/trace/file_spec/spec.h"
#include "vt/objgroup/manager.h"

#include <fstream>

namespace vt { namespace trace { namespace file_spec {

void TraceSpec::init(ProxyType in_proxy) {
proxy_ = in_proxy;
}

bool TraceSpec::checkTraceEnabled(SpecIndex in_phase) {
vtAssertExpr(has_spec_);

for (auto&& elm : spec_mod_) {
if (elm.second.testTraceEnabledFor(in_phase)) {
return true;
}
}
for (auto&& elm : spec_exact_) {
if (elm.second.testTraceEnabledFor(in_phase)) {
return true;
}
}
return false;
}

bool TraceSpec::hasSpec() {
if (ArgType::vt_trace_spec) {
if (ArgType::vt_trace_spec_file == "") {
vtAbort(
"--vt_trace_spec enabled but no file name is specified:"
" --vt_trace_spec_file"
);
return false;
} else {
auto& filename = ArgType::vt_trace_spec_file;
std::ifstream file(filename);
if (not file.good()) {
auto str = fmt::format(
"--vt_trace_spec_file={} is not a valid file", filename
);
vtAbort(str);
return false;
} else {
return true;
}
}
} else {
return false;
}
}

void TraceSpec::parse() {
if (not hasSpec()) {
return;
}

auto& filename = ArgType::vt_trace_spec_file;
std::ifstream file(filename);
vtAssertExpr(file.good());

while (!file.eof()) {
bool is_mod = false;
SpecIndex phase = -1;
SpecIndex phase_negative_offset = 0;
SpecIndex phase_positive_offset = 0;

int c = eatWhitespace(file);

/*
* Optionally parse an entry that starts with an mod phase: "% ..."
* ^
*/
if (static_cast<char>(c) == '%') {
is_mod = true;
// Eat up the '%', move to next
file.get();
c = eatWhitespace(file);
}

/*
* Parse phase/mod phase: "[%]10..."
* ^^
*/
if (std::isdigit(c)) {
file >> phase;
}

c = eatWhitespace(file);

/*
* Parse negative offset for phase/mod: "[%]10 -5..."
* ^^
* This offset must be negative or zero!
*/
if (std::isdigit(c) or static_cast<char>(c) == '-') {
file >> phase_negative_offset;
vtAbortIf(
phase_negative_offset > 0,
fmt::format(
"Parsing file \"{}\" error: found offset in negative offset position"
" that is > 0: value \"{}\"",
filename,
phase_negative_offset
)
);
}

c = eatWhitespace(file);

/*
* Parse positive offset for phase/mod: "[%]10 -5 5..."
* ^
* This offset must be positive or zero!
*/
if (std::isdigit(c)) {
file >> phase_positive_offset;
vtAbortIf(
phase_positive_offset < 0,
fmt::format(
"Parsing file \"{}\" error: found offset in positive offset position"
" that is < 0: value \"{}\"",
filename,
phase_positive_offset
)
);
}

eatWhitespace(file);

/*
* Entry is complete; eat all the following newlines
*/
while (file.peek() == '\n') {
file.get();
}

debug_print(
trace, node,
"TraceSpec::parser: is_mod={}, phase={}, neg={}, pos={}\n",
is_mod, phase, phase_negative_offset, phase_positive_offset
);

// We have a whole entry, put in the spec; it should not already exist
insertSpec(
phase, phase_negative_offset, phase_positive_offset, is_mod,
is_mod ? spec_mod_ : spec_exact_
);
}

has_spec_ = true;
}

void TraceSpec::broadcastSpec() {
auto root = theContext()->getNode();
auto msg = makeMessage<SpecMsg>(spec_mod_, spec_exact_, root);
proxy_.template broadcast<SpecMsg, &TraceSpec::transferSpec>(msg.get());
}

void TraceSpec::transferSpec(SpecMsg* msg) {
// The broadcast will hit all nodes, so the node that it exists on will
// ignore it
if (not has_spec_) {
spec_mod_ = msg->spec_mod_;
spec_exact_ = msg->spec_exact_;
has_spec_ = true;
}
}

void TraceSpec::insertSpec(
SpecIndex phase, SpecIndex neg, SpecIndex pos, bool is_mod, SpecMapType& map
) {
vtAbortIf(
map.find(phase) != map.end(),
fmt::format(
"Parsing file \"{}\" error: multiple lines start with the same {}:"
" value \"{}{}\"",
is_mod ? "mod phase" : "phase",
ArgType::vt_trace_spec_file,
is_mod ? "%" : "",
phase
)
);
map.emplace(
std::piecewise_construct,
std::forward_as_tuple(phase),
std::forward_as_tuple(SpecEntry{phase, neg, pos, is_mod})
);
}

int TraceSpec::eatWhitespace(std::ifstream& file) {
while (not file.eof() and std::isspace(file.peek()) and file.peek() != '\n') {
file.get();
}
return file.eof() ? 0 : file.peek();
}

/*static*/ typename TraceSpec::ProxyType TraceSpec::construct() {
auto proxy = theObjGroup()->makeCollective<TraceSpec>();
proxy.get()->init(proxy);
return proxy;
}

}}} /* end namespace vt::trace::file_spec */
Loading

0 comments on commit 6c7f0e9

Please sign in to comment.