Skip to content
This repository has been archived by the owner on Jan 3, 2023. It is now read-only.

Make ngraph_bridge::Node members const where possible #69

Merged
merged 2 commits into from
Nov 7, 2017

Conversation

adstraw
Copy link
Contributor

@adstraw adstraw commented Nov 6, 2017

Refactor emitter tests according to above const change
Make ngraph_bridge::Node constructors protected
Use more explicit names for function arguments for readability
ngraph_graph.h and .cc clang-format Google

Refactor emitter tests according to above const change
Make ngraph_bridge::Node constructors protected
Use more explicit names for function arguments for readability
ngraph_graph.h and .cc clang-format Google
@@ -25,11 +25,11 @@ struct testEmitter : public Emitter {
NgraphNodePtr data1;
NgraphNodePtr data2;
NgraphNodePtr data3;
testEmitter() {
testEmitter(nnvmNodePtr n) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why add the nnvmNodePtr to the test constructor when it isn't used?

Copy link
Contributor

@mbrookhart mbrookhart Nov 6, 2017

Choose a reason for hiding this comment

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

Nevermind, found the usecase with Adam's help.

Copy link
Contributor Author

@adstraw adstraw left a comment

Choose a reason for hiding this comment

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

I ran clang-format on ngraph_graph.h and cc files so I annotated with comments to help navigate those diffs.

for (auto i : n->inputs_) {
if (i->name_ == "") i->name_ = randomString(6);
if (n->name_ == "") n->name_ = randomString(6);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ran clang-format on this file and most of the changes are due to clang-format (non-functional). So, adding some comments to draw attention to the functional changes.

@@ -250,7 +240,7 @@ void Graph::CollapseSubgraphs() {
// loop variable for undefined number of subgraphs
int i = 1;
while (true) {
auto tmpGraph = std::make_shared<Graph>();
auto tmpGraph = std::make_shared<Graph>("subgraph_" + std::to_string(i));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved Graph name creation to Graph construction time to allow const name

@@ -265,7 +255,6 @@ void Graph::CollapseSubgraphs() {
// set node name and shape based on last node in the subgraph
auto name = tmpGraph->nodes_.back()->name_;
auto shape = tmpGraph->nodes_.back()->shape_;
tmpGraph->name_ = "subgraph_" + name + "_" + randomString();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

... instead of setting on name inside the loop

@@ -42,17 +43,23 @@ using nnvmNodePtr = std::shared_ptr<nnvm::Node>;
using NodePtr = std::shared_ptr<Node>;

// Possible Types of nodes in Current Version
enum class NodeType {kVariable, kAux, kOp, kGraph};
enum class NodeType { kVariable, kAux, kOp, kGraph };
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A few changes in this file due to clang-format but mostly these are "real" changes

Copy link
Contributor

@ransford2011 ransford2011 left a comment

Choose a reason for hiding this comment

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

Overall looks good. Would like to hear your feedback on the comments I provided please.

Node(NodeType t, const nnvmNodePtr n, std::string s, std::vector<NodePtr> i)
: type_(t), orig_node_(n), name_(s), inputs_(i){};
protected:
Node(NodeType type, nnvmNodePtr node, const std::string& name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of the logic on line 54, couldn't you just give it a default parameter value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can, but if I do I would likely want to have a default parameter for the inputs_ argument as well. This would mean collapsing to a single ctor per class. I have mixed feelings about this. What do other people think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the default value for the inputs in the first constructor is just an empty vector, I think it would be okay to create 1 constructor.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you change the ordering, you would not. Let's not dwell on it though. Having conditional within the initializer lists does slow down construction though.

};

// Node for storing operations
class OpNode : public Node {
public:
// Include operation in graphviz
std::string createNodeLabel() {
std::string createNodeLabel() override {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this needs to be virtual as well. I could be wrong here, but I will double check.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. I double-checked. This needs to be virtual

Copy link
Contributor Author

Choose a reason for hiding this comment

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

virtual and override are mutually exclusive, per my understanding. virtual => the function can be overridden by a child class. override => the function is overriding a virtual function from the parent class. please send your documentation. Here's mine:

http://en.cppreference.com/w/cpp/language/override

Note that B::foo() is not marked virtual.

Copy link
Contributor

Choose a reason for hiding this comment

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

@adstraw kinda.. if I remember correctly override is complementary to virtual. It's a hint to a compiler that you actually want to override a virtual method. If you make a mistake and use it on a non-virtual method the compiler will get upset. You don't have to use override on a virtual method you would like to override but it's considered a good practice.

Copy link
Contributor

Choose a reason for hiding this comment

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

My documentation is in the form of slides and is called Information Hiding. You can find the explanation in Effective C++. I will concede to your documentation for now as it seems to be fine. I like en.cppreference.com.

Copy link
Contributor

@ransford2011 ransford2011 Nov 6, 2017

Choose a reason for hiding this comment

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

@Krovatkin That is the way I understand it as well. Non-virtual functions are binded statically to objects. Thus I'm not sure if the proper function will be called. A unit test would resolve this debate 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

@ransford2011 it should do the right thing AFAIK. override is kinda "superset" of virtual in a sense it adds virtual to the declaration to which override was applied to and it also checks that the method in a base class is indeed virtual so it can be overridden. I'm used to a combo of virtual/override I didn't realize the standard also allows me to just use override.

As usual, C++ takes a neat idea and makes it confusing. In c# if you use override and virtual the compiler will complain, so there's just one way in which override is allowed to be used.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ransford2011 @adstraw

#include <iostream>

struct A {
	virtual void v() { std::cout << "A::v" << std::endl; };
	void m() { std::cout << "A::m" << std::endl; };
};

struct B : public A {
	virtual void v() override { std::cout << "B::v" << std::endl; };
	//void m() override {}; ERROR : overrides non-virtual method
	virtual void m() { std::cout << "B::m" << std::endl;  }; //probably doesn't do what a user wanted
};

struct C : public A {
	void v() override { std::cout << "C::v" << std::endl; };
};


int main() {

	A* a = new A();
	A* b = new B();
	A* c = new C();

	a->v(); //A::v
	b->v(); //B::v
	c->v(); //C::v

	a->m(); //A::m
	b->m(); //A::m oopsie
	return 0;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

😆 . Thanks for running that small experiment. As @adstraw has shown from his reference, the behavior is as intended. That's good for me to know as I can save some keystrokes from typing virtual all the time. Thanks again!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ransford you didn't delete a,b,c in your code. Memory leak! Could you please fix that??? :)

Seriously though... Thanks for following up!

@adstraw
Copy link
Contributor Author

adstraw commented Nov 6, 2017

hold off on merge. I missed a unit test failure ngraph_graph.graph_init. will take care of that now.

@adstraw
Copy link
Contributor Author

adstraw commented Nov 6, 2017

fixed test issue... can't check for empty string when using default Graph ctor now that the name is randomized.

@mbrookhart mbrookhart merged commit eb2b00f into ngraph-integration-dev Nov 7, 2017
@mbrookhart mbrookhart deleted the adstraw/node-graph-refactor branch November 7, 2017 00:18
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants