Unverified Commit fd32fbbe authored by Robert Kimball's avatar Robert Kimball Committed by GitHub

Remove Event tracing and replace with chrome trace (#4312)

* Remove Event tracing and replace with chrome trace

* style
Co-authored-by: 's avatarScott Cyphers <diyessi@users.noreply.github.com>
parent 43e393e6
......@@ -56,6 +56,8 @@ set (SRC
builder/split.hpp
builder/tensor_mask.hpp
check.hpp
chrome_trace.cpp
chrome_trace.hpp
code_writer.hpp
component_manager.hpp
coordinate.cpp
......@@ -596,8 +598,6 @@ set (SRC
runtime/backend_manager.hpp
runtime/cache.cpp
runtime/cache.hpp
runtime/chrome_trace.cpp
runtime/chrome_trace.hpp
runtime/executable.cpp
runtime/executable.hpp
runtime/host_tensor.cpp
......@@ -640,7 +640,7 @@ set(SRC ${SRC}
)
if(NGRAPH_JSON_ENABLE)
list(APPEND SRC serializer.cpp serializer.hpp event_tracing.cpp event_tracing.hpp)
list(APPEND SRC serializer.cpp serializer.hpp)
else()
list(APPEND SRC serializer_stub.cpp)
endif()
......
//*****************************************************************************
// Copyright 2017-2020 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************
#include <iostream>
#include <sstream>
#include <string>
#include "distributed.hpp"
#include "event_tracing.hpp"
#include "ngraph/env_util.hpp"
#include "nlohmann/json.hpp"
using namespace std;
NGRAPH_API mutex ngraph::Event::s_file_mutex;
NGRAPH_API ofstream ngraph::Event::s_event_log;
NGRAPH_API bool ngraph::Event::s_tracing_enabled = ngraph::getenv_bool("NGRAPH_ENABLE_TRACING");
NGRAPH_API bool ngraph::Event::s_event_writer_registered = false;
NGRAPH_API std::function<void(const ngraph::Event& event)> ngraph::Event::s_event_writer;
void ngraph::Event::write_trace(const ngraph::Event& event)
{
if (is_tracing_enabled())
{
lock_guard<mutex> lock(s_file_mutex);
if (s_event_writer_registered)
{
s_event_writer(event);
return;
}
static bool so_initialized = false;
if (!so_initialized)
{
// Open the file
std::string file_name = "ngraph_event_trace.json";
if (get_distributed_interface()->get_size() > 1)
{
auto rank = std::to_string(get_distributed_interface()->get_rank());
int num_zero = 3;
std::string prefix = std::string(num_zero - rank.length(), '0') + rank + "_";
file_name.insert(0, prefix);
}
s_event_log.open(file_name, ios_base::trunc);
s_event_log << "[\n";
so_initialized = true;
}
else
{
s_event_log << ",\n";
}
s_event_log << event.to_json() << "\n" << flush;
}
}
string ngraph::Event::to_json() const
{
ostringstream thread_id;
thread_id << this_thread::get_id();
nlohmann::json json_start = {{"name", m_name},
{"cat", m_category},
{"ph", "B"},
{"pid", m_pid},
{"tid", thread_id.str()},
{"ts", m_start.time_since_epoch().count() / 1000},
{"args", m_args}};
nlohmann::json json_end = {{"name", m_name},
{"cat", m_category},
{"ph", "E"},
{"pid", m_pid},
{"tid", thread_id.str()},
{"ts", m_stop.time_since_epoch().count() / 1000},
{"args", m_args}};
ostringstream output;
output << json_start << ",\n" << json_end;
return output.str();
}
void ngraph::Event::enable_event_tracing()
{
s_tracing_enabled = true;
}
void ngraph::Event::disable_event_tracing()
{
s_tracing_enabled = false;
}
//*****************************************************************************
// Copyright 2017-2020 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************
#pragma once
#include <chrono>
#include <fstream>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#ifdef _WIN32
#include <windows.h>
// windows.h must be before processthreadsapi.h so we need this comment
#include <processthreadsapi.h>
#define getpid() GetCurrentProcessId()
#else
#include <unistd.h>
#endif
#include <functional>
#include "ngraph/ngraph_visibility.hpp"
namespace ngraph
{
//
// This class records timestamps for a given user defined event and
// produces output in the chrome tracing format that can be used to view
// the events of a running program
//
// Following is the format of a trace event
//
// {
// "name": "myName",
// "cat": "category,list",
// "ph": "B",
// "ts": 12345,
// "pid": 123,
// "tid": 456,
// "args": {
// "someArg": 1,
// "anotherArg": {
// "value": "my value"
// }
// }
// }
//
// The trace file format is defined here:
// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
//
// The trace file can be viewed by Chrome browser using the
// URL: chrome://tracing/
//
// More information about this is at:
// http://dev.chromium.org/developers/how-tos/trace-event-profiling-tool
class Event
{
public:
explicit Event(const std::string& name,
const std::string& category,
const std::string& args)
: m_pid(getpid())
, m_start(std::chrono::high_resolution_clock::now())
, m_stopped(false)
, m_name(name)
, m_category(category)
, m_args(args)
{
m_stop = m_start;
}
void Stop()
{
if (m_stopped)
{
return;
}
m_stopped = true;
m_stop = std::chrono::high_resolution_clock::now();
}
const std::string& get_name() const { return m_name; }
const std::string& get_category() const { return m_category; }
const std::string& get_agrs() const { return m_args; }
const std::chrono::time_point<std::chrono::high_resolution_clock>& get_start() const
{
return m_start;
}
const std::chrono::time_point<std::chrono::high_resolution_clock>& get_stop() const
{
return m_stop;
}
static void register_event_writer(std::function<void(const Event& event)> callback)
{
std::lock_guard<std::mutex> lock(s_file_mutex);
s_event_writer_registered = true;
s_event_writer = callback;
}
static void write_trace(const Event& event);
static bool is_tracing_enabled() { return s_tracing_enabled; }
static void enable_event_tracing();
static void disable_event_tracing();
std::string to_json() const;
private:
int m_pid;
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
std::chrono::time_point<std::chrono::high_resolution_clock> m_stop;
bool m_stopped;
std::string m_name;
std::string m_category;
std::string m_args;
NGRAPH_API static std::mutex s_file_mutex;
NGRAPH_API static std::ofstream s_event_log;
NGRAPH_API static bool s_tracing_enabled;
NGRAPH_API static std::function<void(const Event& event)> s_event_writer;
NGRAPH_API static bool s_event_writer_registered;
};
} // namespace ngraph
......@@ -17,8 +17,8 @@
#include <cstring>
#include <memory>
#include "ngraph/chrome_trace.hpp"
#include "ngraph/descriptor/layout/dense_tensor_layout.hpp"
#include "ngraph/runtime/chrome_trace.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/util.hpp"
......
......@@ -15,6 +15,7 @@
//*****************************************************************************
#include "ngraph/runtime/interpreter/int_executable.hpp"
#include "ngraph/chrome_trace.hpp"
#include "ngraph/cpio.hpp"
#include "ngraph/descriptor/layout/dense_tensor_layout.hpp"
#include "ngraph/except.hpp"
......@@ -27,7 +28,6 @@
#include "ngraph/pass/manager.hpp"
#include "ngraph/pass/opset0_downgrade.hpp"
#include "ngraph/runtime/backend_manager.hpp"
#include "ngraph/runtime/chrome_trace.hpp"
#include "ngraph/serializer.hpp"
#include "ngraph/util.hpp"
......
......@@ -199,7 +199,7 @@ set(SRC
)
if(NGRAPH_JSON_ENABLE)
list(APPEND SRC core.cpp event_tracing.cpp serialize.cpp)
list(APPEND SRC core.cpp serialize.cpp)
endif()
if(NOT WIN32 AND NGRAPH_TOOLS_ENABLE)
......
//*****************************************************************************
// Copyright 2017-2020 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************
#include <fstream>
#include <iostream>
#include <mutex>
#include <stdlib.h>
#include <vector>
#include "nlohmann/json.hpp"
#include "gtest/gtest.h"
#include "ngraph/event_tracing.hpp"
#include "ngraph/file_util.hpp"
using namespace std;
TEST(event_tracing, event_file)
{
ngraph::Event::enable_event_tracing();
std::vector<std::thread> threads;
for (auto i = 0; i < 10; i++)
{
int id = i;
std::thread next_thread([&] {
std::ostringstream oss;
oss << "Event: " << id;
ngraph::Event event(oss.str(), "Dummy", "none");
std::this_thread::sleep_for(std::chrono::milliseconds(20));
event.Stop();
ngraph::Event::write_trace(event);
});
std::this_thread::sleep_for(std::chrono::milliseconds(20));
threads.push_back(std::move(next_thread));
}
for (auto& next : threads)
{
next.join();
}
// Now read the file
auto json_string = ngraph::file_util::read_file_to_string("ngraph_event_trace.json");
nlohmann::json json_from_file(json_string);
// Validate the JSON objects - there should be 10 of them
// TODO
ngraph::Event::disable_event_tracing();
}
TEST(event_tracing, event_writer_callback)
{
// Create the event writer
vector<ngraph::Event> event_list;
auto event_writer = [&](const ngraph::Event& event) { event_list.push_back(event); };
map<string, unique_ptr<ngraph::Event>> expected_event_table;
mutex expected_event_table_mtx;
ngraph::Event::enable_event_tracing();
ngraph::Event::register_event_writer(event_writer);
auto worker = [&](int worker_id) {
std::ostringstream oss;
oss << "Event: " << worker_id;
unique_ptr<ngraph::Event> event(new ngraph::Event(oss.str(), "Dummy", "none"));
std::this_thread::sleep_for(std::chrono::milliseconds(20));
event->Stop();
ngraph::Event::write_trace(*event);
lock_guard<mutex> lock(expected_event_table_mtx);
expected_event_table[event->get_name()] = move(event);
};
std::vector<std::thread> threads;
for (int i = 0; i < 10; i++)
{
std::thread thread_next(worker, i);
threads.push_back(move(thread_next));
}
for (auto& next : threads)
{
next.join();
}
ngraph::Event::disable_event_tracing();
// Now validate the events
ASSERT_EQ(10, event_list.size());
ASSERT_EQ(10, expected_event_table.size());
for (const auto& next_event : event_list)
{
const auto& expected_event_key = expected_event_table.find(next_event.get_name());
EXPECT_TRUE(expected_event_key != expected_event_table.end());
EXPECT_EQ(expected_event_key->second->get_name(), next_event.get_name());
EXPECT_EQ(expected_event_key->second->get_start(), next_event.get_start());
EXPECT_EQ(expected_event_key->second->get_stop(), next_event.get_stop());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment