Skip to content

Add method for removing redundant nodes#571

Open
arcondello wants to merge 27 commits into
dwavesystems:mainfrom
arcondello:feature/node-equality-and-successor-transfer
Open

Add method for removing redundant nodes#571
arcondello wants to merge 27 commits into
dwavesystems:mainfrom
arcondello:feature/node-equality-and-successor-transfer

Conversation

@arcondello

Copy link
Copy Markdown
Member

Closes #563

AI Generation Disclosure

No AI used.

@arcondello arcondello added the enhancement New feature or request label Jun 24, 2026
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch 2 times, most recently from 4dab596 to a8040b8 Compare June 24, 2026 18:09
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from a8040b8 to 82cc356 Compare June 24, 2026 18:14
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 56195c1 to 57638a8 Compare June 24, 2026 18:18
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 39fb39d to 055fe62 Compare July 2, 2026 17:35
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from ee71c02 to 770a9cb Compare July 3, 2026 17:05
Comment thread dwave/optimization/include/dwave-optimization/nodes/binaryop.hpp
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 261d2d6 to 98e4bd0 Compare July 3, 2026 18:09
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 98e4bd0 to 47e1be7 Compare July 3, 2026 18:14
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 90386b6 to cd107a0 Compare July 6, 2026 16:43
virtual bool equal_to(const Derived& rhs) const = 0;
};

/// Overload for EqualityMixin that does not require a class-specific equal_to()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

A doubt I have is whether these two overloads are different enough that they should actually be given different names 🤔

@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 42a0edd to f7a75d1 Compare July 8, 2026 17:33
Comment thread dwave/optimization/src/nodes/lp.cpp Outdated
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 4e887e4 to f643bca Compare July 9, 2026 22:40
@arcondello arcondello marked this pull request as ready for review July 10, 2026 17:45
@arcondello

arcondello commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

As a note: I didn't try to be inclusive about the asserts in the replace_predecessor_() method. That way lies madness so I just went with some sanity checks.

Comment thread tests/cpp/test_graph.cpp Outdated
@arcondello arcondello requested a review from fastbodin July 10, 2026 18:27
@arcondello arcondello force-pushed the feature/node-equality-and-successor-transfer branch from 212caf4 to d0dd3d3 Compare July 10, 2026 19:05

@fastbodin fastbodin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Managed to work through all files excluding the test files. Thought I would upload these comments before moving onto them.

>>> model = Model()
...
>>> x = model.integer(5)
...

@fastbodin fastbodin Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: I find that the ... do not add much to the example. Additionally, most of the other examples do not include .... Am I missing something?

Comment thread dwave/optimization/src/graph.cpp
Comment thread dwave/optimization/src/graph.cpp
if (not dropped(uptr)) continue;

// Remove the node from its predecessor's successor vectors.
// This very leaves the node in an invalid state, very briefly

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// This very leaves the node in an invalid state, very briefly
// This leaves the node in an invalid state, very briefly

Comment thread dwave/optimization/include/dwave-optimization/nodes/binaryop.hpp
Comment on lines +378 to +379

index -= 1;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

    // If we haven't found the Array* we want to replace, then "normalize"
    // the index so that it looks like it would if `initial_` wasn't an array.

Comment thread dwave/optimization/src/nodes/linear_algebra.cpp
assert(array_ptr != nullptr);
assert(std::ranges::equal(array_ptrs_[index]->shape(), array_ptr->shape()));

assert(0 <= index and static_cast<size_t>(index) < array_ptrs_.size());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: Totally fine as-is but could replace with

    assert(0 <= index and index) < static_cast<ssize_t>(array_ptrs_.size()));

to avoid size_t. 🤷

void NaryOpNode<BinaryOp>::replace_predecessor_(ssize_t index, Node* node_ptr) {
Node::replace_predecessor_(index, node_ptr);

assert(0 <= index and static_cast<size_t>(index) < operands_.size());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

See Nits above regarding size_t. Fine with it as is.

bool UnaryOpNode<UnaryOp>::equal_to(const Node& rhs) const {
const auto* rhs_ptr = dynamic_cast<const UnaryOpNode*>(&rhs);
if (rhs_ptr == nullptr) return false; // not same type so not equal
return this->equal_to(*rhs_ptr);

@fastbodin fastbodin Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Confirming that I am not sleeping at the wheel. I had to do a double take here 😆

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Probably should change 190 to

const UnaryOpNode* rhs_ptr = dynamic_cast<const UnaryOpNode*>(&rhs);

to make it a little clearer what's happening.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Usually I am fine with auto here, but, in this case, that would actually be helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add methods to support the removal of redundant nodes

2 participants