add 2 unittests
Some checks failed
Validate Operations / validate-operations (push) Failing after 8m9s

fix bugs
This commit is contained in:
NiccoloN
2026-04-16 18:01:38 +02:00
parent 197c38f9ca
commit a903e30859
9 changed files with 336 additions and 58 deletions

View File

@@ -31,9 +31,7 @@ public:
bool isLinked() const { return owner_ != nullptr; }
Label getOrderLabel() const { return label; }
friend bool operator<(const LabeledListNode& lft, const LabeledListNode& rgt){
return lft.label < rgt.label;
}
friend bool operator<(const LabeledListNode& lft, const LabeledListNode& rgt) { return lft.label < rgt.label; }
private:
const void* owner_ = nullptr;
@@ -79,17 +77,17 @@ public:
auto it = node->getIterator();
if (it == list->nodes_.begin())
return nullptr;
return *std::prev(it);
return &*std::prev(it);
}
static const NodeT* previous(const NodeT* node) {
if (!node || !owner(node))
return nullptr;
const auto* list = owner(node);
auto it = node->getIterator();
auto it = const_cast<NodeT*>(node)->getIterator();
if (it == list->nodes_.begin())
return nullptr;
return *std::prev(it);
return &*std::prev(it);
}
static NodeT* next(NodeT* node) {
@@ -99,29 +97,29 @@ public:
auto it = std::next(node->getIterator());
if (it == list->nodes_.end())
return nullptr;
return *it;
return &*it;
}
static const NodeT* next(const NodeT* node) {
if (!node || !owner(node))
return nullptr;
const auto* list = owner(node);
auto it = std::next(node->getIterator());
auto it = std::next(const_cast<NodeT*>(node)->getIterator());
if (it == list->nodes_.end())
return nullptr;
return *it;
return &*it;
}
bool contains(const NodeT* node) const { return node && node->owner_ == this; }
Label getOrderLabel(const NodeT* node) const {
assert(contains(node) && "node must belong to this list");
return node->label_;
return node->label;
}
bool comesBefore(const NodeT* lhs, const NodeT* rhs) const {
assert(contains(lhs) && contains(rhs) && "nodes must belong to this list");
return lhs->label_ < rhs->label_;
return lhs->label < rhs->label;
}
void pushFront(NodeT* node) { insertBefore(front(), node); }
@@ -152,7 +150,7 @@ public:
assert(contains(node) && "node must belong to this list");
nodes_.remove(*node);
node->owner_ = nullptr;
node->label_ = 0;
node->label = 0;
--size_;
}
@@ -190,15 +188,14 @@ public:
}
Iterator begin() { return nodes_.begin(); }
Iterator end() { return nodes_.end(); }
RIterator rbegin() { return nodes_.rbegin(); }
RIterator rend() { return nodes_.rend(); }
private:
static const LabeledList* owner(const NodeT* node) { return node->owner_; }
static LabeledList* owner(NodeT* node) { return node->owner_; }
static const LabeledList* owner(const NodeT* node) { return static_cast<const LabeledList*>(node->owner_); }
static LabeledList* owner(NodeT* node) { return static_cast<LabeledList*>(const_cast<void*>(node->owner_)); }
static Label lowerLabel(const NodeT* node) { return node ? node->label : kLowerSentinel; }
static Label upperLabel(const NodeT* node) { return node ? node->label : kUpperSentinel; }

View File

@@ -28,12 +28,12 @@ void addPassesPim(OwningOpRef<ModuleOp>& module,
if (pimEmissionTarget >= EmitSpatial) {
pm.addPass(createONNXToSpatialPass());
pm.addPass(createMergeComputeNodesPass());
// pm.addPass(createCountInstructionPass());
pm.addPass(createMessagePass("Onnx lowered to Spatial"));
}
if (pimEmissionTarget >= EmitPim) {
pm.addPass(createMergeComputeNodesPass());
pm.addPass(createSpatialToPimPass());
// pm.addPass(createCountInstructionPass());
pm.addPass(createMessagePass("Spatial lowered to Pim"));

View File

@@ -47,6 +47,11 @@ int getTranferCost(TaskDCP* parent, TaskDCP* child) {
return child_position->second;
}
size_t GraphDCP::getNodeIndex(const TaskDCP* task) const {
assert(task >= nodes.data() && task < nodes.data() + nodes.size() && "task must belong to graph");
return static_cast<size_t>(task - nodes.data());
}
TaskInsertion GraphDCP::insertTaskInCPU(CPU cpu, TaskDCP* task, size_t position) {
TaskInsertion ret;
task->setCPU(cpu);
@@ -245,12 +250,12 @@ void GraphDCP::topologicalMoveAfter(TaskDCP* task, TaskDCP* pivotPoint) {
auto moveChildAfterMe = [this](TaskDCP* origTask) -> void {
auto cmp = [](Edge_t lft, Edge_t rgt) { return *rgt.first < *lft.first; };
TaskDCP* insertionPoint = origTask;
std::vector<Edge_t>& childEdges = origTask->childs;
std::vector<TaskDCP*> worklist;
worklist.push_back(origTask);
size_t i = 0;
while (i < worklist.size()) {
auto task = worklist[i];
std::vector<Edge_t>& childEdges = task->childs;
// build min heap Complexity 3N
std::make_heap(childEdges.begin(), childEdges.end(), cmp);
auto lastPoppedIter = childEdges.end();
@@ -279,12 +284,12 @@ void GraphDCP::topologicalMoveAfter(TaskDCP* task, TaskDCP* pivotPoint) {
}
};
if (!(*task < *pivotPoint)) {
if (!(*task < *pivotPoint))
return;
topologicalOrder.moveAfter(task, pivotPoint);
if (task->hasChilds())
moveChildAfterMe(task);
}
topologicalOrder.moveAfter(task, pivotPoint);
if (task->hasChilds())
moveChildAfterMe(task);
}
void GraphDCP::topologicalMoveBefore(TaskDCP* task, TaskDCP* pivotPoint) {
@@ -292,12 +297,12 @@ void GraphDCP::topologicalMoveBefore(TaskDCP* task, TaskDCP* pivotPoint) {
auto moveParentBeforeMe = [this](TaskDCP* origTask) -> void {
auto cmp = [](Edge_t lft, Edge_t rgt) { return *lft.first < *rgt.first; };
TaskDCP* insertionPoint = origTask;
std::vector<Edge_t>& parentEdges = origTask->parents;
std::vector<TaskDCP*> worklist;
worklist.push_back(origTask);
size_t i = 0;
while (i < worklist.size()) {
auto task = worklist[i];
std::vector<Edge_t>& parentEdges = task->parents;
// build max heap Complexity 3N
std::make_heap(parentEdges.begin(), parentEdges.end(), cmp);
auto lastPoppedIter = parentEdges.end();
@@ -326,14 +331,13 @@ void GraphDCP::topologicalMoveBefore(TaskDCP* task, TaskDCP* pivotPoint) {
}
};
if (!(*task < *pivotPoint)) {
if (!(*pivotPoint < *task))
return;
topologicalOrder.moveBefore(task, pivotPoint);
if (task->hasParents())
moveParentBeforeMe(task);
}
}
topologicalOrder.moveBefore(task, pivotPoint);
if (task->hasParents())
moveParentBeforeMe(task);
}
GraphDCP::FindSlot GraphDCP::findSlot(TaskDCP* candidate, CPU cpu, bool push) {
int aest_on_cpu = computeAEST(candidate, cpu);
@@ -407,7 +411,6 @@ GraphDCP::FindSlot GraphDCP::findSlot(TaskDCP* candidate, CPU cpu, bool push) {
}
void GraphDCP::selectProcessor(TaskDCP* candidate, bool push) {
std::vector<CPU> processors;
processors.reserve(lastCPU());
for (CPU c = push ? lastCPU() : lastCPU(); c >= 0; c--)
@@ -571,3 +574,15 @@ DCPAnalysisResult GraphDCP::getResult() {
return ret;
}
std::vector<GraphDCP::ScheduledTaskInfo> GraphDCP::getScheduledTasks(CPU cpu) const {
std::vector<ScheduledTaskInfo> scheduledTasks;
auto cpuIt = mapCPUTasks.find(cpu);
if (cpuIt == mapCPUTasks.end())
return scheduledTasks;
scheduledTasks.reserve(cpuIt->second.size());
for (auto* task : cpuIt->second)
scheduledTasks.push_back({getNodeIndex(task), task->getAEST(), task->getALST(), task->getWeight()});
return scheduledTasks;
}

View File

@@ -17,7 +17,15 @@ void removeEdge(TaskDCP* parent, TaskDCP* child);
int getTranferCost(TaskDCP* parent, TaskDCP* child);
class GraphDCP {
public:
struct ScheduledTaskInfo {
size_t nodeIndex;
int aest;
int alst;
int weight;
};
private:
struct FindSlot {
int aest;
int index;
@@ -35,21 +43,22 @@ class GraphDCP {
std::vector<TaskDCP*> getRoots();
long long getUniqueFlag() {return flag++;};
long long getUniqueFlag() { return flag++; }
void initAEST();
int initDCPL();
void initALST();
int computeAEST(TaskDCP* task, CPU cpu);
int computeDCPL(TaskDCP* task, CPU cpu);
int getDCPL() {return DCPL;};
int getDCPL() { return DCPL; }
void initTopological();
void topologicalMoveAfter(TaskDCP* task, TaskDCP * pivotPoint);
void topologicalMoveBefore(TaskDCP* task, TaskDCP * pivotPoint);
void topologicalMoveAfter(TaskDCP* task, TaskDCP* pivotPoint);
void topologicalMoveBefore(TaskDCP* task, TaskDCP* pivotPoint);
llvm::DenseMap<TaskDCP*, int> computeALST(TaskDCP* task, CPU cpu);
size_t getNodeIndex(const TaskDCP* task) const;
TaskDCP* findCandidate(std::vector<TaskDCP*> nodes);
void selectProcessor(TaskDCP* candidate, bool push);
@@ -60,21 +69,29 @@ class GraphDCP {
friend TaskInsertion;
public:
void DCP();
GraphDCP(llvm::ArrayRef<onnx_mlir::spatial::SpatWeightedCompute> spatWeightedComputes,
llvm::ArrayRef<EdgesIndex> edges)
: nodes(), mapCPUTasks() {
for (auto spatWeightedCompute : spatWeightedComputes){
for (auto spatWeightedCompute : spatWeightedComputes)
nodes.emplace_back(spatWeightedCompute);
}
for (auto [start, end, weight] : edges)
makeEdge(start, end, weight);
}
GraphDCP(llvm::ArrayRef<Weight_t> nodeWeights, llvm::ArrayRef<EdgesIndex> edges)
: nodes(), mapCPUTasks() {
nodes.reserve(nodeWeights.size());
for (auto [index, weight] : llvm::enumerate(nodeWeights))
nodes.emplace_back(index, weight);
for (auto [start, end, weight] : edges)
makeEdge(start, end, weight);
}
DCPAnalysisResult getResult();
std::vector<ScheduledTaskInfo> getScheduledTasks(CPU cpu) const;
CPU cpuCount() const { return last_cpu; }
void makeEdge(size_t parent_index, size_t child_index, Weight_t weight) {
addEdge(&nodes[parent_index], &nodes[child_index], weight);

View File

@@ -53,7 +53,7 @@ void TaskInsertion::rollBack() {
addEdge(double_edge.first.first, double_edge.second.first, double_edge.first.second);
}
if (afterNode.has_value()) {
auto double_edge = *beforeNode;
auto double_edge = *afterNode;
addEdge(double_edge.first.first, double_edge.second.first, double_edge.first.second);
}
graph->topologicalOrder.moveBefore( taskInserted,&*oldTopologicalPosition );

View File

@@ -1,9 +1,6 @@
#pragma once
#include <cassert>
#include <cstdint>
#include <iterator>
#include <list>
#include <optional>
#include <vector>
@@ -21,6 +18,7 @@ class TaskDCP : public onnx_mlir::LabeledListNode<TaskDCP> {
int weight;
int origWeight;
long long flag = 0;
int64_t syntheticId = -1;
std::optional<Edge_t> addChild(TaskDCP* child, Weight_t weight);
std::optional<Edge_t> addChild(TaskDCP& child, Weight_t weight) { return addChild(&child, weight); }
@@ -39,12 +37,27 @@ public:
std::vector<Edge_t> childs;
TaskDCP() = default;
TaskDCP(onnx_mlir::spatial::SpatWeightedCompute spatWeightedCompute)
: onnx_mlir::LabeledListNode<TaskDCP>(), spatWeightedCompute(spatWeightedCompute),
: onnx_mlir::LabeledListNode<TaskDCP>(),
spatWeightedCompute(spatWeightedCompute),
aest(0),
alst(0),
scheduledCPU(),
weight(getSpatWeightCompute(spatWeightedCompute)),
origWeight(weight),
syntheticId(-1),
parents(),
childs() {}
TaskDCP(int64_t id, int weight)
: onnx_mlir::LabeledListNode<TaskDCP>(),
spatWeightedCompute(),
aest(0),
alst(0),
scheduledCPU(),
weight(weight),
origWeight(weight),
flag(0),
syntheticId(id),
parents(),
childs() {}
@@ -54,35 +67,35 @@ public:
void setCPU(CPU cpu) { scheduledCPU = cpu; }
std::optional<CPU> getCPU() const { return scheduledCPU; }
void resetCPU() { scheduledCPU = std::nullopt; }
int getWeight() {
int getWeight() const {
if (isScheduled())
return weight;
else
return origWeight;
return origWeight;
}
void setWeight(int val) { weight = val; }
void resetWeight() { weight = origWeight; }
int computeWeight(GraphDCP* graph, CPU cpu);
bool hasParents() { return parents.size() != 0; }
bool hasChilds() { return childs.size() != 0; }
bool hasParents() const { return parents.size() != 0; }
bool hasChilds() const { return childs.size() != 0; }
int getAEST() { return aest; }
int getALST() { return alst; }
int getAEST() const { return aest; }
int getALST() const { return alst; }
void setAEST(int val) {
assert(val >= 0);
aest = val;
}
void setALST(int val) {
assert(val >= 0 && val >= aest);
alst = val;
}
void setALST(int val) { alst = val; }
bool hasDescendent(TaskDCP* child);
int64_t Id() const { return (int64_t) spatWeightedCompute.getAsOpaquePointer(); }
int64_t Id() const {
if (spatWeightedCompute)
return reinterpret_cast<int64_t>(spatWeightedCompute.getAsOpaquePointer());
return syntheticId;
}
bool isCP() const { return alst == aest; }
bool isScheduled() const { return scheduledCPU.has_value(); }
onnx_mlir::spatial::SpatWeightedCompute getSpatWeightedCompute() { return spatWeightedCompute; }
onnx_mlir::spatial::SpatWeightedCompute getSpatWeightedCompute() const { return spatWeightedCompute; }
void setFlag(long long val) { flag = val; }
long long getFlag() const { return flag; }
@@ -94,7 +107,6 @@ public:
friend int getTranferCost(TaskDCP* parent, TaskDCP* child);
};
struct TaskInsertion {
std::optional<DoubleEdge> beforeNode;
std::optional<DoubleEdge> afterNode;
@@ -103,5 +115,5 @@ struct TaskInsertion {
TaskDCP* taskInserted;
GraphDCP* graph;
void rollBack();
void rollBack();
};