|  | 
| 10 | 10 | #include "iree/compiler/Codegen/Dialect/Codegen/IR/IREECodegenDialect.h" | 
| 11 | 11 | #include "iree/compiler/Codegen/Dialect/GPU/IR/IREEGPUAttrs.h" | 
| 12 | 12 | #include "iree/compiler/Codegen/Dialect/GPU/IR/IREEGPUDialect.h" | 
|  | 13 | +#include "iree/compiler/Codegen/Dialect/GPU/TargetUtils/KnownTargets.h" | 
| 13 | 14 | #include "iree/compiler/Codegen/Utils/GPUUtils.h" | 
| 14 | 15 | #include "iree/compiler/Dialect/Encoding/IR/EncodingTypes.h" | 
| 15 | 16 | #include "iree/compiler/Dialect/HAL/Analysis/DeviceAnalysis.h" | 
| @@ -59,43 +60,43 @@ updateFuncSignature(FunctionOpInterface funcOp, | 
| 59 | 60 |   } | 
| 60 | 61 | } | 
| 61 | 62 | 
 | 
| 62 |  | -static LogicalResult | 
| 63 |  | -materializeFuncOpEncodings(FunctionOpInterface funcOp, | 
| 64 |  | -                           IREE::HAL::ExecutableTargetAttr targetAttr, | 
| 65 |  | -                           bool testCLGPUTarget = false) { | 
|  | 63 | +static LogicalResult materializeFuncOpEncodings( | 
|  | 64 | +    FunctionOpInterface funcOp, IREE::HAL::ExecutableTargetAttr targetAttr, | 
|  | 65 | +    ::mlir::iree_compiler::detail::TestingResolverKind resolverSource = | 
|  | 66 | +        ::mlir::iree_compiler::detail::TestingResolverKind::kNone) { | 
| 66 | 67 |   MLIRContext *ctx = funcOp.getContext(); | 
| 67 | 68 |   { | 
| 68 | 69 |     RewritePatternSet patterns(ctx); | 
| 69 | 70 |     DictionaryAttr targetConfig = | 
| 70 | 71 |         targetAttr ? targetAttr.getConfiguration() : nullptr; | 
| 71 |  | -    // Check if the encoding resolver is a GPUPaddingResolverAttr. For padding | 
| 72 |  | -    // encoding materialization, we use a separate pass, so skip materialization | 
| 73 |  | -    // here. | 
| 74 |  | -    // TODO(#20160): Support GPUPaddingResolverAttr materialization through this | 
| 75 |  | -    // pass, and remove the ad-hoc materialization pass for padding. | 
| 76 |  | -    if (targetConfig && targetConfig.getAs<IREE::GPU::GPUPaddingResolverAttr>( | 
| 77 |  | -                            IREE::Encoding::kEncodingResolverAttrName)) { | 
| 78 |  | -      LDBG() | 
| 79 |  | -          << "Found GPUPaddingResolverAttr encoding resolver. Materialization " | 
| 80 |  | -             "will be handled later."; | 
| 81 |  | -      return success(); | 
| 82 |  | -    } | 
| 83 |  | - | 
| 84 | 72 |     auto getTestTargetOrNopLayout = | 
| 85 | 73 |         [&]() -> IREE::Encoding::LayoutMaterializerAttr { | 
| 86 |  | -      if (testCLGPUTarget) { | 
|  | 74 | +      LDBG() << "Select GPUEncodingResolverAttr attribute as the layout " | 
|  | 75 | +                "attribute. (testCLGPUTarget)"; | 
|  | 76 | +      SmallVector<NamedAttribute> configItems; | 
|  | 77 | +      IREE::GPU::TargetAttr targetAttr = | 
|  | 78 | +          getGPUTargetAttr(ctx, /*target=*/nullptr); | 
|  | 79 | +      addConfigGPUTarget(ctx, targetAttr, configItems); | 
|  | 80 | +      switch (resolverSource) { | 
|  | 81 | +      case ::mlir::iree_compiler::detail::TestingResolverKind::kGPUDataTiling: { | 
| 87 | 82 |         LDBG() << "Select GPUEncodingResolverAttr attribute as the layout " | 
| 88 |  | -                  "attribute. (testCLGPUTarget)"; | 
| 89 |  | -        SmallVector<NamedAttribute> configItems; | 
| 90 |  | -        // Setting a nullptr to `target` below returns the target from command | 
| 91 |  | -        // line. | 
| 92 |  | -        IREE::GPU::TargetAttr targetAttr = | 
| 93 |  | -            getGPUTargetAttr(ctx, /*target=*/nullptr); | 
| 94 |  | -        addConfigGPUTarget(ctx, targetAttr, configItems); | 
|  | 83 | +                  "attribute. (kGPUDataTiling)"; | 
| 95 | 84 |         return cast<IREE::Encoding::LayoutMaterializerAttr>( | 
| 96 | 85 |             IREE::GPU::GPUEncodingResolverAttr::get( | 
| 97 | 86 |                 ctx, DictionaryAttr::get(ctx, configItems))); | 
| 98 | 87 |       } | 
|  | 88 | +      case ::mlir::iree_compiler::detail::TestingResolverKind::kGPUPadding: { | 
|  | 89 | +        LDBG() << "Select GPUPaddingResolverAttr attribute as the layout " | 
|  | 90 | +                  "attribute. (kGPUPadding)"; | 
|  | 91 | +        std::optional<IREE::GPU::L1CacheInfo> cache = | 
|  | 92 | +            IREE::GPU::getL1CacheInfo(targetAttr); | 
|  | 93 | +        return cast<IREE::Encoding::LayoutMaterializerAttr>( | 
|  | 94 | +            IREE::GPU::GPUPaddingResolverAttr::get(ctx, cache->cacheLineBytes, | 
|  | 95 | +                                                   cache->cacheSets)); | 
|  | 96 | +      } | 
|  | 97 | +      case ::mlir::iree_compiler::detail::TestingResolverKind::kNone: | 
|  | 98 | +        break; | 
|  | 99 | +      } | 
| 99 | 100 |       LDBG() << "Select IdentityResolverAttr attribute as the layout " | 
| 100 | 101 |                 "attribute (Encoding resolver unknown or unsupported)."; | 
| 101 | 102 |       return cast<IREE::Encoding::LayoutMaterializerAttr>( | 
| @@ -132,10 +133,10 @@ materializeFuncOpEncodings(FunctionOpInterface funcOp, | 
| 132 | 133 |     populateMaterializeEncodingPatterns(patterns, target, typeConverter); | 
| 133 | 134 | 
 | 
| 134 | 135 |     // Replace any unrealized conversions to tensor.cast ops if they come from | 
| 135 |  | -    // block arguments. The function signature is updated to match the converted | 
| 136 |  | -    // types after the partial conversion. This is used in testing, where | 
| 137 |  | -    // function arguments have encodings to reduce the amount of IR, but we do | 
| 138 |  | -    // not expect function arguments to have encodings in practice. | 
|  | 136 | +    // block arguments. The function signature is updated to match the | 
|  | 137 | +    // converted types after the partial conversion. This is used in testing, | 
|  | 138 | +    // where function arguments have encodings to reduce the amount of IR, but | 
|  | 139 | +    // we do not expect function arguments to have encodings in practice. | 
| 139 | 140 |     auto castFnArguments = [](OpBuilder &builder, Type resultTy, | 
| 140 | 141 |                               ValueRange inputs, Location loc) -> Value { | 
| 141 | 142 |       if (inputs.size() != 1) { | 
| @@ -174,11 +175,11 @@ materializeFuncOpEncodings(FunctionOpInterface funcOp, | 
| 174 | 175 |         patterns, [](OpOperand *opOperand) { | 
| 175 | 176 |           Operation *producer = opOperand->get().getDefiningOp(); | 
| 176 | 177 |           Operation *consumer = opOperand->getOwner(); | 
| 177 |  | -          // If we have a pack/unpack consumer and a producer that has multiple | 
| 178 |  | -          // uses, this _probably_ means the producer won't get dce'd. If that | 
| 179 |  | -          // is the case, by folding the consumer pack/unpack, we break the | 
| 180 |  | -          // producer consumer chain between them and inhibit fusion later in | 
| 181 |  | -          // the pipeline. | 
|  | 178 | +          // If we have a pack/unpack consumer and a producer that has | 
|  | 179 | +          // multiple uses, this _probably_ means the producer won't get | 
|  | 180 | +          // dce'd. If that is the case, by folding the consumer pack/unpack, | 
|  | 181 | +          // we break the producer consumer chain between them and inhibit | 
|  | 182 | +          // fusion later in the pipeline. | 
| 182 | 183 |           if (isa<linalg::PackOp, linalg::UnPackOp>(consumer) && | 
| 183 | 184 |               isa_and_nonnull<TilingInterface>(producer) && | 
| 184 | 185 |               !producer->hasOneUse()) | 
| @@ -301,7 +302,7 @@ struct MaterializeDeviceEncodingPass final | 
| 301 | 302 |     FunctionOpInterface funcOp = getOperation(); | 
| 302 | 303 |     auto executableTargetAttr = IREE::HAL::ExecutableTargetAttr::lookup(funcOp); | 
| 303 | 304 |     if (failed(materializeFuncOpEncodings(funcOp, executableTargetAttr, | 
| 304 |  | -                                          testCLGPUTarget))) { | 
|  | 305 | +                                          testGPUEncodingResolver))) { | 
| 305 | 306 |       return signalPassFailure(); | 
| 306 | 307 |     } | 
| 307 | 308 |   } | 
|  | 
0 commit comments