Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e61d3d4

Browse files
committed
Track numSlack variables separately from numOmegaCoefs
numSlack are the independent solution constraints
1 parent ae4bfae commit e61d3d4

File tree

2 files changed

+45
-28
lines changed

2 files changed

+45
-28
lines changed

include/LoopBlock.hpp

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,13 @@ class LinearProgramLoopBlock {
308308
// earlier level.
309309
// Vector<bool, 256> doNotAddEdge;
310310
// Vector<bool, 256> scheduled;
311-
[[no_unique_address]] size_t numPhiCoefs{0};
312-
[[no_unique_address]] size_t numOmegaCoefs{0};
313-
[[no_unique_address]] size_t numLambda{0};
314-
[[no_unique_address]] size_t numBounding{0};
315-
[[no_unique_address]] size_t numConstraints{0};
316-
[[no_unique_address]] size_t numActiveEdges{0};
311+
[[no_unique_address]] unsigned numPhiCoefs{0};
312+
[[no_unique_address]] unsigned numOmegaCoefs{0};
313+
[[no_unique_address]] unsigned numSlack{0};
314+
[[no_unique_address]] unsigned numLambda{0};
315+
[[no_unique_address]] unsigned numBounding{0};
316+
[[no_unique_address]] unsigned numConstraints{0};
317+
[[no_unique_address]] unsigned numActiveEdges{0};
317318

318319
public:
319320
using BitSet = ::MemoryAccess::BitSet;
@@ -812,11 +813,14 @@ class LinearProgramLoopBlock {
812813
// C, lambdas, omegas, Phis
813814
numOmegaCoefs = 0;
814815
numPhiCoefs = 0;
816+
numSlack = 0;
815817
for (auto &&node : nodes) {
816818
// note, we had d > node.getNumLoops() for omegas earlier; why?
817819
if ((d >= node.getNumLoops()) || (!hasActiveEdges(g, node, d))) continue;
818-
if (!node.phiIsScheduled(d))
820+
if (!node.phiIsScheduled(d)) {
819821
numPhiCoefs = node.updatePhiOffset(numPhiCoefs);
822+
++numSlack;
823+
}
820824
numOmegaCoefs = node.updateOmegaOffset(numOmegaCoefs);
821825
}
822826
}
@@ -825,25 +829,38 @@ class LinearProgramLoopBlock {
825829
for (auto edge : edges) edge.validate();
826830
}
827831
#endif
828-
// the plan is to generally avoid instantiating the omni-simplex
829-
// first, we solve individual problems
832+
/// For now, we instantiate a dense simplex specifying the full problem.
833+
///
834+
/// Eventually, the plan is to generally avoid instantiating the omni-simplex
835+
/// first, we solve individual problems
836+
///
837+
/// The order of variables in the simplex is:
838+
/// C, lambdas, slack, omegas, Phis, w, u
839+
/// where
840+
/// C: constraints, rest of matrix * variables == C
841+
/// lambdas: farkas multipliers
842+
/// slack: slack variables from independent phi solution constraints
843+
/// omegas: scheduling offsets
844+
/// Phis: scheduling rotations
845+
/// w: bounding offsets, independent of symbolic variables
846+
/// u: bounding offsets, dependent on symbolic variables
830847
auto instantiateOmniSimplex(const Graph &g, size_t d, bool satisfyDeps)
831848
-> Optional<Simplex *> {
832849
auto omniSimplex =
833-
Simplex::create(allocator, numConstraints + numOmegaCoefs,
850+
Simplex::create(allocator, numConstraints + numSlack,
834851
1 + numBounding + numActiveEdges + numPhiCoefs +
835-
2 * numOmegaCoefs + numLambda);
852+
numOmegaCoefs + numSlack + numLambda);
836853
auto C{omniSimplex->getConstraints()};
837854
C << 0;
838855
// layout of omniSimplex:
839856
// Order: C, then rev-priority to minimize
840-
// C, lambdas, omegas, Phis, w, u
857+
// C, lambdas, slack, omegas, Phis, w, u
841858
// rows give constraints; each edge gets its own
842859
// numBounding = num u
843860
// numActiveEdges = num w
844861
Row c = 0;
845-
Col l = 1, o = 1 + numLambda, p = o + numOmegaCoefs, w = p + numPhiCoefs,
846-
u = w + numActiveEdges;
862+
Col l = 1, o = 1 + numLambda + numSlack, p = o + numOmegaCoefs,
863+
w = p + numPhiCoefs, u = w + numActiveEdges;
847864
for (size_t e = 0; e < edges.size(); ++e) {
848865
Dependence &edge = edges[e];
849866
if (g.isInactive(e, d)) continue;
@@ -985,7 +1002,7 @@ class LinearProgramLoopBlock {
9851002
-> std::optional<BitSet> {
9861003
auto omniSimplex = instantiateOmniSimplex(g, depth, satisfyDeps);
9871004
if (!omniSimplex) return {};
988-
auto sol = omniSimplex->rLexMinStop(numLambda);
1005+
auto sol = omniSimplex->rLexMinStop(numLambda + numSlack);
9891006
updateSchedules(g, depth, sol);
9901007
return deactivateSatisfiedEdges(g, depth,
9911008
sol[_(numPhiCoefs + numOmegaCoefs, end)]);
@@ -1077,39 +1094,39 @@ class LinearProgramLoopBlock {
10771094
return 0;
10781095
}
10791096
void addIndependentSolutionConstraints(NotNull<Simplex> omniSimplex,
1080-
const Graph &g, size_t depth) {
1097+
const Graph &g, size_t d) {
10811098
// omniSimplex->setNumCons(omniSimplex->getNumCons() +
10821099
// memory.size());
10831100
// omniSimplex->reserveExtraRows(memory.size());
10841101
auto C{omniSimplex->getConstraints()};
1085-
size_t i = size_t{C.numRow()} - numOmegaCoefs;
1086-
size_t o = 1 + numLambda + numOmegaCoefs;
1087-
if (depth == 0) {
1102+
size_t i = size_t{C.numRow()} - numSlack, s = numLambda,
1103+
o = 1 + numSlack + numLambda + numOmegaCoefs;
1104+
if (d == 0) {
10881105
// add ones >= 0
10891106
for (auto &&node : nodes) {
1090-
if (node.phiIsScheduled(depth) || (!hasActiveEdges(g, node))) continue;
1107+
if (node.phiIsScheduled(d) || (!hasActiveEdges(g, node, d))) continue;
10911108
C(i, 0) = 1;
10921109
C(i, node.getPhiOffsetRange() + o) << 1;
1093-
C(i++, last) = -1; // for >=
1110+
C(i++, ++s) = -1; // for >=
10941111
}
10951112
} else {
10961113
DenseMatrix<int64_t> A, N;
10971114
for (auto &&node : nodes) {
1098-
if (node.phiIsScheduled(depth) || (depth >= node.getNumLoops()) ||
1099-
(!hasActiveEdges(g, node)))
1115+
if (node.phiIsScheduled(d) || (d >= node.getNumLoops()) ||
1116+
(!hasActiveEdges(g, node, d)))
11001117
continue;
1101-
A.resizeForOverwrite(Row{size_t(node.getPhi().numCol())}, Col{depth});
1102-
A << node.getPhi()(_(0, depth), _).transpose();
1118+
A.resizeForOverwrite(Row{size_t(node.getPhi().numCol())}, Col{d});
1119+
A << node.getPhi()(_(0, d), _).transpose();
11031120
NormalForm::nullSpace11(N, A);
11041121
C(i, 0) = 1;
11051122
MutPtrVector<int64_t> cc{C(i, node.getPhiOffsetRange() + o)};
11061123
// sum(N,dims=1) >= 1 after flipping row signs to be lex > 0
11071124
for (size_t m = 0; m < N.numRow(); ++m)
11081125
cc += N(m, _) * lexSign(N(m, _));
1109-
C(i++, last) = -1; // for >=
1126+
C(i++, ++s) = -1; // for >=
11101127
}
11111128
}
1112-
omniSimplex->truncateConstraints(i);
1129+
assert(omniSimplex->getNumCons() == i);
11131130
assert(!allZero(omniSimplex->getConstraints()(last, _)));
11141131
}
11151132
[[nodiscard]] static auto nonZeroMask(const AbstractVector auto &x)

include/Math/MatrixDimensions.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct StridedDims {
6666
}
6767
friend inline auto operator<<(llvm::raw_ostream &os, StridedDims x)
6868
-> llvm::raw_ostream & {
69-
return os << x.M << " x " << x.N << "(stride " << x.strideM << ")";
69+
return os << x.M << " x " << x.N << " (stride " << x.strideM << ")";
7070
}
7171
};
7272
/// Dimensions with a capacity

0 commit comments

Comments
 (0)