Files
Raptor/test/PIM/SpatialSchedulingTargetTest.cpp
T
2026-08-06 14:32:57 +02:00

151 lines
5.7 KiB
C++

#include <cassert>
#include <cstdlib>
#include <string>
#include <vector>
#include "src/Accelerators/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.hpp"
#include "src/Accelerators/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.hpp"
using namespace onnx_mlir::spatial;
int main() {
TransferCost transfer {.fixed = 50, .networkFlits = 4};
SchedulingTarget fast;
fast.processorCount = 2;
fast.interProcessorLatencyNs = {0, 3, 3, 0};
fast.averageInterProcessorLatencyNs = 3;
SchedulingTarget slow = fast;
slow.interProcessorLatencyNs = {0, 10, 10, 0};
slow.averageInterProcessorLatencyNs = 10;
assert(getPeftTransferTime(transfer, 0, 0, fast) == 0);
assert(getPeftTransferTime(transfer, 0, 1, fast) == 62);
assert(getPeftTransferTime(transfer, 0, 1, slow) == 90);
assert(fast.getInterProcessorLatencyNs(0, 1) == 3);
assert(slow.getInterProcessorLatencyNs(0, 1) == 10);
SchedulingTarget line;
line.processorCount = 3;
line.interProcessorLatencyNs = {
0,
1,
10,
1,
0,
1,
10,
1,
0,
};
std::vector<Cost> logicalTrafficFlits(9, 0);
logicalTrafficFlits[2] = 100;
assert(mapLogicalProcessorsToPhysicalCores(logicalTrafficFlits, line) == std::vector<size_t>({1, 0, 2}));
SchedulingTarget alreadyPlaced = line;
alreadyPlaced.interProcessorLatencyNs = {
0,
10,
1,
10,
0,
1,
1,
1,
0,
};
assert(mapLogicalProcessorsToPhysicalCores(logicalTrafficFlits, alreadyPlaced) == std::vector<size_t>({0, 1, 2}));
ComputeGraph graph;
graph.successors.resize(6);
graph.predecessors.resize(6);
graph.successors[1].push_back({2, TransferCost {.fixed = 1, .networkFlits = 1}});
graph.predecessors[2].push_back({1, TransferCost {.fixed = 1, .networkFlits = 1}});
const Cost costs[] = {6, 4, 6, 4, 8, 8};
for (uint32_t task = 0; task < 6; ++task) {
ComputeInstance instance {nullptr, task, 1};
ResidentWeight weight;
weight.opaqueLane = task;
graph.nodes.push_back({instance, costs[task], {weight}, task});
graph.instanceToIndex[instance] = task;
}
MergeScheduleResult pipelineSchedule;
pipelineSchedule.processorCount = 2;
pipelineSchedule.dominanceOrderCompute.reserve(graph.nodes.size());
for (size_t task = 0; task < graph.nodes.size(); ++task) {
const ComputeInstance& instance = graph.nodes[task].instance;
pipelineSchedule.dominanceOrderCompute.push_back(instance);
size_t cpu = task < 4 ? 0 : 1;
pipelineSchedule.computeToCpuMap[instance] = cpu;
pipelineSchedule.computeToCpuSlotMap[instance] = task < 4 ? task : task - 4;
pipelineSchedule.computeToAestMap[instance] = task;
}
SchedulingTarget physical = fast;
physical.processorCount = 4;
physical.residentWeightCapacity = 2;
physical.interProcessorLatencyNs = {
0, 3, 3, 3,
3, 0, 3, 3,
3, 3, 0, 3,
3, 3, 3, 0,
};
std::string pipelineError;
assert(mlir::succeeded(applyPipelineScheduling(
graph, pipelineSchedule, 2, physical, pipelineError)));
assert(pipelineSchedule.processorCount == 4);
assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[0].instance) == 0);
assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[1].instance) == 0);
assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[2].instance) == 2);
assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[3].instance) == 2);
assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[4].instance) == 1);
assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[5].instance) == 3);
assert(pipelineSchedule.computeToAestMap.lookup(graph.nodes[2].instance)
>= pipelineSchedule.computeToAestMap.lookup(graph.nodes[1].instance)
+ graph.nodes[1].cost + 4);
assert(pipelineSchedule.equivalentClass.empty());
ComputeGraph communicationGraph;
communicationGraph.successors.resize(5);
communicationGraph.predecessors.resize(5);
communicationGraph.successors[4].push_back(
{3, TransferCost {.fixed = 0, .networkFlits = 1}});
communicationGraph.predecessors[3].push_back(
{4, TransferCost {.fixed = 0, .networkFlits = 1}});
const Cost communicationCosts[] = {6, 4, 6, 4, 1};
MergeScheduleResult communicationSchedule;
communicationSchedule.processorCount = 2;
for (uint32_t task = 0; task < 5; ++task) {
ComputeInstance instance {nullptr, task, 1};
ResidentWeight weight;
weight.opaqueLane = task;
communicationGraph.nodes.push_back(
{instance, communicationCosts[task], {weight}, task});
communicationGraph.instanceToIndex[instance] = task;
communicationSchedule.dominanceOrderCompute.push_back(instance);
size_t cpu = task < 4 ? 0 : 1;
communicationSchedule.computeToCpuMap[instance] = cpu;
communicationSchedule.computeToCpuSlotMap[instance] = task < 4 ? task : 0;
communicationSchedule.computeToAestMap[instance] = task;
}
SchedulingTarget fastPipeline = physical;
fastPipeline.residentWeightCapacity = 4;
MergeScheduleResult fastCommunicationSchedule = communicationSchedule;
assert(mlir::succeeded(applyPipelineScheduling(
communicationGraph, fastCommunicationSchedule, 2, fastPipeline, pipelineError)));
assert(fastCommunicationSchedule.computeToCpuMap.lookup(
communicationGraph.nodes[2].instance) == 2);
SchedulingTarget slowPipeline = fastPipeline;
slowPipeline.averageInterProcessorLatencyNs = 10;
MergeScheduleResult slowCommunicationSchedule = communicationSchedule;
assert(mlir::succeeded(applyPipelineScheduling(
communicationGraph, slowCommunicationSchedule, 2, slowPipeline, pipelineError)));
assert(slowCommunicationSchedule.computeToCpuMap.lookup(
communicationGraph.nodes[2].instance) < 2);
return EXIT_SUCCESS;
}