[Formal][Property Annotation] Annotate Reconvergent-paths using flow variables#716
[Formal][Property Annotation] Annotate Reconvergent-paths using flow variables#716Basmet0 wants to merge 7 commits intoEPFL-LAP:mainfrom
Conversation
…e invariant in hopes of allowing nuXmv to prove them with 1-induction
| unsigned id; | ||
| }; | ||
|
|
||
| void swapRows(boost::numeric::ublas::matrix<int> &m, size_t row1, size_t row2) { |
There was a problem hiding this comment.
APIs for accessing rows/cols
https://www.boost.org/doc/libs/latest/libs/numeric/ublas/doc/matrix_proxy.html
| unsigned id; | ||
| }; | ||
|
|
||
| void swapRows(boost::numeric::ublas::matrix<int> &m, size_t row1, size_t row2) { |
There was a problem hiding this comment.
using MatIntType = boost::numeric::ublas::matrix<int>;
There was a problem hiding this comment.
Maybe pull out the linear algebra stuff to dynamatic/Support/LinearAlgebra/Gaussian.h
| } | ||
| } | ||
|
|
||
| void gaussianElimination(boost::numeric::ublas::matrix<int> &m) { |
There was a problem hiding this comment.
Add a bit more descriptions on this
| // 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); |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
add a constructor: FlowVariable(...)
There was a problem hiding this comment.
Implement a separate DSL for writing flow equations
Add rationale for this:
Why don't we use CPVar from ConstraintProgramming.h:
- Integer coefficients (int16 maybe is good enough), but CPVar always uses double
- We can freely attach metadata type without confusing the users of ConstraintProgramming.h
- 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).
- 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) { |
There was a problem hiding this comment.
Split this function into multiple smaller ones:
- createFlowVariables
- addEquations
- solveGaussian
- ...
separation of function into smaller steps
|
We could do a separate PR for class HandshakeOpInternalState |
|
|
||
| struct PathEquation { | ||
| std::vector<int> coefficients; | ||
| std::vector<std::string> names; |
| // 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 { |
There was a problem hiding this comment.
We could unify Matrix and its index management as a single struct
class -> struct because we are not hiding anything
| using MatIntZero = boost::numeric::ublas::zero_matrix<int>; | ||
| using MatIntType = boost::numeric::ublas::matrix<int>; | ||
| using MatIntRow = boost::numeric::ublas::matrix_row<MatIntType>; |
There was a problem hiding this comment.
Maybe add a link to some referneces
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.