#include "ConvGeometry.hpp" #include #include "src/Accelerators/PIM/Common/IR/ShapeUtils.hpp" #include "src/Accelerators/PIM/Compiler/PimCompilerOptions.hpp" namespace onnx_mlir { bool isDepthwiseConv(int64_t group, int64_t numChannelsIn, int64_t numChannelsOut, int64_t numChannelsInPerGroup) { return group == numChannelsIn && numChannelsInPerGroup == 1 && numChannelsOut % group == 0; } ConvGeometry buildConvGeometry(const ConvLoweringState& state) { ConvGeometry geo { state.batchSize, state.numChannelsIn, state.xHeight, state.xWidth, state.numChannelsOut, state.wHeight, state.wWidth, state.outHeight, state.outWidth, state.group, state.numChannelsInPerGroup, state.numChannelsOutPerGroup, state.numChannelsInPerGroup * state.wHeight * state.wWidth, state.numChannelsOutPerGroup, state.batchSize * state.outHeight * state.outWidth, static_cast(crossbarSize.getValue()), 1, 0, state.hasBias, isDepthwiseConv(state.group, state.numChannelsIn, state.numChannelsOut, state.numChannelsInPerGroup), }; geo.pack = std::max(1, geo.xbarSize / std::max(geo.k, geo.c)); geo.im2colElements = static_cast(std::max(0, geo.p)) * static_cast(std::max(0, geo.k)); return geo; } uint64_t chooseStreamChunkPositions(const ConvGeometry& geo, int64_t packFactor) { const uint64_t patchElements = static_cast(std::max(1, geo.k)); uint64_t chunkPositions = std::max(1, pimConvIm2colMaxElements / patchElements); chunkPositions = std::min(chunkPositions, static_cast(std::max(1, geo.p))); chunkPositions = std::min(chunkPositions, std::max(1, pimConvStreamChunkPositions)); if (packFactor > 1 && chunkPositions > static_cast(packFactor)) { chunkPositions -= chunkPositions % static_cast(packFactor); chunkPositions = std::max(chunkPositions, static_cast(packFactor)); } return std::max(1, chunkPositions); } RowInterval computeConvInputRowsForOutputRows(RowInterval outputRows, const ConvLoweringState& state) { const int64_t rawBegin = outputRows.begin * state.strideHeight - state.padHeightBegin; const int64_t rawEnd = (outputRows.end - 1) * state.strideHeight - state.padHeightBegin + state.dilationHeight * (state.wHeight - 1) + 1; return {std::max(0, rawBegin), std::min(state.xHeight, rawEnd)}; } ConvRowDemand buildConvRowDemand(RowInterval outputRows, const ConvLoweringState& state) { ConvRowDemand demand; demand.outputRows = outputRows; demand.neededInputRows = computeConvInputRowsForOutputRows(outputRows, state); demand.acquiredInputRows = demand.neededInputRows; const int64_t rawBegin = outputRows.begin * state.strideHeight - state.padHeightBegin; const int64_t rawEnd = (outputRows.end - 1) * state.strideHeight - state.padHeightBegin + state.dilationHeight * (state.wHeight - 1) + 1; demand.topHaloRows = std::max(0, -rawBegin); demand.bottomHaloRows = std::max(0, rawEnd - state.xHeight); demand.acquiredInputRows = demand.neededInputRows; return demand; } } // namespace onnx_mlir