@@ -155,16 +155,20 @@ Operation* remapAndExtractResult(ImplicitLocOpBuilder& builder, Value input,
155155 return extractRemap;
156156}
157157
158- // Rebuilds the full periodic layout of a kernel's output from its first valid
159- // period. Assumes the first period is uncorrupted by wrap-around bounds.
160- Operation* replicateFirstPeriodOfResult (ImplicitLocOpBuilder& b, Value input,
158+ // Rebuilds the full periodic layout of a kernel's output from the valid prefix
159+ // of the periodic pattern. Greedily replicates the valid periodic prefix of the
160+ // layout until the all of the slot count is covered.
161+ Operation* replicateValidPrefixOfResult (ImplicitLocOpBuilder& b, Value input,
161162 LayoutAttr resultLayout,
162- int64_t period) {
163+ int64_t inputPeriod,
164+ int64_t validPrefix) {
163165 auto ctSemanticType = cast<RankedTensorType>(input.getType ());
164166 int64_t numCiphertexts = ctSemanticType.getDimSize (0 );
165167 int64_t numSlots = ctSemanticType.getDimSize (1 );
166- IntegerRelation replication =
167- getPeriodicReplicationRelation (numCiphertexts, numSlots, period);
168+ int64_t actualValidPrefix =
169+ validPrefix > 0 ? (validPrefix / inputPeriod) * inputPeriod : 0 ;
170+ IntegerRelation replication = getPeriodicReplicationRelation (
171+ numCiphertexts, numSlots, actualValidPrefix);
168172 LayoutAttr replicationMapping =
169173 LayoutAttr::getFromIntegerRelation (b.getContext (), replication);
170174 auto remapOp = tensor_ext::RemapOp::create (b, input, replicationMapping);
@@ -2825,12 +2829,20 @@ struct ConvertLinalgMatmul
28252829 addBias->setAttr (kLayoutAttrName , layoutAttr);
28262830 setMaterializedAttr (addBias);
28272831
2828- // Rebuild the full periodic output layout from the first period.
2832+ // Rebuild the full periodic output layout from the widest valid
2833+ // period-aligned window. The rotation reach of rotate-and-reduce with
2834+ // `steps` iterations of stride `period` is period * (steps - 1).
28292835 auto dataSemanticResultType =
28302836 cast<RankedTensorType>(op->getResult (0 ).getType ());
2831- Operation* replicated =
2832- replicateFirstPeriodOfResult (b, addBias->getResult (0 ), layoutAttr,
2833- dataSemanticResultType.getNumElements ());
2837+ int64_t reach = period * (steps - 1 );
2838+ auto ctSemanticResultType =
2839+ cast<RankedTensorType>(addBias->getResult (0 ).getType ());
2840+ int64_t validPrefix = ctSemanticResultType.getDimSize (1 ) - reach;
2841+ LLVM_DEBUG (llvm::dbgs () << " Bicyclic diagonal matmul valid prefix: "
2842+ << validPrefix << " \n " );
2843+ Operation* replicated = replicateValidPrefixOfResult (
2844+ b, addBias->getResult (0 ), layoutAttr,
2845+ dataSemanticResultType.getNumElements (), validPrefix);
28342846 setMaterializedAttr (replicated);
28352847 rewriter.replaceOp (op, replicated);
28362848 }
@@ -2882,12 +2894,23 @@ struct ConvertLinalgMatmul
28822894 addBias->setAttr (kLayoutAttrName , layoutAttr);
28832895 setMaterializedAttr (addBias);
28842896
2885- // Rebuild the full periodic output layout from the first period.
2897+ // Rebuild the full periodic output layout from the widest valid
2898+ // period-aligned window. For (m x n) * (n x p), the BSGS rotation reach
2899+ // is n * p - 1 + m * (n - 1).
28862900 auto dataSemanticResultType =
28872901 cast<RankedTensorType>(op->getResult (0 ).getType ());
2888- Operation* replicated =
2889- replicateFirstPeriodOfResult (b, addBias->getResult (0 ), layoutAttr,
2890- dataSemanticResultType.getNumElements ());
2902+ int64_t m = lhsType.getDimSize (0 );
2903+ int64_t n = lhsType.getDimSize (1 );
2904+ int64_t p = rhsType.getDimSize (1 );
2905+ int64_t reach = n * p - 1 + m * (n - 1 );
2906+ auto ctSemanticResultType =
2907+ cast<RankedTensorType>(addBias->getResult (0 ).getType ());
2908+ int64_t validPrefix = ctSemanticResultType.getDimSize (1 ) - reach;
2909+ LLVM_DEBUG (llvm::dbgs ()
2910+ << " Bicyclic matmul valid prefix: " << validPrefix << " \n " );
2911+ Operation* replicated = replicateValidPrefixOfResult (
2912+ b, addBias->getResult (0 ), layoutAttr,
2913+ dataSemanticResultType.getNumElements (), validPrefix);
28912914 setMaterializedAttr (replicated);
28922915 rewriter.replaceOp (op, replicated);
28932916 }
@@ -2968,12 +2991,24 @@ struct ConvertLinalgBatchMatmul
29682991 addBias->setAttr (kLayoutAttrName , layoutAttr);
29692992 setMaterializedAttr (addBias);
29702993
2971- // Rebuild the full periodic output layout from the first period.
2994+ // Rebuild the full periodic output layout from the widest valid
2995+ // period-aligned window. For (h x m x n) * (h x n x p), the BSGS rotation
2996+ // reach is h * n * p - 1 + h * m * (n - 1).
29722997 auto dataSemanticResultType =
29732998 cast<RankedTensorType>(op->getResult (0 ).getType ());
2974- Operation* replicated =
2975- replicateFirstPeriodOfResult (b, addBias->getResult (0 ), layoutAttr,
2976- dataSemanticResultType.getNumElements ());
2999+ int64_t h = lhsType.getShape ()[0 ];
3000+ int64_t m = lhsType.getShape ()[1 ];
3001+ int64_t n = lhsType.getShape ()[2 ];
3002+ int64_t p = rhsType.getShape ()[2 ];
3003+ int64_t reach = h * n * p - 1 + h * m * (n - 1 );
3004+ auto ctSemanticResultType =
3005+ cast<RankedTensorType>(addBias->getResult (0 ).getType ());
3006+ int64_t validPrefix = ctSemanticResultType.getDimSize (1 ) - reach;
3007+ LLVM_DEBUG (llvm::dbgs () << " Tricyclic batch matmul valid prefix: "
3008+ << validPrefix << " \n " );
3009+ Operation* replicated = replicateValidPrefixOfResult (
3010+ b, addBias->getResult (0 ), layoutAttr,
3011+ dataSemanticResultType.getNumElements (), validPrefix);
29773012 setMaterializedAttr (replicated);
29783013 rewriter.replaceOp (op, replicated);
29793014 }
0 commit comments