Files
TheRock/compiler/amd-llvm/mlir/lib/Dialect/GPU/Transforms/IndexedAccessOpInterfaceImpl.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

120 lines
4.8 KiB
C++

//===- IndexedAccessOpInterfaceImpl.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Implement IndexedAccessOpInterface on GPU dialect operations that have
// %memref[%i0, %i1, ...] arguments to allow them to be manipulated by
// generic memref-dialect passes.
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/GPU/Transforms/IndexedAccessOpInterfaceImpl.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/PatternMatch.h"
using namespace mlir;
using namespace mlir::memref;
using namespace mlir::gpu;
/// Given a GPU matrix type that will be loaded or stored, the leading dimension
/// of the matrix in memory, and whether or not the matrix is transposed,
/// compute the size of the linear memory that the load/store spans as
/// dC + leadingDim * (dR - 1) where dR and dC are the non-contiguous and
/// contiguous matrix dimensions, respectively (we get to the dX-1th row and
/// then access the first dY elements of it).
static int64_t get1DAccessSize(MMAMatrixType matrixType, int64_t leadingDim,
bool transpose) {
assert(matrixType.getShape().size() == 2 && "expected matrices to be 2D");
int64_t c = matrixType.getShape()[1];
int64_t r = matrixType.getShape()[0];
if (transpose)
std::swap(c, r);
return c + leadingDim * (r - 1);
}
namespace {
struct SubgroupMmaLoadMatrixOpImpl final
: IndexedAccessOpInterface::ExternalModel<SubgroupMmaLoadMatrixOpImpl,
SubgroupMmaLoadMatrixOp> {
TypedValue<MemRefType> getAccessedMemref(Operation *op) const {
return cast<SubgroupMmaLoadMatrixOp>(op).getSrcMemref();
}
Operation::operand_range getIndices(Operation *op) const {
return cast<SubgroupMmaLoadMatrixOp>(op).getIndices();
}
/// This returns a 1-D shape so that it's clear that both linearization and
/// folding in expand/collapse_shape operations are allowed.
SmallVector<int64_t> getAccessedShape(Operation *op) const {
auto loadOp = cast<SubgroupMmaLoadMatrixOp>(op);
return {get1DAccessSize(cast<MMAMatrixType>(loadOp.getRes().getType()),
loadOp.getLeadDimension().getZExtValue(),
loadOp.getTranspose().value_or(false))};
}
std::optional<SmallVector<Value>>
updateMemrefAndIndices(Operation *op, RewriterBase &rewriter, Value newMemref,
ValueRange newIndices) const {
auto loadOp = cast<SubgroupMmaLoadMatrixOp>(op);
rewriter.modifyOpInPlace(loadOp, [&]() {
loadOp.getSrcMemrefMutable().assign(newMemref);
loadOp.getIndicesMutable().assign(newIndices);
});
return std::nullopt;
}
bool hasInboundsIndices(Operation *) const { return true; }
};
struct SubgroupMmaStoreMatrixOpImpl final
: IndexedAccessOpInterface::ExternalModel<SubgroupMmaStoreMatrixOpImpl,
SubgroupMmaStoreMatrixOp> {
TypedValue<MemRefType> getAccessedMemref(Operation *op) const {
return cast<SubgroupMmaStoreMatrixOp>(op).getDstMemref();
}
Operation::operand_range getIndices(Operation *op) const {
return cast<SubgroupMmaStoreMatrixOp>(op).getIndices();
}
/// This returns a 1-D shape so that it's clear that both linearization and
/// folding in expand/collapse_shape operations are allowed.
SmallVector<int64_t> getAccessedShape(Operation *op) const {
auto storeOp = cast<SubgroupMmaStoreMatrixOp>(op);
return {get1DAccessSize(storeOp.getSrc().getType(),
storeOp.getLeadDimension().getZExtValue(),
storeOp.getTranspose().value_or(false))};
}
std::optional<SmallVector<Value>>
updateMemrefAndIndices(Operation *op, RewriterBase &rewriter, Value newMemref,
ValueRange newIndices) const {
auto storeOp = cast<SubgroupMmaStoreMatrixOp>(op);
rewriter.modifyOpInPlace(storeOp, [&]() {
storeOp.getDstMemrefMutable().assign(newMemref);
storeOp.getIndicesMutable().assign(newIndices);
});
return std::nullopt;
}
bool hasInboundsIndices(Operation *) const { return true; }
};
} // namespace
void mlir::gpu::registerIndexedAccessOpInterfaceExternalModels(
DialectRegistry &registry) {
registry.addExtension(+[](MLIRContext *ctx, gpu::GPUDialect *dialect) {
SubgroupMmaLoadMatrixOp::attachInterface<SubgroupMmaLoadMatrixOpImpl>(*ctx);
SubgroupMmaStoreMatrixOp::attachInterface<SubgroupMmaStoreMatrixOpImpl>(
*ctx);
});
}