Skip to content

[Formal][Property Annotation] Annotate Reconvergent-paths using flow variables#716

Draft
Basmet0 wants to merge 7 commits intoEPFL-LAP:mainfrom
Basmet0:invariant-flow
Draft

[Formal][Property Annotation] Annotate Reconvergent-paths using flow variables#716
Basmet0 wants to merge 7 commits intoEPFL-LAP:mainfrom
Basmet0:invariant-flow

Conversation

@Basmet0
Copy link
Collaborator

@Basmet0 Basmet0 commented Jan 27, 2026

Each operation has local properties on how tokens are distributed between inputs and outputs. For example, a join operation expects the same number of tokens coming from each input, and sends them to its output. By extracting all of these local equations from a circuit, and then performing Gaussian elimination, one gets equations that describe properties of paths using only the internal states of the operations, rather than having to keep track of how many tokens are sent across each channel.

unsigned id;
};

void swapRows(boost::numeric::ublas::matrix<int> &m, size_t row1, size_t row2) {
Copy link
Member

Choose a reason for hiding this comment

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

unsigned id;
};

void swapRows(boost::numeric::ublas::matrix<int> &m, size_t row1, size_t row2) {
Copy link
Member

Choose a reason for hiding this comment

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

using MatIntType = boost::numeric::ublas::matrix<int>;

Copy link
Member

Choose a reason for hiding this comment

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

Maybe pull out the linear algebra stuff to dynamatic/Support/LinearAlgebra/Gaussian.h

}
}

void gaussianElimination(boost::numeric::ublas::matrix<int> &m) {
Copy link
Member

Choose a reason for hiding this comment

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

Add a bit more descriptions on this

https://en.wikipedia.org/wiki/Row_echelon_form

Comment on lines 328 to 332
// channel metadata
CPVar i1 = CPVar(llvm::formatv("#x1{0}", getUniqueName(&op)).str(),
VarType::INTEGER);
CPVar i2 = CPVar(llvm::formatv("#x2{0}", getUniqueName(&op)).str(),
VarType::INTEGER);
Copy link
Member

Choose a reason for hiding this comment

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

Here we should describe the model that we assume:

every unit is a cascade of: merge/join/mux -(internal_channel1)-> [slot]* -(internal_channel2)-> fork

Rename i1 -> lambda_internal_channel1

TYPE type;
Value channel;
Operation *op;
unsigned id;
Copy link
Member

Choose a reason for hiding this comment

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

add a constructor: FlowVariable(...)

Copy link
Member

Choose a reason for hiding this comment

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

Implement a separate DSL for writing flow equations

Add rationale for this:
Why don't we use CPVar from ConstraintProgramming.h:

  1. Integer coefficients (int16 maybe is good enough), but CPVar always uses double
  2. We can freely attach metadata type without confusing the users of ConstraintProgramming.h
  3. We don't need to encode anything in the name (we don't actually need a name because we don't need any external solvers for our equations).
  4. Dedicated conversion function to boost::...::matrix

struct FlowVarImpl {
std::shared_ptr<...> impl;
};

struct FlowVar {
std::shared_ptr<...> impl;
};

FlowEquation {

};

FlowExpression operator+(FlowExpression, FlowExpression);
FlowExpression operator-(FlowExpression, FlowExpression);
FlowExpression operator*(FlowExpression, FlowExpression);

}

LogicalResult
HandshakeAnnotatePropertiesPass::annotateReconvergentPathFlow(ModuleOp modOp) {
Copy link
Member

Choose a reason for hiding this comment

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

Split this function into multiple smaller ones:

  • createFlowVariables
  • addEquations
  • solveGaussian
  • ...

Bas Niekel added 2 commits January 29, 2026 14:23
@Jiahui17
Copy link
Member

Jiahui17 commented Feb 4, 2026

We could do a separate PR for class HandshakeOpInternalState

- <forkOp> fork1 -> { fork1.sent1, fork1.sent2, ... }
- fork1.sent2 -> { "it is a sent", "the second one" }
- parse
- print
- write smv

struct HandshakeOpInternalState {
  StringRef writeSmv() virtual = 0;
  /// This is the same as the "handshake.name" of the operation
  std::string name;
  static std::optional<HandshakeOpInternalState> parse() virtual = 0;
  Operation * getOperation(NameAnalysis& namer) {
    namer.findOepration(this->name)
  }
};


struct EagerForkSent : public HandshakeOpInternalState {
  Operation * op;
  unsigned outputId;
  StringRef writeSmv() override {

  }

  // Validate that there is an op with a matching name
  std::optional<HandshakeOpInternalState> parse(NameAnalysis& namer) override {
    

  }
};

if (auto state = EagerForkSent::parse(name)) {
  ...
} else if (auto state = BufferFull::parse(name)) {
  ...
} 

...


struct PathEquation {
std::vector<int> coefficients;
std::vector<std::string> names;
Copy link
Member

Choose a reason for hiding this comment

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

std::vector is better here

// FlowExpression, i.e. indices 0 to n-1 are used for n variables, while keeping
// lambda variables with low indices to ensure they are eliminated first within
// the row-echelon form
class IndexMap {
Copy link
Member

Choose a reason for hiding this comment

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

We could unify Matrix and its index management as a single struct

class -> struct because we are not hiding anything

Comment on lines +4 to +6
using MatIntZero = boost::numeric::ublas::zero_matrix<int>;
using MatIntType = boost::numeric::ublas::matrix<int>;
using MatIntRow = boost::numeric::ublas::matrix_row<MatIntType>;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add a link to some referneces

@Jiahui17 Jiahui17 marked this pull request as draft February 10, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants