add ablation study
Validate Operations / validate-operations (push) Has been cancelled

normalize names and artifact paths
This commit is contained in:
NiccoloN
2026-08-20 17:58:02 +02:00
parent add20e56eb
commit b009e1ff08
67 changed files with 1573 additions and 993 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ struct ResolvedContiguousAddress {
};
/// Records compile-time facts used when interpreting address arithmetic and
/// loop-carried aliases inside PIM regions.
/// loop-carried aliases inside Pim regions.
struct StaticValueKnowledge {
llvm::DenseMap<mlir::Value, int64_t> indexValues;
llvm::DenseMap<mlir::Value, mlir::Value> aliases;
+4 -4
View File
@@ -85,12 +85,12 @@ static mlir::LogicalResult walkPimCoreBlockImpl(mlir::Block& block,
auto step = resolveIndexValue(forOp.getStep(), knowledge);
if (failed(lower) || failed(upper) || failed(step)
|| (mode == CoreWalkMode::ExecuteCommunication && *step <= 0)) {
forOp.emitOpError() << "requires statically evaluable scf.for bounds for PIM " << purpose;
forOp.emitOpError() << "requires statically evaluable scf.for bounds for Pim " << purpose;
hasFailure = true;
continue;
}
if (*step <= 0) {
forOp.emitOpError("requires positive scf.for step for PIM verification");
forOp.emitOpError("requires positive scf.for step for Pim verification");
hasFailure = true;
continue;
}
@@ -126,7 +126,7 @@ static mlir::LogicalResult walkPimCoreBlockImpl(mlir::Block& block,
if (auto ifOp = mlir::dyn_cast<mlir::scf::IfOp>(op)) {
auto condition = resolveIndexValue(ifOp.getCondition(), knowledge);
if (failed(condition)) {
ifOp.emitOpError() << "requires statically evaluable scf.if condition for PIM " << purpose;
ifOp.emitOpError() << "requires statically evaluable scf.if condition for Pim " << purpose;
hasFailure = true;
continue;
}
@@ -147,7 +147,7 @@ static mlir::LogicalResult walkPimCoreBlockImpl(mlir::Block& block,
if (auto switchOp = mlir::dyn_cast<mlir::scf::IndexSwitchOp>(op)) {
auto selector = resolveIndexValue(switchOp.getArg(), knowledge);
if (failed(selector)) {
switchOp.emitOpError() << "requires a statically evaluable scf.index_switch selector for PIM " << purpose;
switchOp.emitOpError() << "requires a statically evaluable scf.index_switch selector for Pim " << purpose;
hasFailure = true;
continue;
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace onnx_mlir {
using PimCoreCommunicationPlan = llvm::DenseMap<mlir::Block*, llvm::SmallVector<mlir::Operation*, 8>>;
/// Returns true for ops in a `pim.core` body that only participate in static
/// address or index computation and therefore do not emit PIM instructions.
/// address or index computation and therefore do not emit Pim instructions.
bool isCoreStaticAddressOp(mlir::Operation* op);
/// Walks a `pim.core` body's communication stream, statically unrolling
+2 -2
View File
@@ -9,7 +9,7 @@ llvm::FailureOr<mlir::func::FuncOp> getPimEntryFunc(mlir::ModuleOp moduleOp) {
llvm::SmallVector<mlir::ONNXEntryPointOp> entryPoints(moduleOp.getOps<mlir::ONNXEntryPointOp>());
if (entryPoints.size() > 1) {
moduleOp.emitError("PIM pipeline requires a single ONNX entry point, but found ") << entryPoints.size();
moduleOp.emitError("Pim pipeline requires a single ONNX entry point, but found ") << entryPoints.size();
return mlir::failure();
}
if (!entryPoints.empty()) {
@@ -38,7 +38,7 @@ llvm::FailureOr<mlir::func::FuncOp> getPimEntryFunc(mlir::ModuleOp moduleOp) {
if (nonExternalFuncs.size() == 1)
return nonExternalFuncs.front();
moduleOp.emitError("could not resolve a unique PIM entry function");
moduleOp.emitError("could not resolve a unique Pim entry function");
return mlir::failure();
}
+1 -1
View File
@@ -5,7 +5,7 @@
namespace onnx_mlir {
/// Resolves the function the PIM pipeline should treat as its entry point.
/// Resolves the function the Pim pipeline should treat as its entry point.
/// Prefers ONNX entry-point metadata, then `main_graph`, then the only
/// non-external function if the module is otherwise unambiguous.
llvm::FailureOr<mlir::func::FuncOp> getPimEntryFunc(mlir::ModuleOp moduleOp);
+1 -1
View File
@@ -32,7 +32,7 @@ struct ResolvedWeightView {
bool hasWeightAlways(mlir::Operation* op);
/// Tags an op as producing a value that should stay materialized as a reusable
/// weight across later PIM lowering/codegen stages.
/// weight across later Pim lowering/codegen stages.
void markWeightAlways(mlir::Operation* op);
bool isSpatialMvmVmmWeightUse(mlir::OpOperand& use);
+8 -8
View File
@@ -11,7 +11,7 @@ namespace onnx_mlir::pim {
namespace {
static void emitCrashMessage(llvm::StringRef fieldName, llvm::StringRef message) {
llvm::errs() << "PIM " << fieldName << " " << message << "\n";
llvm::errs() << "Pim " << fieldName << " " << message << "\n";
}
template <typename To, typename From>
@@ -65,7 +65,7 @@ InFlightDiagnostic emitCheckedArithmeticError(Operation* anchor, llvm::StringRef
}
InFlightDiagnostic emitCheckedArithmeticError(Location loc, llvm::StringRef fieldName, llvm::StringRef message) {
return emitError(loc) << "PIM " << fieldName << " " << message;
return emitError(loc) << "Pim " << fieldName << " " << message;
}
FailureOr<int32_t> checkedI32(int64_t value, Operation* anchor, llvm::StringRef fieldName) {
@@ -174,7 +174,7 @@ FailureOr<uint64_t> getCheckedShapedTypeSizeInBytes(ShapedType type, Location lo
int32_t checkedI32OrCrash(int64_t value, llvm::StringRef fieldName) {
if (value < std::numeric_limits<int32_t>::min() || value > std::numeric_limits<int32_t>::max()) {
emitCrashMessage(fieldName, "is outside representable range");
llvm_unreachable("PIM checked arithmetic failure");
llvm_unreachable("Pim checked arithmetic failure");
}
return static_cast<int32_t>(value);
}
@@ -182,7 +182,7 @@ int32_t checkedI32OrCrash(int64_t value, llvm::StringRef fieldName) {
int32_t checkedI32OrCrash(uint64_t value, llvm::StringRef fieldName) {
if (value > static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
emitCrashMessage(fieldName, "is outside representable range");
llvm_unreachable("PIM checked arithmetic failure");
llvm_unreachable("Pim checked arithmetic failure");
}
return static_cast<int32_t>(value);
}
@@ -190,7 +190,7 @@ int32_t checkedI32OrCrash(uint64_t value, llvm::StringRef fieldName) {
uint8_t checkedU8OrCrash(uint64_t value, llvm::StringRef fieldName) {
if (value > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max())) {
emitCrashMessage(fieldName, "is outside representable range");
llvm_unreachable("PIM checked arithmetic failure");
llvm_unreachable("Pim checked arithmetic failure");
}
return static_cast<uint8_t>(value);
}
@@ -198,7 +198,7 @@ uint8_t checkedU8OrCrash(uint64_t value, llvm::StringRef fieldName) {
size_t checkedSizeOrCrash(int64_t value, llvm::StringRef fieldName) {
if (value < 0) {
emitCrashMessage(fieldName, "is outside representable range");
llvm_unreachable("PIM checked arithmetic failure");
llvm_unreachable("Pim checked arithmetic failure");
}
return static_cast<size_t>(value);
}
@@ -206,7 +206,7 @@ size_t checkedSizeOrCrash(int64_t value, llvm::StringRef fieldName) {
size_t checkedAddOrCrash(size_t lhs, size_t rhs, llvm::StringRef fieldName) {
if (rhs > std::numeric_limits<size_t>::max() - lhs) {
emitCrashMessage(fieldName, "addition overflow");
llvm_unreachable("PIM checked arithmetic failure");
llvm_unreachable("Pim checked arithmetic failure");
}
return lhs + rhs;
}
@@ -214,7 +214,7 @@ size_t checkedAddOrCrash(size_t lhs, size_t rhs, llvm::StringRef fieldName) {
size_t checkedMulOrCrash(size_t lhs, size_t rhs, llvm::StringRef fieldName) {
if (lhs != 0 && rhs > std::numeric_limits<size_t>::max() / lhs) {
emitCrashMessage(fieldName, "multiplication overflow");
llvm_unreachable("PIM checked arithmetic failure");
llvm_unreachable("Pim checked arithmetic failure");
}
return lhs * rhs;
}
+1 -1
View File
@@ -4,7 +4,7 @@
namespace onnx_mlir {
/// Returns the directory that should hold PIM artifacts/debug dumps for the
/// Returns the directory that should hold Pim artifacts/debug dumps for the
/// current compiler invocation.
std::string getOutputDir();
+3 -3
View File
@@ -171,19 +171,19 @@ inline Opcode opcodeFromString(llvm::StringRef opName) {
for (auto [index, name] : llvm::enumerate(kOpcodeNames))
if (opName == name)
return static_cast<Opcode>(index);
llvm_unreachable("Unsupported PIM binary opcode");
llvm_unreachable("Unsupported Pim binary opcode");
}
inline llvm::StringRef opcodeToString(Opcode opcode) {
size_t index = static_cast<size_t>(opcode);
assert(index < kOpcodeNames.size() && "Unsupported PIM binary opcode");
assert(index < kOpcodeNames.size() && "Unsupported Pim binary opcode");
return kOpcodeNames[index];
}
inline InstructionRecord makeInstructionRecord(const llvm::json::Object& instruction) {
InstructionRecord record;
std::optional<llvm::StringRef> opName = instruction.getString("op");
assert(opName && "Missing op field in PIM instruction");
assert(opName && "Missing op field in Pim instruction");
record.opcode = opcodeFromString(*opName);
const auto& format = kInstructionJsonFormats[static_cast<size_t>(record.opcode)];
if (format.rd)
+19 -15
View File
@@ -125,7 +125,7 @@ static bool isZeroSplatGlobal(mlir::Value value) {
return false;
}
// PIM instruction immediates are serialized as signed int32_t fields today
// Pim instruction immediates are serialized as signed int32_t fields today
// (`sldi` goes through checkedI32OrCrash), so local addresses must stay within
// the non-negative int32_t range.
static FailureOr<size_t> checkedAlignTo(size_t value, size_t alignment, Operation* anchor, StringRef fieldName) {
@@ -141,7 +141,7 @@ static void printMemoryOverflowDiagnostic(const MemoryValueKey& key,
size_t requestedSize,
size_t currentFirstAvailableAddress,
size_t alignedEndAddress) {
llvm::errs() << "PIM local memory allocation overflow\n";
llvm::errs() << "Pim local memory allocation overflow\n";
llvm::errs() << "Requested allocation size: " << requestedSize << " bytes\n";
llvm::errs() << "Current firstAvailableAddress: " << currentFirstAvailableAddress << "\n";
llvm::errs() << "Aligned end address: " << alignedEndAddress << "\n";
@@ -187,7 +187,7 @@ size_t PimMemory::allocateAddress(size_t size, const MemoryValueKey& key) {
size,
firstAvailableAddress,
succeeded(checkedAlignedEnd) ? *checkedAlignedEnd : kPimLocalMemoryAddressLimit);
llvm_unreachable("PIM local memory allocation overflow");
llvm_unreachable("Pim local memory allocation overflow");
}
firstAvailableAddress = *checkedAlignedEnd;
return address;
@@ -276,7 +276,7 @@ void PimMemory::allocateCore(const CompiledCoreMemoryPlan& plan, std::optional<u
}
else if (*localArenaSize != plan.arenaSize || reportRow.logicalLocalAllocationCount != plan.logicalAllocationCount
|| reportRow.logicalLocalBytes != plan.logicalBytes)
llvm_unreachable("inconsistent PIM local-memory plan across core-batch lanes");
llvm_unreachable("inconsistent Pim local-memory plan across core-batch lanes");
for (const CompiledLocalMemoryEntry& entry : plan.entries) {
MemoryValueKey key = getMemoryValueKey(entry.value, lane);
ownedMemEntriesMap[key] = entry.memory;
@@ -352,8 +352,8 @@ size_t PimAcceleratorMemory::getValueAddress(mlir::Value value,
llvm_unreachable("Missing mem entry");
}
size_t byteOffset = pim::checkedSizeOrCrash(resolvedAddress->byteOffset, "resolved PIM byte offset");
return pim::checkedAddOrCrash(iter->second.address, byteOffset, "resolved PIM address");
size_t byteOffset = pim::checkedSizeOrCrash(resolvedAddress->byteOffset, "resolved Pim byte offset");
return pim::checkedAddOrCrash(iter->second.address, byteOffset, "resolved Pim address");
}
llvm::FailureOr<int64_t> PimAcceleratorMemory::getIndexValue(mlir::Value value,
@@ -706,6 +706,8 @@ void PimCodeGen::codeGenSendOp(pim::PimSendOp sendOp, const StaticValueKnowledge
void PimCodeGen::codeGenWaitOp(
pim::PimWaitOp waitOp, const StaticValueKnowledge& knowledge) const {
if (pimDisableSynchronization)
return;
auto eventRegister = indexOf(waitOp.getEventRegister(), knowledge);
auto waitValue = indexOf(waitOp.getWaitValue(), knowledge);
assert(succeeded(eventRegister) && succeeded(waitValue)
@@ -722,6 +724,8 @@ void PimCodeGen::codeGenWaitOp(
void PimCodeGen::codeGenSyncOp(
pim::PimSyncOp syncOp, const StaticValueKnowledge& knowledge) const {
if (pimDisableSynchronization)
return;
auto targetCoreId = indexOf(syncOp.getTargetCoreId(), knowledge);
auto eventRegister = indexOf(syncOp.getEventRegister(), knowledge);
assert(succeeded(targetCoreId) && succeeded(eventRegister)
@@ -958,7 +962,7 @@ static LogicalResult executeCompiledCorePlan(
auto step = node.step.evaluate(knowledge);
auto forOp = cast<mlir::scf::ForOp>(node.op);
if (failed(lowerBound) || failed(upperBound) || failed(step) || *step <= 0) {
forOp.emitOpError("requires statically evaluable scf.for bounds for PIM codegen");
forOp.emitOpError("requires statically evaluable scf.for bounds for Pim codegen");
return failure();
}
@@ -984,7 +988,7 @@ static LogicalResult executeCompiledCorePlan(
auto condition = node.condition.evaluate(knowledge);
auto ifOp = cast<mlir::scf::IfOp>(node.op);
if (failed(condition)) {
ifOp.emitOpError("requires statically evaluable scf.if condition for PIM codegen");
ifOp.emitOpError("requires statically evaluable scf.if condition for Pim codegen");
return failure();
}
@@ -998,7 +1002,7 @@ static LogicalResult executeCompiledCorePlan(
auto selector = node.condition.evaluate(knowledge);
auto switchOp = cast<mlir::scf::IndexSwitchOp>(node.op);
if (failed(selector)) {
switchOp.emitOpError("requires a statically evaluable scf.index_switch selector for PIM codegen");
switchOp.emitOpError("requires a statically evaluable scf.index_switch selector for Pim codegen");
return failure();
}
const llvm::SmallVectorImpl<CompiledCoreNode>* selectedBody = node.defaultBody.get();
@@ -1184,12 +1188,12 @@ OnnxMlirCompilerErrorCodes onnx_mlir::compileToPimCode(ModuleOp& moduleOp, std::
}
auto getCompiledProgram = [&](Operation* op) {
auto it = compiledPrograms.find(op);
assert(it != compiledPrograms.end() && "missing compiled PIM core program");
assert(it != compiledPrograms.end() && "missing compiled Pim core program");
return it->second.get();
};
auto getMemoryPlan = [&](Operation* op) {
auto it = memoryPlans.find(op);
assert(it != memoryPlans.end() && "missing PIM core memory plan");
assert(it != memoryPlans.end() && "missing Pim core memory plan");
return it->second.get();
};
@@ -1267,7 +1271,7 @@ OnnxMlirCompilerErrorCodes onnx_mlir::compileToPimCode(ModuleOp& moduleOp, std::
if (failed(weightView)) {
std::string message;
llvm::raw_string_ostream os(message);
os << "requires a statically resolvable dense global weight view during PIM codegen; weight="
os << "requires a statically resolvable dense global weight view during Pim codegen; weight="
<< vmmOp.getWeight() << " type=" << vmmOp.getWeight().getType();
result.recordDiagnostic(vmmOp, os.str());
return failure();
@@ -1275,7 +1279,7 @@ OnnxMlirCompilerErrorCodes onnx_mlir::compileToPimCode(ModuleOp& moduleOp, std::
if (weightView->shape.size() != 2) {
std::string message;
llvm::raw_string_ostream os(message);
os << "requires a rank-2 matrix weight view during PIM codegen; resolved shape=[";
os << "requires a rank-2 matrix weight view during Pim codegen; resolved shape=[";
llvm::interleaveComma(weightView->shape, os);
os << "] weight=" << vmmOp.getWeight() << " type=" << vmmOp.getWeight().getType();
result.recordDiagnostic(vmmOp, os.str());
@@ -1387,7 +1391,7 @@ OnnxMlirCompilerErrorCodes onnx_mlir::compileToPimCode(ModuleOp& moduleOp, std::
}
if (diagnostics.hasFailure())
diagnostics.emitSuppressedSummary(summaryAnchor ? summaryAnchor : moduleOp.getOperation(),
"PIM codegen diagnostic(s)");
"Pim codegen diagnostic(s)");
for (size_t jobIndex = 0; jobIndex < jobs.size(); ++jobIndex)
if (jobResults[jobIndex].status != CompilerSuccess)
@@ -1453,7 +1457,7 @@ OnnxMlirCompilerErrorCodes onnx_mlir::compileToPimCode(ModuleOp& moduleOp, std::
if (!batchPerCoreRow)
batchPerCoreRow = result.reportRow;
else if (!(*batchPerCoreRow == result.reportRow))
llvm_unreachable("one PIM core batch produced inconsistent per-core memory reports");
llvm_unreachable("one Pim core batch produced inconsistent per-core memory reports");
}
uint64_t batchReportId = jobs[group.front()].batchReportId.value_or(0);
+51 -32
View File
@@ -9,25 +9,25 @@
namespace onnx_mlir {
llvm::cl::opt<PimEmissionTargetType> pimEmissionTarget(
llvm::cl::desc("[Optional] Choose PIM-related target to emit (once selected it will cancel the other targets):"),
llvm::cl::values(clEnumVal(EmitSpatial, "Lower model to spatial IR")),
llvm::cl::values(clEnumVal(EmitPim, "Lower model to PIM IR")),
llvm::cl::values(clEnumVal(EmitPimBufferized, "Lower model to PIM IR and bufferize it")),
llvm::cl::values(clEnumVal(EmitPimCodegen, "Lower model to PIM IR and generate code for PIM")),
llvm::cl::desc("[Optional] Choose Pim-related target to emit (once selected it will cancel the other targets):"),
llvm::cl::values(clEnumVal(EmitSpatial, "Lower model to Spatial IR")),
llvm::cl::values(clEnumVal(EmitPim, "Lower model to Pim IR")),
llvm::cl::values(clEnumVal(EmitPimBufferized, "Lower model to Pim IR and bufferize it")),
llvm::cl::values(clEnumVal(EmitPimCodegen, "Lower model to Pim IR and generate code for Pim")),
llvm::cl::init(EmitPimCodegen),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<PimMemoryReportLevel> pimMemoryReport(
"pim-memory-report",
llvm::cl::desc("Emit a human-readable PIM memory planning report"),
llvm::cl::values(clEnumValN(PimMemoryReportNone, "none", "Do not emit any PIM memory planning report")),
llvm::cl::values(clEnumValN(PimMemoryReportSummary, "summary", "Emit a concise PIM memory summary")),
llvm::cl::desc("Emit a human-readable Pim memory planning report"),
llvm::cl::values(clEnumValN(PimMemoryReportNone, "none", "Do not emit any Pim memory planning report")),
llvm::cl::values(clEnumValN(PimMemoryReportSummary, "summary", "Emit a concise Pim memory summary")),
llvm::cl::init(PimMemoryReportSummary),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<PimConvLoweringType> pimConvLowering(
"pim-conv-lowering",
llvm::cl::desc("Convolution lowering strategy for PIM"),
llvm::cl::desc("Convolution lowering strategy for Pim"),
llvm::cl::values(clEnumValN(PimConvLoweringAuto, "auto", "Select the Conv lowering strategy automatically")),
llvm::cl::values(clEnumValN(PimConvLoweringLegacy, "legacy", "Use the legacy explicit-im2col Conv lowering")),
llvm::cl::values(clEnumValN(PimConvLoweringDepthwise, "depthwise", "Force the depthwise-specialized Conv lowering")),
@@ -55,20 +55,20 @@ llvm::cl::opt<PimSpatialDataflowExportType> pimExportSpatialDataflow(
llvm::cl::desc("Emit Gephi-importable CSV dataflow reports for Spatial pipeline snapshots"),
llvm::cl::values(clEnumValN(SpatialDataflowExportNone, "none", "Do not emit Spatial dataflow CSV reports")),
llvm::cl::values(
clEnumValN(SpatialDataflowExportSpatial1, "spatial1", "Emit spatial1 graph dataflow CSV reports")),
clEnumValN(SpatialDataflowExportSpatial1, "spatial1", "Emit Spatial1 graph dataflow CSV reports")),
llvm::cl::values(
clEnumValN(SpatialDataflowExportSpatial2, "spatial2", "Emit spatial2 trivially merged graph dataflow CSV reports")),
clEnumValN(SpatialDataflowExportSpatial2, "spatial2", "Emit Spatial2 trivially merged graph dataflow CSV reports")),
llvm::cl::values(
clEnumValN(SpatialDataflowExportSpatial3, "spatial3", "Emit spatial3 scheduled dataflow CSV reports")),
clEnumValN(SpatialDataflowExportSpatial3, "spatial3", "Emit Spatial3 scheduled dataflow CSV reports")),
llvm::cl::values(
clEnumValN(SpatialDataflowExportSpatial4, "spatial4", "Emit spatial4 realized dataflow CSV reports")),
clEnumValN(SpatialDataflowExportSpatial4, "spatial4", "Emit Spatial4 realized dataflow CSV reports")),
llvm::cl::values(clEnumValN(SpatialDataflowExportAll, "all", "Emit all Spatial dataflow CSV reports")),
llvm::cl::init(SpatialDataflowExportNone),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<bool>
pimOnlyCodegen("pim-only-codegen",
llvm::cl::desc("Only generate code for PIM (assume input is already in bufferized PIM IR)"),
llvm::cl::desc("Only generate code for Pim (assume input is already in bufferized Pim IR)"),
llvm::cl::init(false),
llvm::cl::cat(OnnxMlirOptions));
@@ -96,21 +96,37 @@ llvm::cl::opt<bool> pimEmitJson("pim-emit-json",
llvm::cl::opt<bool> pimDetectCommunicationDeadlock(
"pim-detect-communication-deadlock",
llvm::cl::desc("Expensively simulate the statically expanded PIM send/receive order at verification time and fail if a blocking communication deadlock is found"),
llvm::cl::desc("Expensively simulate the statically expanded Pim send/receive order at verification time and fail if a blocking communication deadlock is found"),
llvm::cl::init(false),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<bool> pimVerifyBufferizationCopyFreedom(
"pim-verify-bufferization-copy-freedom",
llvm::cl::desc("Run the expensive official PIM tensor-copy freedom proof before bufferization"),
llvm::cl::desc("Run the expensive official Pim tensor-copy freedom proof before bufferization"),
llvm::cl::init(false),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<bool> pimDisableSynchronization(
"pim-disable-synchronization",
llvm::cl::desc("Omit Pim wait/sync instructions from generated code for performance ablation"),
llvm::cl::init(false),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<bool> pimDisableSpatialPlanning(
"pim-disable-spatial-planning",
llvm::cl::desc("Select the trivial Spatial layout plan for performance ablation"),
llvm::cl::init(false),
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<size_t>
crossbarSize("crossbar-size", llvm::cl::desc("Width and height of a single crossbar"), llvm::cl::init(128));
crossbarSize("crossbar-size",
llvm::cl::desc("Width and height of a single crossbar (required for Pim compilation)"),
llvm::cl::init(0));
llvm::cl::opt<size_t>
crossbarCountInCore("crossbar-count", llvm::cl::desc("Number of crossbars in each core"), llvm::cl::init(64));
crossbarCountInCore("crossbar-count",
llvm::cl::desc("Number of crossbars in each core (required for Pim compilation)"),
llvm::cl::init(0));
llvm::cl::opt<size_t> pipelineStages(
"pipeline",
@@ -119,32 +135,35 @@ llvm::cl::opt<size_t> pipelineStages(
llvm::cl::cat(OnnxMlirOptions));
llvm::cl::opt<long> coresCount("core-count",
llvm::cl::desc("Number of cores in the chip. Required for PIM compilation."),
llvm::cl::desc("Number of cores in the chip. Required for Pim compilation."),
llvm::cl::init(-1));
llvm::cl::opt<std::string> pimTargetConfig(
"pim-target-config",
llvm::cl::desc("PIM target configuration used to construct the Spatial scheduling cost model"),
llvm::cl::desc("Pim target configuration used to construct the Spatial scheduling cost model"),
llvm::cl::init(""),
llvm::cl::cat(OnnxMlirOptions));
bool hasExplicitPimCoreCount() { return coresCount.getNumOccurrences() != 0; }
void verifyExplicitPimCoreCount() {
if (!hasExplicitPimCoreCount())
llvm::report_fatal_error("PIM compilation requires an explicit --core-count=<positive integer>");
void verifyPimCompilerOptions() {
if (coresCount.getNumOccurrences() == 0)
llvm::report_fatal_error("Pim compilation requires an explicit --core-count=<positive integer>");
if (coresCount.getValue() <= 0)
llvm::report_fatal_error("PIM compilation requires --core-count to be a positive integer");
}
void verifyPimPipelineStages() {
llvm::report_fatal_error("Pim compilation requires --core-count to be a positive integer");
if (crossbarSize.getNumOccurrences() == 0)
llvm::report_fatal_error("Pim compilation requires an explicit --crossbar-size=<positive integer>");
if (crossbarSize.getValue() == 0)
llvm::report_fatal_error("Pim compilation requires --crossbar-size to be a positive integer");
if (crossbarCountInCore.getNumOccurrences() == 0)
llvm::report_fatal_error("Pim compilation requires an explicit --crossbar-count=<positive integer>");
if (crossbarCountInCore.getValue() == 0)
llvm::report_fatal_error("Pim compilation requires --crossbar-count to be a positive integer");
if (pipelineStages.getValue() == 0)
llvm::report_fatal_error("PIM compilation requires --pipeline to be positive");
llvm::report_fatal_error("Pim compilation requires --pipeline to be positive");
if (static_cast<size_t>(coresCount.getValue()) < pipelineStages.getValue())
llvm::report_fatal_error("PIM compilation requires --pipeline not to exceed --core-count");
llvm::report_fatal_error("Pim compilation requires --pipeline not to exceed --core-count");
if (crossbarCountInCore.getValue()
> std::numeric_limits<size_t>::max() / pipelineStages.getValue())
llvm::report_fatal_error("PIM compilation --crossbar-count * --pipeline overflows");
llvm::report_fatal_error("Pim compilation --crossbar-count * --pipeline overflows");
}
} // namespace onnx_mlir
+3 -3
View File
@@ -59,6 +59,8 @@ extern llvm::cl::opt<bool> pimEmitJson;
extern llvm::cl::opt<bool> pimReportConvLowering;
extern llvm::cl::opt<bool> pimDetectCommunicationDeadlock;
extern llvm::cl::opt<bool> pimVerifyBufferizationCopyFreedom;
extern llvm::cl::opt<bool> pimDisableSynchronization;
extern llvm::cl::opt<bool> pimDisableSpatialPlanning;
extern llvm::cl::opt<size_t> crossbarSize;
extern llvm::cl::opt<size_t> crossbarCountInCore;
@@ -68,8 +70,6 @@ extern llvm::cl::opt<std::string> pimTargetConfig;
extern llvm::cl::opt<uint64_t> pimConvIm2colMaxElements;
extern llvm::cl::opt<uint64_t> pimConvStreamChunkPositions;
bool hasExplicitPimCoreCount();
void verifyExplicitPimCoreCount();
void verifyPimPipelineStages();
void verifyPimCompilerOptions();
} // namespace onnx_mlir
+21 -21
View File
@@ -97,7 +97,7 @@ spatial::ConvLoweringStrategy getSpatialConvLoweringStrategy(PimConvLoweringType
case PimConvLoweringInputKTiled: return spatial::ConvLoweringStrategy::InputKTiled;
case PimConvLoweringTiled2D: return spatial::ConvLoweringStrategy::Tiled2D;
}
llvm_unreachable("unknown PIM Conv lowering strategy");
llvm_unreachable("unknown Pim Conv lowering strategy");
}
spatial::SpatialDataflowExportStage getPimSpatialDataflowExportStage(
@@ -110,7 +110,7 @@ spatial::SpatialDataflowExportStage getPimSpatialDataflowExportStage(
case SpatialDataflowExportSpatial4: return spatial::SpatialDataflowExportStage::Spatial4;
case SpatialDataflowExportAll: return spatial::SpatialDataflowExportStage::All;
}
llvm_unreachable("unknown PIM Spatial dataflow export stage");
llvm_unreachable("unknown Pim Spatial dataflow export stage");
}
spatial::SpatialTargetResources getPimSpatialTargetResources(const spatial::SchedulingTarget& target) {
@@ -120,7 +120,7 @@ spatial::SpatialTargetResources getPimSpatialTargetResources(const spatial::Sche
resources.processorCount = target.processorCount;
resources.vectorWidth = target.vectorWidth;
if (failed(resources.verify()))
llvm::report_fatal_error("PIM target resources are incomplete");
llvm::report_fatal_error("Pim target resources are incomplete");
return resources;
}
@@ -138,7 +138,7 @@ const llvm::json::Object& requireObject(const llvm::json::Object& object,
llvm::StringRef path) {
const llvm::json::Object* nested = object.getObject(key);
if (!nested)
llvm::report_fatal_error("PIM target config is missing object '" + path + "." + key + "'");
llvm::report_fatal_error("Pim target config is missing object '" + path + "." + key + "'");
return *nested;
}
@@ -151,7 +151,7 @@ Cost getConfigCost(const llvm::json::Object& object,
return fallback;
if (!std::isfinite(*number) || *number < 0.0 || (!allowZero && *number == 0.0)
|| *number > static_cast<double>(std::numeric_limits<Cost>::max()))
llvm::report_fatal_error("PIM target config field '" + key + "' must be a valid positive number");
llvm::report_fatal_error("Pim target config field '" + key + "' must be a valid positive number");
return static_cast<Cost>(std::ceil(*number));
}
@@ -159,11 +159,11 @@ std::pair<size_t, size_t> getConfigPair(const llvm::json::Object& object,
llvm::StringRef key) {
const llvm::json::Array* values = object.getArray(key);
if (!values || values->size() != 2)
llvm::report_fatal_error("PIM target config field '" + key + "' must contain two integers");
llvm::report_fatal_error("Pim target config field '" + key + "' must contain two integers");
std::optional<int64_t> first = (*values)[0].getAsInteger();
std::optional<int64_t> second = (*values)[1].getAsInteger();
if (!first || !second || *first <= 0 || *second <= 0)
llvm::report_fatal_error("PIM target config field '" + key + "' must contain two positive integers");
llvm::report_fatal_error("Pim target config field '" + key + "' must contain two positive integers");
return {static_cast<size_t>(*first), static_cast<size_t>(*second)};
}
@@ -174,7 +174,7 @@ void loadPimInterProcessorLatencies(
network.getString("net_config_file_path");
if (!filename)
llvm::report_fatal_error(
"PIM target config is missing network latency file path");
"Pim target config is missing network latency file path");
llvm::SmallString<256> networkPath(*filename);
if (!llvm::sys::path::is_absolute(networkPath)) {
@@ -187,19 +187,19 @@ void loadPimInterProcessorLatencies(
auto buffer = llvm::MemoryBuffer::getFile(networkPath);
if (!buffer)
llvm::report_fatal_error(
llvm::Twine("failed to read PIM network config '")
llvm::Twine("failed to read Pim network config '")
+ networkPath + "': " + buffer.getError().message());
auto parsed = llvm::json::parse(buffer.get()->getBuffer());
if (!parsed)
llvm::report_fatal_error(
llvm::Twine("failed to parse PIM network config '")
llvm::Twine("failed to parse Pim network config '")
+ networkPath + "': " + llvm::toString(parsed.takeError()));
const llvm::json::Object* root = parsed->getAsObject();
const llvm::json::Object* latencies =
root ? root->getObject("latency") : nullptr;
if (!latencies)
llvm::report_fatal_error(
"PIM network config is missing its latency matrix");
"Pim network config is missing its latency matrix");
target.interProcessorLatencyNs.assign(
target.processorCount * target.processorCount, 0);
@@ -210,7 +210,7 @@ void loadPimInterProcessorLatencies(
const llvm::json::Object* row = latencies->getObject(sourceKey);
if (!row)
llvm::report_fatal_error(
llvm::Twine("PIM network config is missing latency row ")
llvm::Twine("Pim network config is missing latency row ")
+ sourceKey);
for (size_t destination = 0;
destination < target.processorCount; ++destination) {
@@ -220,7 +220,7 @@ void loadPimInterProcessorLatencies(
std::optional<double> latency = row->getNumber(destinationKey);
if (!latency || !std::isfinite(*latency) || *latency <= 0.0)
llvm::report_fatal_error(
llvm::Twine("PIM network config is missing latency ")
llvm::Twine("Pim network config is missing latency ")
+ sourceKey + " -> " + destinationKey);
Cost roundedLatency = static_cast<Cost>(std::ceil(*latency));
target.interProcessorLatencyNs[
@@ -244,17 +244,17 @@ spatial::SchedulingTarget getPimSchedulingTarget() {
auto buffer = llvm::MemoryBuffer::getFile(pimTargetConfig);
if (!buffer)
llvm::report_fatal_error(
llvm::Twine("failed to read PIM target config '")
llvm::Twine("failed to read Pim target config '")
+ pimTargetConfig.getValue() + "': " + buffer.getError().message());
auto parsed = llvm::json::parse(buffer.get()->getBuffer());
if (!parsed)
llvm::report_fatal_error(
llvm::Twine("failed to parse PIM target config '")
llvm::Twine("failed to parse Pim target config '")
+ pimTargetConfig.getValue() + "': "
+ llvm::toString(parsed.takeError()));
const llvm::json::Object* root = parsed->getAsObject();
if (!root)
llvm::report_fatal_error("PIM target config must contain a JSON object");
llvm::report_fatal_error("Pim target config must contain a JSON object");
const llvm::json::Object& chip = requireObject(*root, "chip_config", "root");
const llvm::json::Object& core = requireObject(chip, "core_config", "chip_config");
@@ -267,7 +267,7 @@ spatial::SchedulingTarget getPimSchedulingTarget() {
std::optional<int64_t> coreCount = chip.getInteger("core_cnt");
if (!coreCount || *coreCount <= 0)
llvm::report_fatal_error("PIM target config field 'core_cnt' must be a positive integer");
llvm::report_fatal_error("Pim target config field 'core_cnt' must be a positive integer");
target.processorCount = static_cast<size_t>(*coreCount);
target.residentWeightCapacity =
getConfigCost(matrix, "xbar_array_count", target.residentWeightCapacity);
@@ -278,7 +278,7 @@ spatial::SchedulingTarget getPimSchedulingTarget() {
|| target.residentWeightCapacity != crossbarCountInCore.getValue()
|| target.matrixRows != crossbarSize.getValue()
|| target.matrixColumns != crossbarSize.getValue())
llvm::report_fatal_error("PIM target config resources do not match --core-count, "
llvm::report_fatal_error("Pim target config resources do not match --core-count, "
"--crossbar-count, and --crossbar-size");
loadPimInterProcessorLatencies(target, network);
@@ -331,8 +331,7 @@ void addPassesPim(OwningOpRef<ModuleOp>& module,
PassManager& pm,
EmissionTargetType& emissionTarget,
std::string outputNameNoExt) {
verifyExplicitPimCoreCount();
verifyPimPipelineStages();
verifyPimCompilerOptions();
spatial::SchedulingTarget schedulingTarget = getPimSchedulingTarget();
spatial::SpatialTargetResources targetResources = getPimSpatialTargetResources(schedulingTarget);
@@ -352,7 +351,8 @@ void addPassesPim(OwningOpRef<ModuleOp>& module,
spatial::SpatialDataflowExportStage exportStage =
getPimSpatialDataflowExportStage(pimExportSpatialDataflow.getValue());
pm.addPass(createONNXToSpatialPass(targetResources, planningOptions));
pm.addPass(createSpatialLayoutPlanningPass(targetResources));
pm.addPass(createSpatialLayoutPlanningPass(
targetResources, pimDisableSpatialPlanning.getValue()));
pm.addPass(createLowerSpatialPlansPass(targetResources, planningOptions, exportStage));
pm.addPass(createTrivialGraphComputeMergePass(
schedulingTarget.residentWeightCapacity, exportStage));
+3 -3
View File
@@ -46,7 +46,7 @@ static LogicalResult compileCoreEmissionPlan(Block& block, SmallVectorImpl<Compi
auto upper = compileIndexExpr(forOp.getUpperBound());
auto step = compileIndexExpr(forOp.getStep());
if (failed(lower) || failed(upper) || failed(step)) {
forOp.emitOpError("requires statically evaluable scf.for bounds for PIM codegen");
forOp.emitOpError("requires statically evaluable scf.for bounds for Pim codegen");
return failure();
}
CompiledCoreNode node;
@@ -63,7 +63,7 @@ static LogicalResult compileCoreEmissionPlan(Block& block, SmallVectorImpl<Compi
if (auto ifOp = dyn_cast<scf::IfOp>(op)) {
auto condition = compileIndexExpr(ifOp.getCondition());
if (failed(condition)) {
ifOp.emitOpError("requires statically evaluable scf.if condition for PIM codegen");
ifOp.emitOpError("requires statically evaluable scf.if condition for Pim codegen");
return failure();
}
CompiledCoreNode node;
@@ -82,7 +82,7 @@ static LogicalResult compileCoreEmissionPlan(Block& block, SmallVectorImpl<Compi
if (auto switchOp = dyn_cast<scf::IndexSwitchOp>(op)) {
auto selector = compileIndexExpr(switchOp.getArg());
if (failed(selector)) {
switchOp.emitOpError("requires a statically evaluable scf.index_switch selector for PIM codegen");
switchOp.emitOpError("requires a statically evaluable scf.index_switch selector for Pim codegen");
return failure();
}
CompiledCoreNode node;
@@ -249,7 +249,7 @@ auto createEmptySpatGraphComputeBatch(RewriterT& rewriter,
if (laneCount <= 0 || laneCount > std::numeric_limits<int32_t>::max())
return mlir::FailureOr<spatial::SpatGraphComputeBatch>(mlir::failure());
auto laneCountAttr = pim::getCheckedI32Attr(rewriter, loc, laneCount, "spatial compute_batch lane count");
auto laneCountAttr = pim::getCheckedI32Attr(rewriter, loc, laneCount, "Spatial compute_batch lane count");
if (mlir::failed(laneCountAttr))
return mlir::FailureOr<spatial::SpatGraphComputeBatch>(mlir::failure());
@@ -25,7 +25,7 @@ llvm::SmallVector<mlir::Value> sliceVector(const mlir::Value& vectorToSlice,
mlir::Location loc);
/// Partitions one logical vector into per-core crossbar-sized slices using the
/// current PIM target geometry.
/// current Pim target geometry.
llvm::DenseMap<CoreId, llvm::SmallVector<mlir::Value>> sliceVectorPerCrossbarPerCore(
const mlir::Value& vectorToSlice,
mlir::PatternRewriter& rewriter,
@@ -46,7 +46,7 @@ struct LowerSpatialPlansPass final
}
auto entryFunc = getPimEntryFunc(moduleOp);
if (failed(entryFunc)) {
moduleOp.emitError("failed to locate the PIM entry function during LowerSpatialPlans");
moduleOp.emitError("failed to locate the Pim entry function during LowerSpatialPlans");
signalPassFailure();
return;
}
@@ -158,7 +158,7 @@ void ONNXToSpatialPass::runOnOperation() {
auto entryFunc = getPimEntryFunc(moduleOp);
if (failed(entryFunc)) {
moduleOp.emitError("failed to locate the PIM entry function during ONNX-to-Spatial lowering");
moduleOp.emitError("failed to locate the Pim entry function during ONNX-to-Spatial lowering");
signalPassFailure();
return;
}
@@ -245,7 +245,7 @@ void ONNXToSpatialPass::runOnOperation() {
RewritePatternSet postPatterns(ctx);
populatePostPatterns(postPatterns, ctx);
if (failed(applyPartialConversion(*entryFunc, postTarget, std::move(postPatterns)))) {
moduleOp.emitError("failed to normalize weight-like Spatial compute operands before Spatial-to-PIM lowering");
moduleOp.emitError("failed to normalize weight-like Spatial compute operands before Spatial-to-Pim lowering");
signalPassFailure();
return;
}
@@ -42,8 +42,9 @@ static SmallVector<spatial::PhysicalLayout> getOperandLayouts(
class SpatialLayoutAnalysis {
public:
SpatialLayoutAnalysis(func::FuncOp funcOp,
const spatial::SpatialTargetResources& target)
: funcOp(funcOp), target(target) {}
const spatial::SpatialTargetResources& target,
bool selectTrivialPlan)
: funcOp(funcOp), target(target), selectTrivialPlan(selectTrivialPlan) {}
FailureOr<SpatialLayoutSelection> run() {
SpatialLayoutSelection selection;
@@ -56,6 +57,9 @@ public:
selection.selectedAlternative[&op] = 0;
}
if (selectTrivialPlan)
return selection;
const size_t maxRounds = 2 * planOps.size() + 1;
for (size_t round = 0; round < maxRounds; ++round) {
bool changed = false;
@@ -168,6 +172,7 @@ private:
func::FuncOp funcOp;
const spatial::SpatialTargetResources& target;
bool selectTrivialPlan;
};
static LogicalResult materializeMismatchedUses(
@@ -251,8 +256,9 @@ struct SpatialLayoutPlanningPass final
}
SpatialLayoutPlanningPass() = default;
explicit SpatialLayoutPlanningPass(const spatial::SpatialTargetResources& target)
: target(target), hasTarget(true) {}
SpatialLayoutPlanningPass(const spatial::SpatialTargetResources& target,
bool selectTrivialPlan)
: target(target), selectTrivialPlan(selectTrivialPlan), hasTarget(true) {}
void runOnOperation() override {
ModuleOp moduleOp = getOperation();
@@ -263,13 +269,13 @@ struct SpatialLayoutPlanningPass final
}
auto entryFunc = getPimEntryFunc(moduleOp);
if (failed(entryFunc)) {
moduleOp.emitError("failed to locate the PIM entry function during Spatial layout planning");
moduleOp.emitError("failed to locate the Pim entry function during Spatial layout planning");
signalPassFailure();
return;
}
func::FuncOp funcOp = *entryFunc;
SpatialLayoutAnalysis analysis(funcOp, target);
SpatialLayoutAnalysis analysis(funcOp, target, selectTrivialPlan);
FailureOr<SpatialLayoutSelection> selection = analysis.run();
if (failed(selection)) {
signalPassFailure();
@@ -301,6 +307,7 @@ struct SpatialLayoutPlanningPass final
}
spatial::SpatialTargetResources target;
bool selectTrivialPlan = false;
bool hasTarget = false;
};
@@ -311,8 +318,8 @@ std::unique_ptr<Pass> createSpatialLayoutPlanningPass() {
}
std::unique_ptr<Pass> createSpatialLayoutPlanningPass(
const spatial::SpatialTargetResources& target) {
return std::make_unique<SpatialLayoutPlanningPass>(target);
const spatial::SpatialTargetResources& target, bool selectTrivialPlan) {
return std::make_unique<SpatialLayoutPlanningPass>(target, selectTrivialPlan);
}
} // namespace onnx_mlir
@@ -199,7 +199,7 @@ static bool writeConvLoweringReport(const ConvLoweringReportEntry& entry,
return false;
}
reportFile << "# PIM Conv Lowering Report (bounded to 512 rows)\n\n";
reportFile << "# Pim conv lowering report (bounded to 512 rows)\n\n";
reportFile << "## Plan selection\n";
writeConvReportTableHeader(reportFile, "Selector");
bool realizationSectionStarted = false;
@@ -307,7 +307,7 @@ LogicalResult raptor::SpatialToPimPass::lowerComputeBatchOp(spatial::SpatSchedul
"resultful compute_batch lowering currently requires a spat.in_parallel terminator");
}
auto coreIds = getRequiredScheduledBatchCoreIds(computeBatchOp, "spatial compute_batch core id");
auto coreIds = getRequiredScheduledBatchCoreIds(computeBatchOp, "Spatial compute_batch core id");
if (failed(coreIds))
return failure();
SmallVector<Value> batchWeights(computeBatchOp.getWeights().begin(), computeBatchOp.getWeights().end());
@@ -317,7 +317,7 @@ LogicalResult raptor::SpatialToPimPass::lowerComputeBatchOp(spatial::SpatSchedul
rewriter.setInsertionPointAfter(computeBatchOp);
auto laneCountAttr = pim::getCheckedI32Attr(
rewriter, computeBatchOp, static_cast<uint64_t>(computeBatchOp.getLaneCount()), "pim core_batch lane count");
rewriter, computeBatchOp, static_cast<uint64_t>(computeBatchOp.getLaneCount()), "Pim core_batch lane count");
if (failed(laneCountAttr))
return failure();
auto coreBatchOp =
@@ -410,7 +410,7 @@ LogicalResult raptor::SpatialToPimPass::lowerComputeOp(spatial::SpatScheduledCom
continue;
}
return computeOp.emitOpError("has an unsupported remaining result use during Spatial-to-PIM lowering");
return computeOp.emitOpError("has an unsupported remaining result use during Spatial-to-Pim lowering");
}
rewriter.setInsertionPoint(yieldOp);
@@ -420,7 +420,7 @@ LogicalResult raptor::SpatialToPimPass::lowerComputeOp(spatial::SpatScheduledCom
if (!computeOp.getWeights().empty())
computeWeights.append(computeOp.getWeights().begin(), computeOp.getWeights().end());
rewriter.setInsertionPointAfter(computeOp);
auto checkedCoreId = getRequiredScheduledCoreId(computeOp, "spatial compute core id");
auto checkedCoreId = getRequiredScheduledCoreId(computeOp, "Spatial compute core id");
if (failed(checkedCoreId))
return failure();
auto coreIdAttr = pim::getCheckedI32Attr(rewriter, computeOp, static_cast<int64_t>(*checkedCoreId), "pim core id");
@@ -734,7 +734,7 @@ raptor::SpatialToPimPass::ReturnPathLoweringResult raptor::SpatialToPimPass::low
auto storedType = dyn_cast<RankedTensorType>(storedValue.getType());
if (!storedType) {
producerOp->emitOpError(
"has an unsupported non-ranked concat-return helper yield during Spatial-to-PIM lowering");
"has an unsupported non-ranked concat-return helper yield during Spatial-to-Pim lowering");
return ReturnPathLoweringResult::Failure;
}
rewriter.setInsertionPointAfterValue(storedValue);
@@ -748,7 +748,7 @@ raptor::SpatialToPimPass::ReturnPathLoweringResult raptor::SpatialToPimPass::low
SmallVector<int64_t> destinationIndices;
if (failed(mapIndicesThroughHelperChain(
sourceIndices, concatReturnUse->concatShape, concatReturnUse->helperChain, destinationIndices))) {
producerOp->emitOpError("has an unsupported concat-return helper chain during Spatial-to-PIM lowering");
producerOp->emitOpError("has an unsupported concat-return helper chain during Spatial-to-Pim lowering");
return ReturnPathLoweringResult::Failure;
}
@@ -88,7 +88,7 @@ void onnx_mlir::raptor::SpatialToPimPass::runOnOperation() {
operationsToRemove.clear();
ModuleOp moduleOp = getOperation();
if (!hasTarget || failed(targetResources.verify())) {
moduleOp.emitError("Spatial-to-PIM lowering requires valid injected target resources");
moduleOp.emitError("Spatial-to-Pim lowering requires valid injected target resources");
signalPassFailure();
return;
}
@@ -96,7 +96,7 @@ void onnx_mlir::raptor::SpatialToPimPass::runOnOperation() {
auto entryFunc = getPimEntryFunc(moduleOp);
if (failed(entryFunc)) {
moduleOp.emitError("failed to locate the PIM entry function during Spatial-to-PIM lowering");
moduleOp.emitError("failed to locate the Pim entry function during Spatial-to-Pim lowering");
signalPassFailure();
return;
}
@@ -135,7 +135,7 @@ void onnx_mlir::raptor::SpatialToPimPass::runOnOperation() {
RewritePatternSet initialPatterns(ctx);
populateInitialPatterns(initialPatterns);
if (failed(applyPartialConversion(moduleOp, target, std::move(initialPatterns)))) {
moduleOp.emitError("failed to lower required Spatial ops to the initial PIM form");
moduleOp.emitError("failed to lower required Spatial ops to the initial Pim form");
signalPassFailure();
return;
}
@@ -153,7 +153,7 @@ void onnx_mlir::raptor::SpatialToPimPass::runOnOperation() {
auto returnOp = cast<func::ReturnOp>(funcOp.front().getTerminator());
addReturnOutputBuffers(returnOp, rewriter);
if (failed(allocateAndInitializeCoreLocalVariables(funcOp, rewriter))) {
funcOp.emitOpError("failed to allocate or initialize core-local tensors during Spatial-to-PIM lowering");
funcOp.emitOpError("failed to allocate or initialize core-local tensors during Spatial-to-Pim lowering");
signalPassFailure();
return;
}
@@ -285,7 +285,7 @@ void onnx_mlir::raptor::SpatialToPimPass::runOnOperation() {
RewritePatternSet communicationPatterns(ctx);
populateChannelLoweringPatterns(communicationPatterns);
if (failed(applyFullConversion(funcOp, communicationTarget, std::move(communicationPatterns)))) {
funcOp.emitOpError("failed to lower Spatial communication ops to PIM communication ops");
funcOp.emitOpError("failed to lower Spatial communication ops to Pim communication ops");
signalPassFailure();
return;
}
@@ -26,7 +26,7 @@ namespace raptor {
struct SpatialToPimPass : mlir::PassWrapper<SpatialToPimPass, mlir::OperationPass<mlir::ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SpatialToPimPass)
llvm::StringRef getArgument() const override { return "convert-spatial-to-pim"; }
llvm::StringRef getDescription() const override { return "Lower Spatial ops to PIM-ready format"; }
llvm::StringRef getDescription() const override { return "Lower Spatial ops to Pim-ready format"; }
SpatialToPimPass() = default;
explicit SpatialToPimPass(const spatial::SpatialTargetResources& target)
@@ -402,7 +402,7 @@ static LogicalResult verifyPimCoresNeedNoTensorCopies(
bufferization::BufferizationState state;
if (failed(bufferization::insertTensorCopies(*clone, options, state))) {
moduleOp.emitError("official one-shot analysis failed while verifying PIM core copy freedom");
moduleOp.emitError("official one-shot analysis failed while verifying Pim core copy freedom");
return failure();
}
@@ -415,10 +415,10 @@ static LogicalResult verifyPimCoresNeedNoTensorCopies(
Operation* requiredBy = alloc->getUsers().empty()
? alloc.getOperation() : *alloc->getUsers().begin();
diagnostics.report(requiredBy, [](Operation* op) {
op->emitOpError("official one-shot bufferization requires a tensor copy inside a PIM core");
op->emitOpError("official one-shot bufferization requires a tensor copy inside a Pim core");
});
});
diagnostics.emitSuppressedSummary(moduleOp, "required PIM core tensor copies");
diagnostics.emitSuppressedSummary(moduleOp, "required Pim core tensor copies");
return success(!diagnostics.hasFailure());
}
@@ -440,7 +440,7 @@ static LogicalResult runOneShotPimBufferization(
bufferization::BufferizationState state;
if (failed(bufferization::insertTensorCopies(moduleOp, hostOptions, state))
|| failed(bufferization::bufferizeModuleOp(moduleOp, options, state))) {
moduleOp.emitError("Failed to bufferize PIM and Spatial ops");
moduleOp.emitError("Failed to bufferize Pim and Spatial ops");
return failure();
}
return success();
@@ -478,7 +478,7 @@ static LogicalResult verifyContiguousRuntimeOperands(ModuleOp moduleOp) {
if (succeeded(resolveContiguousAddress(operand, knowledge)) || succeeded(compileContiguousAddressExpr(operand)))
return;
op.emitOpError() << "operand #" << operandIndex
<< " is not backed by contiguous addressable storage after PIM bufferization";
<< " is not backed by contiguous addressable storage after Pim bufferization";
hasFailure = true;
};
@@ -552,7 +552,7 @@ static LogicalResult verifyContiguousRuntimeOperands(ModuleOp moduleOp) {
});
if (hasFailure) {
moduleOp.emitError("PIM bufferization must fully normalize executable runtime operand contiguity before codegen");
moduleOp.emitError("Pim bufferization must fully normalize executable runtime operand contiguity before codegen");
return failure();
}
return success();
@@ -589,7 +589,7 @@ static LogicalResult verifyPimCopyAddressSpaces(ModuleOp moduleOp) {
});
if (failureCount != 0)
moduleOp.emitError() << "found " << failureCount
<< " PIM copy address-space violation(s); the first is reported above";
<< " Pim copy address-space violation(s); the first is reported above";
return success(failureCount == 0);
}
@@ -673,7 +673,7 @@ static LogicalResult normalizePimMemory(ModuleOp moduleOp, func::FuncOp funcOp)
GreedyRewriteConfig contiguityConfig;
contiguityConfig.enableFolding(false);
if (failed(applyPatternsGreedily(moduleOp, std::move(contiguityPatterns), contiguityConfig))) {
moduleOp.emitError("failed to normalize PIM copy contiguity during bufferization");
moduleOp.emitError("failed to normalize Pim copy contiguity during bufferization");
return failure();
}
annotateWeightsMemrefs(moduleOp, funcOp);
@@ -684,7 +684,7 @@ static LogicalResult normalizePimMemory(ModuleOp moduleOp, func::FuncOp funcOp)
static FailureOr<func::FuncOp> requirePimEntryFunc(ModuleOp moduleOp, StringRef phase) {
auto entryFunc = getPimEntryFunc(moduleOp);
if (failed(entryFunc)) {
moduleOp.emitError("failed to locate the PIM entry function during ") << phase;
moduleOp.emitError("failed to locate the Pim entry function during ") << phase;
return failure();
}
return *entryFunc;
@@ -701,12 +701,12 @@ struct PimBufferizationPreparationPass
StringRef getArgument() const override { return "pim-bufferization-preparation"; }
StringRef getDescription() const override {
return "Prepare writable tensor destinations for PIM one-shot bufferization.";
return "Prepare writable tensor destinations for Pim one-shot bufferization.";
}
void runOnOperation() final {
ModuleOp moduleOp = getOperation();
auto funcOp = requirePimEntryFunc(moduleOp, "PIM bufferization preparation");
auto funcOp = requirePimEntryFunc(moduleOp, "Pim bufferization preparation");
if (failed(funcOp)) {
signalPassFailure();
return;
@@ -725,7 +725,7 @@ struct PimOneShotBufferizationPass
StringRef getArgument() const override { return "pim-one-shot-bufferization"; }
StringRef getDescription() const override {
return "Run one-shot bufferization for PIM and Spatial tensors.";
return "Run one-shot bufferization for Pim and Spatial tensors.";
}
void runOnOperation() final {
@@ -740,12 +740,12 @@ struct PimMemoryNormalizationPass
StringRef getArgument() const override { return "pim-memory-normalization"; }
StringRef getDescription() const override {
return "Normalize PIM memory copies and verify addressable operands.";
return "Normalize Pim memory copies and verify addressable operands.";
}
void runOnOperation() final {
ModuleOp moduleOp = getOperation();
auto funcOp = requirePimEntryFunc(moduleOp, "PIM memory normalization");
auto funcOp = requirePimEntryFunc(moduleOp, "Pim memory normalization");
if (failed(funcOp)) {
signalPassFailure();
return;
@@ -761,20 +761,20 @@ static LogicalResult verifyNoTensorValues(ModuleOp moduleOp) {
if (failureCount >= 8)
return;
if (op->getDialect()->getNamespace() == "tensor") {
op->emitOpError("tensor operation remains after PIM bufferization");
op->emitOpError("tensor operation remains after Pim bufferization");
++failureCount;
return;
}
for (Value value : op->getOperands()) {
if (isa<TensorType>(value.getType())) {
op->emitOpError("tensor operand remains after PIM bufferization");
op->emitOpError("tensor operand remains after Pim bufferization");
++failureCount;
return;
}
}
for (Value value : op->getResults()) {
if (isa<TensorType>(value.getType())) {
op->emitOpError("tensor result remains after PIM bufferization");
op->emitOpError("tensor result remains after Pim bufferization");
++failureCount;
return;
}
@@ -782,7 +782,7 @@ static LogicalResult verifyNoTensorValues(ModuleOp moduleOp) {
});
if (failureCount != 0)
moduleOp.emitError() << "found " << failureCount
<< " tensor value(s) after PIM bufferization"
<< " tensor value(s) after Pim bufferization"
<< (failureCount == 8 ? " (first 8 reported)" : "");
return success(failureCount == 0);
}
@@ -793,7 +793,7 @@ struct PimBufferizationVerificationPass
StringRef getArgument() const override { return "pim-bufferization-verification"; }
StringRef getDescription() const override {
return "Verify tensor elimination, contiguity, and PIM copy address spaces.";
return "Verify tensor elimination, contiguity, and Pim copy address spaces.";
}
void runOnOperation() final {
@@ -16,7 +16,7 @@ struct HostConstantFoldingPass : PassWrapper<HostConstantFoldingPass, OperationP
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(HostConstantFoldingPass)
StringRef getArgument() const override { return "pim-host-constant-folding-pass"; }
StringRef getDescription() const override { return "Fold host-side constant expressions before PIM verification"; }
StringRef getDescription() const override { return "Fold host-side constant expressions before Pim verification"; }
LogicalResult initialize(MLIRContext* context) override {
RewritePatternSet owningPatterns(context);
@@ -38,7 +38,7 @@ struct HostConstantFoldingPass : PassWrapper<HostConstantFoldingPass, OperationP
GreedyRewriteConfig config;
config.enableFolding();
if (failed(applyPatternsGreedily(moduleOp, *patterns, config))) {
moduleOp.emitError("PIM host constant folding failed in the greedy rewrite driver");
moduleOp.emitError("Pim host constant folding failed in the greedy rewrite driver");
signalPassFailure();
return;
}
@@ -472,7 +472,7 @@ struct FoldConstantHostCopyPattern final : OpRewritePattern<memref::CopyOp> {
}
};
// Converts PIM copies from dense globals into direct folded globals before codegen.
// Converts Pim copies from dense globals into direct folded globals before codegen.
struct FoldConstantMemCpPattern final : OpRewritePattern<pim::PimMemCopyOp> {
using OpRewritePattern::OpRewritePattern;
@@ -40,7 +40,7 @@ struct LowerTransposePattern final : OpRewritePattern<pim::PimTransposeOp> {
auto sourceType = dyn_cast<MemRefType>(op.getInput().getType());
auto targetType = dyn_cast<MemRefType>(op.getOutputBuffer().getType());
if (!sourceType || !targetType || !sourceType.hasStaticShape() || !targetType.hasStaticShape())
return op.emitOpError("requires static memref operands before PIM instruction selection");
return op.emitOpError("requires static memref operands before Pim instruction selection");
ArrayRef<int64_t> sourceShape = sourceType.getShape();
size_t rank = sourceShape.size();
@@ -147,7 +147,7 @@ struct InstructionSelectionPass : PassWrapper<InstructionSelectionPass, Operatio
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(InstructionSelectionPass)
StringRef getArgument() const override { return "pim-instruction-selection"; }
StringRef getDescription() const override { return "Select explicit PIM ISA operations"; }
StringRef getDescription() const override { return "Select explicit Pim ISA operations"; }
void runOnOperation() override {
RewritePatternSet patterns(&getContext());
@@ -36,7 +36,7 @@ struct PimLocalMemoryPlanningPass : PassWrapper<PimLocalMemoryPlanningPass, Oper
StringRef getArgument() const override { return "pim-local-memory-planning"; }
StringRef getDescription() const override {
return "Plan liveness-based addresses for PIM core-local memory";
return "Plan liveness-based addresses for Pim core-local memory";
}
void runOnOperation() override {
@@ -149,14 +149,14 @@ FailureOr<CoreMemoryPlan> buildCoreMemoryPlan(Operation* coreLikeOp) {
plan.intervals = std::move(*intervals);
auto placements = planLocalMemoryPlacements(plan.intervals, kPimLocalMemoryAddressLimit);
if (failed(placements)) {
coreLikeOp->emitError("PIM local-memory plan exceeds the signed int32 address range");
coreLikeOp->emitError("Pim local-memory plan exceeds the signed int32 address range");
return failure();
}
plan.placements = std::move(*placements);
for (const LocalMemoryPlacement& placement : plan.placements) {
auto end = alignedEnd(placement.address, placement.size, kPimLocalMemoryAddressLimit);
if (failed(end)) {
coreLikeOp->emitError("PIM local-memory plan has invalid address arithmetic");
coreLikeOp->emitError("Pim local-memory plan has invalid address arithmetic");
return failure();
}
plan.arenaSize = std::max(plan.arenaSize, *end);
@@ -117,7 +117,7 @@ verifyLocalMemoryPlan(Operation* coreLikeOp, pim::CappedDiagnosticReporter& diag
for (StringRef name : kRemovedLocalMemoryPlanAttrNames)
if (coreLikeOp->hasAttr(name)) {
diagnostics.report(coreLikeOp, [name](Operation* op) {
op->emitError() << "contains removed PIM local-memory planning attribute '" << name << "'";
op->emitError() << "contains removed Pim local-memory planning attribute '" << name << "'";
});
hasFailure = true;
}
@@ -137,7 +137,7 @@ verifyLocalMemoryPlan(Operation* coreLikeOp, pim::CappedDiagnosticReporter& diag
auto analyzed = pim::analyzeLocalMemoryLifetimes(coreLikeOp);
if (failed(analyzed)) {
diagnostics.report(coreLikeOp, [](Operation* op) {
op->emitError("cannot analyze PIM local-memory lifetimes for plan verification");
op->emitError("cannot analyze Pim local-memory lifetimes for plan verification");
});
return failure();
}
@@ -156,7 +156,7 @@ verifyLocalMemoryPlan(Operation* coreLikeOp, pim::CappedDiagnosticReporter& diag
for (StringRef name : kRemovedLocalMemoryPlanAttrNames)
if (allocation->hasAttr(name)) {
diagnostics.report(allocation, [name](Operation* op) {
op->emitOpError() << "contains removed PIM local-memory planning attribute '" << name << "'";
op->emitOpError() << "contains removed Pim local-memory planning attribute '" << name << "'";
});
hasFailure = true;
}
@@ -171,7 +171,7 @@ verifyLocalMemoryPlan(Operation* coreLikeOp, pim::CappedDiagnosticReporter& diag
uint64_t address = static_cast<uint64_t>(addressAttr.getInt());
if (address % 4 != 0 || address > arenaSize || interval.size > arenaSize - address) {
diagnostics.report(allocation, [&](Operation* op) {
op->emitOpError() << "has invalid PIM local-memory range [" << address << ", "
op->emitOpError() << "has invalid Pim local-memory range [" << address << ", "
<< (address <= arenaSize && interval.size <= arenaSize - address
? address + interval.size
: arenaSize)
@@ -221,7 +221,7 @@ verifyLocalMemoryPlan(Operation* coreLikeOp, pim::CappedDiagnosticReporter& diag
memref::AllocOp otherAllocation = other.allocation;
diagnostics.report(allocation, [&](Operation*) {
auto diagnostic = allocation.emitOpError()
<< "PIM local-memory plan assigns simultaneously live allocations to overlapping ranges; first range ["
<< "Pim local-memory plan assigns simultaneously live allocations to overlapping ranges; first range ["
<< conflicting->first << ", " << conflicting->first + other.size << "), second range [" << address
<< ", " << address + interval.size << "), live positions overlap at ["
<< std::max(interval.start, other.start) << ", " << std::min(interval.end, other.end) << "]";
@@ -471,7 +471,7 @@ static LogicalResult appendCoreCommunicationEvents(Block& block,
auto targetCoreId = resolveIndexValue(sendOp.getTargetCoreId(), knowledge);
if (failed(targetCoreId)) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError("cannot statically resolve send target core for PIM communication deadlock check");
illegalOp->emitOpError("cannot statically resolve send target core for Pim communication deadlock check");
});
return failure();
}
@@ -490,7 +490,7 @@ static LogicalResult appendCoreCommunicationEvents(Block& block,
if (failed(sourceCoreId)) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError(
"cannot statically resolve receive source core for PIM communication deadlock check");
"cannot statically resolve receive source core for Pim communication deadlock check");
});
return failure();
}
@@ -530,7 +530,7 @@ static void printCommunicationWindow(llvm::raw_ostream& os,
static void printCommunicationDeadlockReport(const DenseMap<int64_t, CommunicationEventVector>& coreEvents,
const DenseMap<int64_t, size_t>& programCounters,
ArrayRef<int64_t> cycle) {
llvm::errs() << "\n=== PIM static communication deadlock report ===\n";
llvm::errs() << "\n=== Pim static communication deadlock report ===\n";
llvm::errs() << "wait cycle:";
for (int64_t coreId : cycle)
llvm::errs() << " " << coreId;
@@ -565,7 +565,7 @@ static void printCommunicationDeadlockReport(const DenseMap<int64_t, Communicati
continue;
printCommunicationWindow(llvm::errs(), coreEvents, coreId, pcIt->second);
}
llvm::errs() << "=== end PIM static communication deadlock report ===\n\n";
llvm::errs() << "=== end Pim static communication deadlock report ===\n\n";
}
static void emitCommunicationDeadlockCycle(ModuleOp moduleOp,
@@ -576,8 +576,8 @@ static void emitCommunicationDeadlockCycle(ModuleOp moduleOp,
auto diagnostic =
moduleOp.emitError()
<< "PIM communication deadlock check found a blocking send/receive cycle while statically simulating the "
"expanded per-core communication streams; see the PIM static communication deadlock report above";
<< "Pim communication deadlock check found a blocking send/receive cycle while statically simulating the "
"expanded per-core communication streams; see the Pim static communication deadlock report above";
for (int64_t coreId : cycle) {
auto eventsIt = coreEvents.find(coreId);
@@ -728,7 +728,7 @@ static LogicalResult verifyNoStaticCommunicationDeadlock(ModuleOp moduleOp,
auto diagnostic =
moduleOp.emitError()
<< "PIM communication deadlock check stalled without finding a closed wait cycle; this usually means a "
<< "Pim communication deadlock check stalled without finding a closed wait cycle; this usually means a "
"send/receive peer is missing or ordered after a finished core";
for (const auto& [coreId, events] : coreEvents) {
size_t pc = programCounters[coreId];
@@ -746,7 +746,7 @@ struct VerificationPass : PassWrapper<VerificationPass, OperationPass<ModuleOp>>
StringRef getArgument() const override { return "verify-pim-pass"; }
StringRef getDescription() const override {
return "Verify that bufferized PIM IR contains only explicit host/device transfers";
return "Verify that bufferized Pim IR contains only explicit host/device transfers";
}
VerificationPass() {}
@@ -763,7 +763,7 @@ struct VerificationPass : PassWrapper<VerificationPass, OperationPass<ModuleOp>>
pim::CappedDiagnosticReporter diagnostics;
if (!hasTarget || failed(targetResources.verify())) {
moduleOp.emitError("PIM codegen verification requires valid injected target resources");
moduleOp.emitError("Pim codegen verification requires valid injected target resources");
signalPassFailure();
return;
}
@@ -792,7 +792,7 @@ struct VerificationPass : PassWrapper<VerificationPass, OperationPass<ModuleOp>>
return;
diagnostics.report(op, [](Operation* illegalOp) {
illegalOp->emitError("illegal Spatial operation reached PIM codegen verification");
illegalOp->emitError("illegal Spatial operation reached Pim codegen verification");
});
});
@@ -833,7 +833,7 @@ struct VerificationPass : PassWrapper<VerificationPass, OperationPass<ModuleOp>>
if (!isAddressOnlyHostOp(&op)) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError("illegal host-side runtime op remains after PIM bufferization; "
illegalOp->emitOpError("illegal host-side runtime op remains after Pim bufferization; "
"fold it to constants or lower it into pim.core");
});
continue;
@@ -849,7 +849,7 @@ struct VerificationPass : PassWrapper<VerificationPass, OperationPass<ModuleOp>>
if (diagnostics.hasFailure()) {
diagnostics.emitSuppressedSummary(moduleOp, "verification failures");
moduleOp.emitError("PIM codegen verification failed; see diagnostics above");
moduleOp.emitError("Pim codegen verification failed; see diagnostics above");
hasFailure = true;
}
@@ -928,7 +928,7 @@ private:
bool hasFailure = false;
if (!isSupportedCoreInstructionOp(&op)) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError("unsupported executable op reached PIM codegen verification");
illegalOp->emitOpError("unsupported executable op reached Pim codegen verification");
});
hasFailure = true;
}
@@ -990,7 +990,7 @@ private:
if (failed(resolveIndexValue(storeOp.getHostTargetOffset(), knowledge))
|| failed(resolveIndexValue(storeOp.getDeviceSourceOffset(), knowledge))) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError("offset operands must be statically evaluable for PIM codegen");
illegalOp->emitOpError("offset operands must be statically evaluable for Pim codegen");
});
hasFailure = true;
}
@@ -1006,7 +1006,7 @@ private:
if (failed(resolveIndexValue(loadOp.getDeviceTargetOffset(), knowledge))
|| failed(resolveIndexValue(loadOp.getHostSourceOffset(), knowledge))) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError("offset operands must be statically evaluable for PIM codegen");
illegalOp->emitOpError("offset operands must be statically evaluable for Pim codegen");
});
hasFailure = true;
}
@@ -1022,7 +1022,7 @@ private:
if (failed(resolveIndexValue(copyOp.getTargetOffset(), knowledge))
|| failed(resolveIndexValue(copyOp.getSourceOffset(), knowledge))) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError("offset operands must be statically evaluable for PIM codegen");
illegalOp->emitOpError("offset operands must be statically evaluable for Pim codegen");
});
hasFailure = true;
}
@@ -1032,7 +1032,7 @@ private:
&& failed(resolveIndexValue(receiveOp.getOutputOffset(), knowledge))) {
diagnostics.report(&op, [](Operation* illegalOp) {
illegalOp->emitOpError(
"output offset must be statically evaluable for PIM codegen");
"output offset must be statically evaluable for Pim codegen");
});
hasFailure = true;
}
+2 -2
View File
@@ -11,7 +11,7 @@ include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.td"
def PimDialect : Dialect {
let name = "pim";
let summary = "A low-level dialect for the PIM coprocessors on ReRAM crossbars";
let summary = "A low-level dialect for the Pim coprocessors on ReRAM crossbars";
let cppNamespace = "::onnx_mlir::pim";
}
@@ -27,7 +27,7 @@ def PimTensor :
def PimCoreOp : PimOp<"core", [SingleBlock,
DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmBlockArgumentNames"]>]> {
let summary = "Execute a block on a PIM core";
let summary = "Execute a block on a Pim core";
let regions = (region SizedRegion<1>:$body);
@@ -28,7 +28,7 @@ static bool hasValidTarget(const SchedulingTarget& target) {
static FailureOr<func::FuncOp> requireEntry(ModuleOp moduleOp) {
auto entry = getPimEntryFunc(moduleOp);
if (failed(entry)) {
moduleOp.emitError("failed to locate the PIM entry function during Spatial scheduling and realization");
moduleOp.emitError("failed to locate the Pim entry function during Spatial scheduling and realization");
return failure();
}
return *entry;
@@ -193,7 +193,7 @@ FailureOr<TopLevelOpInfo> buildTopLevelOpInfo(Operation& op, bool isScheduled, s
if constexpr (std::is_same_v<ComputeOpTy, SpatScheduledCompute>) {
if (auto compute = dyn_cast<ComputeOpTy>(&op)) {
auto coreId = getOptionalScheduledCoreId(compute, "spatial dataflow export core id");
auto coreId = getOptionalScheduledCoreId(compute, "Spatial dataflow export core id");
if (failed(coreId))
return failure();
if (*coreId)
@@ -207,7 +207,7 @@ FailureOr<TopLevelOpInfo> buildTopLevelOpInfo(Operation& op, bool isScheduled, s
template <typename BatchOpTy>
FailureOr<SmallVector<int32_t, 8>> getBatchLaneCoreIds(BatchOpTy batch) {
if constexpr (std::is_same_v<BatchOpTy, SpatScheduledComputeBatch>) {
auto coreIds = getOptionalScheduledBatchCoreIds(batch, "spatial dataflow export core ids");
auto coreIds = getOptionalScheduledBatchCoreIds(batch, "Spatial dataflow export core ids");
if (failed(coreIds))
return failure();
if (!*coreIds)
+1 -1
View File
@@ -13,7 +13,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
def SpatialDialect : Dialect {
let name = "spat";
let summary = "Dialect designed for deep learning computation in a spatial architecture";
let summary = "Dialect designed for deep learning computation in a Spatial architecture";
let cppNamespace = "::onnx_mlir::spatial";
let useDefaultAttributePrinterParser = 0;
let extraClassDeclaration = [{
+2 -1
View File
@@ -25,7 +25,8 @@ std::unique_ptr<mlir::Pass> createONNXToSpatialPass(
const spatial::SpatialTargetResources& target,
const ONNXToSpatialPlanningOptions& options);
std::unique_ptr<mlir::Pass> createSpatialLayoutPlanningPass();
std::unique_ptr<mlir::Pass> createSpatialLayoutPlanningPass(const spatial::SpatialTargetResources& target);
std::unique_ptr<mlir::Pass> createSpatialLayoutPlanningPass(
const spatial::SpatialTargetResources& target, bool selectTrivialPlan = false);
std::unique_ptr<mlir::Pass> createLowerSpatialPlansPass();
std::unique_ptr<mlir::Pass> createLowerSpatialPlansPass(
const spatial::SpatialTargetResources& target,
@@ -12,7 +12,7 @@ namespace {
struct EmitPimCodePass : PassWrapper<EmitPimCodePass, OperationPass<ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(EmitPimCodePass);
StringRef getArgument() const override { return "emit-pim-code-pass"; }
StringRef getDescription() const override { return "Emit PIM simulator code artifacts"; }
StringRef getDescription() const override { return "Emit Pim simulator code artifacts"; }
EmitPimCodePass() {}
EmitPimCodePass(const EmitPimCodePass& pass) {}
@@ -25,7 +25,7 @@ struct EmitPimCodePass : PassWrapper<EmitPimCodePass, OperationPass<ModuleOp>> {
int compiler_error_code = compileToPimCode(moduleOp, pimDir);
if (compiler_error_code != CompilerSuccess) {
moduleOp.emitError() << "failed to emit PIM simulator code artifacts; compiler error code "
moduleOp.emitError() << "failed to emit Pim simulator code artifacts; compiler error code "
<< compiler_error_code;
signalPassFailure();
}