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

AutoFilter network graph representation #592

Merged
merged 7 commits into from
Jun 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions autowiring/AutowiringDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
#pragma once
#include <string>
#include <vector>
#include <iostream>
#include <ostream>
#include <memory>

struct AutoFilterDescriptor;
class AutoPacket;
class CoreContext;

namespace autowiring {
namespace dbg {
Expand All @@ -21,9 +23,10 @@ bool IsLambda(const std::type_info& ti);
std::string ContextName(void);

/// <summary>
/// Write a string representation of the context hierarchy to 'os'
/// Write a string representation of the context hierarchy to 'os'(defaults to std::cout)
/// </summary>
void PrintContextTree(std::ostream& os = std::cout);
void PrintContextTree(void);
void PrintContextTree(std::ostream& os);

/// <returns>
/// The current packet under processing
Expand All @@ -48,6 +51,14 @@ std::string AutoFilterInfo(const char* name);
/// <param name="name">The name of the filter</param>
std::vector<std::string> ListRootDecorations(void);

/// <summary>
/// Write a DOT file representing the AutoFilter
/// </summary>
/// <param name="ctxt">Context of AutoFilter network to output. Defaults to AutoCurrentContext</param>
/// <param name="os">output stream to write DOT file</param>
void WriteAutoFilterGraph(std::ostream& os);
void WriteAutoFilterGraph(std::ostream& os, std::shared_ptr<CoreContext> ctxt);

/// <summary>
/// Initializes the Autowiring debug library
/// </summary>
Expand Down
88 changes: 87 additions & 1 deletion src/autowiring/AutowiringDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "stdafx.h"
#include "AutowiringDebug.h"
#include "Autowired.h"
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <sstream>
Expand Down Expand Up @@ -43,7 +44,8 @@ static std::string DemangleWithAutoID(const std::type_info& ti) {

if (retVal.compare(0, sizeof(prefix) - 1, prefix) == 0) {
size_t off = sizeof(prefix) - 1;
retVal = retVal.substr(off, retVal.length() - off - 2);
size_t end = retVal.find_last_not_of(' ', retVal.find_last_of('>') - 1);
retVal = retVal.substr(off, end - off + 1);
}
return retVal;
}
Expand Down Expand Up @@ -91,6 +93,10 @@ void autowiring::dbg::PrintContextTree(std::ostream& os) {
PrintContextTreeRecursive(os, AutoGlobalContext());
}

void autowiring::dbg::PrintContextTree(void) {
PrintContextTreeRecursive(std::cout, AutoGlobalContext());
}

AutoPacket* autowiring::dbg::CurrentPacket(void) {
Autowired<AutoPacketFactory> factory;
if (!factory)
Expand Down Expand Up @@ -193,6 +199,86 @@ std::vector<std::string> autowiring::dbg::ListRootDecorations(void) {
return retVal;
}

void autowiring::dbg::WriteAutoFilterGraph(std::ostream& os) {
WriteAutoFilterGraph(os, AutoCurrentContext());
}

void autowiring::dbg::WriteAutoFilterGraph(std::ostream& os, std::shared_ptr<CoreContext> ctxt) {
CurrentContextPusher pshr(ctxt);
Autowired<AutoPacketFactory> factory;

// Write opening and closing parts of file. Now, we only need to write edges
os << "digraph " << autowiring::demangle(ctxt->GetSigilType()) << " {" << std::endl;
auto exit = MakeAtExit([&os]{
os << "}" << std::endl;
});

// If no factory, this is an empty network
if (!factory) {
return;
}

// Obtain all descriptors:
const std::vector<AutoFilterDescriptor> descs = factory->GetAutoFilters();

std::unordered_map<std::string, int> decorations; // demangled name to ID
std::unordered_map<std::string, int> filters; // demangled name to ID

// give each node a unique id
int idCounter = 0;

for (const auto& desc : descs) {
std::string filter = autowiring::demangle(desc.GetType());

// Assign each filter an ID
if (filters.find(filter) == filters.end()) {
filters[filter] = idCounter++;
}

auto args = desc.GetAutoFilterArguments();
for (size_t i = 0; i < desc.GetArity(); i++) {
const AutoFilterArgument& arg = args[i];

std::string decoration = DemangleWithAutoID(*arg.ti);

// Assign each decoration and ID
if (decorations.find(decoration) == decorations.end()) {
decorations[decoration] = idCounter++;
}

// Add edge
if (arg.is_input) {
os << decorations[decoration] << " -> " << filters[filter];
} else {
os << filters[filter] << " -> " << decorations[decoration];
}

// Label time shifted edges
if (arg.tshift) {
os << " [style=dotted label=\"prev=" << arg.tshift << "\"]";
}

os << std::endl;
}
}

// Label each filter with its demangled name
for (const auto& filter : filters) {
const std::string& name = filter.first;
int id = filter.second;

os << id << " [shape=box label=\""<< name << "\"];" << std::endl;
}

// Label each decoration with its demangled name
for (const auto& decoration : decorations) {
const std::string& name = decoration.first;
int id = decoration.second;

os << id << " [shape=oval label=\""<< name << "\"];" << std::endl;
}
}

void autowiring::dbg::DebugInit(void) {

}
39 changes: 39 additions & 0 deletions src/autowiring/test/AutowiringDebugTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <autowiring/AutowiringDebug.h>
#include "TestFixtures/Decoration.hpp"
#include <algorithm>
#include <fstream>

class AutowiringDebugTest:
public testing::Test
Expand Down Expand Up @@ -86,3 +87,41 @@ TEST_F(AutowiringDebugTest, ContextPrintout) {

ASSERT_EQ(tree, output) << "Didn't print correct tree";
}

struct IntOutputer {
void AutoFilter(int& i) {
i = 4;
}
};

struct IntInFloatOut {
void AutoFilter(const int& i, float& f) {
f = static_cast<float>(i) + 3;
}
};

struct IntInFloatIn {
void AutoFilter(const int& i, const float& f) {}
};

TEST_F(AutowiringDebugTest, BasicAutoFilterGraph) {
AutoRequired<AutoPacketFactory> factory;
AutoRequired<IntOutputer> filter1;
AutoRequired<IntInFloatOut> filter2;
AutoRequired<IntInFloatIn> filter3;

*factory += [](auto_prev<float> in, std::string& out) {
out = "hello world";
};

*factory += [](double& out) { out = 3.0;};
*factory += [](double& out) { out = 4.0; };

*factory += [](const double* vals []){};

AutoCurrentContext()->Initiate();
auto packet = factory->NewPacket();

std::stringstream ss;
autowiring::dbg::WriteAutoFilterGraph(ss);
}