Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

cmake_minimum_required(VERSION 3.20.0)

include(cmake/fetch_cann_cmake.cmake)

# CANN/Ascend CMake packages used by downstream PTOAS builds may still use the
# pre-CMake-3.30 FetchContent_Populate(<declared-name>) pattern. Keep that
# compatibility path enabled so CMake 4.x developer warnings do not become
Expand All @@ -29,6 +27,8 @@ if(POLICY CMP0175)
set(CMAKE_POLICY_DEFAULT_CMP0175 OLD)
endif()

include(cmake/fetch_cann_cmake.cmake)

# Standard Python build backends pass environment variables through to CMake
# but do not synthesize project-specific cache arguments. Accept the existing
# LLVM_BUILD_DIR convention directly so `pip wheel .` and `pip install .` can
Expand Down
9 changes: 7 additions & 2 deletions cmake/fetch_cann_cmake.cmake
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
# -----------------------------------------------------------------------------------------------------------
# Copyright (c) 2026 Huawei Technologies Co., Ltd.
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
# CANN Open Software License Agreement Version 2.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
# -----------------------------------------------------------------------------------------------------------

if(NOT PROJECT_SOURCE_DIR)
# Standalone builds may configure without a pre-seeded CANN third-party
# directory (e.g. CI). Keep FetchContent's declared SOURCE_DIR inside the
# writable CMake binary tree instead of resolving an empty variable to the
# filesystem root. Script-mode packaging still requires an explicit path.
if(NOT CANN_3RD_LIB_PATH AND CMAKE_BINARY_DIR)
set(CANN_3RD_LIB_PATH "${CMAKE_BINARY_DIR}/cann-3rd-lib")
endif()
# Temporary test pin for cann/cmake MR !277. Revert this URL/ref pair
# after validation and switch to the released cann/cmake tag once MR !277
# is merged.
Expand Down
14 changes: 14 additions & 0 deletions lib/PTO/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ add_mlir_dialect_library(PTOTransforms
TileFusion/PTOUnrollAfterLoopFusion.cpp
TileFusion/PTOFlattenFusionRegion.cpp
VPTOLLVMEmitter.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterCommon.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterBasic.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterVector.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterVectorReduction.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterVectorPredicate.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterMemory.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterCubeMad.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterCubeMemory.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterVectorMemory.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterVectorGather.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterUbuf.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterScalarRuntime.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterSyncConfig.cpp
VPTOLLVMEmitter/VPTOLLVMEmitterVcvt.cpp
VPTOCANN900LLVMEmitter.cpp
VPTOCANN900LLVMEmitterArithmeticPatterns.cpp
VPTOCANN900LLVMEmitterCalleeCore.cpp
Expand Down
12 changes: 6 additions & 6 deletions lib/PTO/Transforms/VPTOCANN900LLVMEmitterCalleeCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ FailureOr<StringRef> buildPstuCallee(MLIRContext *context, pto::PstuOp op) {
}

FailureOr<StringRef> buildVstusCallee(MLIRContext *context, Type valueType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
auto lanes = getElementCountFromVectorLike(valueType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -90,7 +90,7 @@ FailureOr<StringRef> buildVstusCallee(MLIRContext *context, Type valueType) {
}

FailureOr<StringRef> buildVstusPostCallee(MLIRContext *context, Type valueType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
auto lanes = getElementCountFromVectorLike(valueType);
if (vec.empty() || !lanes) {
return failure();
Expand Down Expand Up @@ -399,7 +399,7 @@ FailureOr<StringRef> buildConvertCallee(MLIRContext *context, Type srcType, Type
}

FailureOr<StringRef> buildVldsPostCallee(MLIRContext *context, Type resultType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
auto lanes = getElementCountFromVectorLike(resultType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -408,7 +408,7 @@ FailureOr<StringRef> buildVldsPostCallee(MLIRContext *context, Type resultType)
}

FailureOr<StringRef> buildVstsPostCallee(MLIRContext *context, Type valueType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
auto lanes = getElementCountFromVectorLike(valueType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -419,7 +419,7 @@ FailureOr<StringRef> buildVstsPostCallee(MLIRContext *context, Type valueType) {
StringRef buildVldasCallee(MLIRContext *context) { return StringAttr::get(context, "llvm.hivm.vldas").getValue(); }

FailureOr<StringRef> buildVldusCallee(MLIRContext *context, Type resultType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
auto lanes = getElementCountFromVectorLike(resultType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -428,7 +428,7 @@ FailureOr<StringRef> buildVldusCallee(MLIRContext *context, Type resultType) {
}

FailureOr<StringRef> buildVldusPostCallee(MLIRContext *context, Type resultType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
auto lanes = getElementCountFromVectorLike(resultType);
if (vec.empty() || !lanes) {
return failure();
Expand Down
51 changes: 6 additions & 45 deletions lib/PTO/Transforms/VPTOCANN900LLVMEmitterCalleeMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,45 +89,6 @@ FailureOr<StringRef> buildCopyGmToCbufMultiNd2NzCallee(MLIRContext *context, Typ
return StringAttr::get(context, "llvm.hivm.MOV.OUT.TO.L1.MULTI.ND2NZ." + elem + ".V310").getValue();
}

std::string getDn2NzCopyElementFragment(Type type) {
auto ptrType = dyn_cast<pto::PtrType>(type);
if (!ptrType) {
return {};
}

Type elementType = ptrType.getElementType();
std::string typeText;
llvm::raw_string_ostream os(typeText);
elementType.print(os);
os.flush();
std::string lower = StringRef(typeText).lower();
if (StringRef(lower).contains("e4m3") || StringRef(lower).contains("e5m2") || StringRef(lower).contains("e8m0") ||
StringRef(lower).contains("hif8")) {
return "u8";
}

if (elementType.isF16() || elementType.isBF16()) {
return "u16";
}
if (elementType.isF32()) {
return "u32";
}

if (auto intType = dyn_cast<IntegerType>(elementType)) {
switch (intType.getWidth()) {
case 8:
return "u8";
case 16:
return "u16";
case 32:
return "u32";
default:
return {};
}
}
return {};
}

FailureOr<StringRef> buildCopyGmToCbufMultiDn2NzCallee(MLIRContext *context, Type sourceType) {
auto ptrType = dyn_cast<pto::PtrType>(sourceType);
if (!ptrType) {
Expand Down Expand Up @@ -327,7 +288,7 @@ FailureOr<StringRef> buildVmullCallee(MLIRContext *context, Type resultType) {
}

FailureOr<StringRef> buildVldsCallee(MLIRContext *context, Type resultType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
auto lanes = getElementCountFromVectorLike(resultType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -336,7 +297,7 @@ FailureOr<StringRef> buildVldsCallee(MLIRContext *context, Type resultType) {
}

FailureOr<StringRef> buildVldsx2Callee(MLIRContext *context, Type resultType, bool post) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(resultType));
auto lanes = getElementCountFromVectorLike(resultType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -359,7 +320,7 @@ FailureOr<StringRef> buildBlockStridedMemoryCallee(MLIRContext *context, Type ve
} else if (isLowpPayloadElementType(elementType)) {
element = "i8";
} else {
element = getMemoryElementTypeFragment(elementType);
element = getCANN900MemoryElementTypeFragment(elementType);
}
if (element.empty()) {
return failure();
Expand All @@ -375,7 +336,7 @@ FailureOr<StringRef> buildVsldbCallee(MLIRContext *context, Type resultType, boo
}

FailureOr<StringRef> buildVstsCallee(MLIRContext *context, Type valueType) {
std::string vec = getMemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
std::string vec = getCANN900MemoryElementTypeFragment(getElementTypeFromVectorLike(valueType));
auto lanes = getElementCountFromVectorLike(valueType);
if (vec.empty() || !lanes) {
return failure();
Expand All @@ -390,7 +351,7 @@ FailureOr<StringRef> buildVstsx2Callee(MLIRContext *context, Type valueType) {
return failure();
}

std::string element = getMemoryElementTypeFragment(elementType);
std::string element = getCANN900MemoryElementTypeFragment(elementType);
if (element.empty()) {
return failure();
}
Expand Down Expand Up @@ -619,7 +580,7 @@ FailureOr<VcvtContract> buildVcvtContract(pto::VcvtOp op) {
return *contract;
}

bool needsV300CtrlModeForVPTOFunc(func::FuncOp funcOp) {
bool needsV300CtrlModeForCANN900Func(func::FuncOp funcOp) {
if (!pto::isPTOEntryFunction(funcOp) || funcOp.getBlocks().empty()) {
return false;
}
Expand Down
64 changes: 3 additions & 61 deletions lib/PTO/Transforms/VPTOCANN900LLVMEmitterInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "PTO/Transforms/Passes.h"
#include "PTO/Transforms/VPTOLLVMEmitter.h"
#include "PTO/Transforms/VPTOLLVMEmitterHelper.h"
#include "VPTOLLVMEmitter/VPTOLLVMEmitterInternal.h"

#include "mlir/Conversion/Passes.h"
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
Expand Down Expand Up @@ -59,15 +60,6 @@ namespace detail {
inline constexpr llvm::StringLiteral kVectorSuffix = "_mix_aiv";
inline constexpr llvm::StringLiteral kCubeSuffix = "_mix_aic";

struct PlannedDecl {
std::string name;
FunctionType type;
};

struct LoweringState {
SmallVector<PlannedDecl> plannedDecls;
};

enum class VcvtElemKind {
Invalid,
F16,
Expand Down Expand Up @@ -108,37 +100,6 @@ struct LowpPayloadABI {
StringRef intrinsicElementFragment;
};

Type convertVPTOType(Type type, Builder &builder);
Value materializeVPTOCast(OpBuilder &builder, Type resultType, ValueRange inputs, Location loc);

class VPTOTypeConverter final : public TypeConverter {
public:
explicit VPTOTypeConverter(MLIRContext *context) {
addConversion([](Type type) { return type; });
addConversion([](Type type) -> Type {
Builder builder(type.getContext());
return convertVPTOType(type, builder);
});
addSourceMaterialization(materializeVPTOCast);
addTargetMaterialization(materializeVPTOCast);
}
};

Type getLowPrecisionLLVMType(Type type, MLIRContext *context);
bool isLLVMExtensionVectorElementType(Type type);
Type getLLVMCompatibleVectorType(ArrayRef<int64_t> shape, Type elementType, ArrayRef<bool> scalableDims);
Type normalizePayloadTypeForLLVMLowering(Type type, Builder &builder);
Type normalizeGEPElementTypeForLLVMLowering(Type type, Builder &builder);
Type convertVPTOType(Type type, Builder &builder);
unsigned getNaturalByteAlignment(Type type);
bool hasVPTOConvertibleType(Type type);
bool hasVPTOConvertibleType(TypeRange types);
Value materializeVPTOCast(OpBuilder &builder, Type resultType, ValueRange inputs, Location loc);
LLVM::LLVMStructType getVPTOStructStorageType(pto::StructType structType, Builder &builder);
FailureOr<Value> getVPTOStructFieldAddress(ConversionPatternRewriter &rewriter, Location loc, Value root,
pto::StructType rootType, ArrayRef<int64_t> path);
Value getI64Constant(OpBuilder &builder, Location loc, uint64_t value);
Value getI32Constant(OpBuilder &builder, Location loc, uint64_t value);
Value getI1Constant(OpBuilder &builder, Location loc, bool value);
bool isMxElementType(Type ty);
std::string getMadMxElementFragment(Type type);
Expand All @@ -147,9 +108,7 @@ bool isSignedOrSignlessInteger(IntegerType intType, unsigned width);
std::string getMadRhsFragment(Type type);
bool isMadE4M3ElementType(Type type);
bool isMadE5M2ElementType(Type type);
std::string getMadDstFragment(Type type);
ArrayRef<MadCalleeContract> getMadCalleeContracts();
std::string getMadLhsFragment(Type type);
FailureOr<StringRef> buildMadTypedCalleeName(MLIRContext *context, Type lhsElem, Type rhsElem, Type dstElem);
FailureOr<StringRef> buildLaneTypedCallee(MLIRContext *context, Type resultType, StringRef stem, StringRef suffix);
std::string getCANN900VectorElementFragment(Type type);
Expand All @@ -160,9 +119,7 @@ FailureOr<StringRef> buildCANN900SignedModeTypedCallee(MLIRContext *context, Typ
StringRef mode);
FailureOr<StringRef> buildCANN900WideningReductionCallee(MLIRContext *context, Type inputType, Type resultType,
StringRef stem, StringRef mode);
std::string getElementTypeFragment(Type type);
std::string getLowPrecisionElementFragment(Type type);
std::string getMemoryElementTypeFragment(Type type);
std::string getCANN900MemoryElementTypeFragment(Type type);
bool isLowpPayloadElementType(Type type);
std::optional<LowpPayloadABI> getLowpPayloadABI(Type elementType, MLIRContext *context);
std::string getDirectLowpVLogicElementFragment(Type type);
Expand All @@ -178,24 +135,13 @@ std::string getAtomicElementTypeFragment(Type type, Attribute signednessAttr);
std::string getL0LoadElementFragment(Type type);
std::string getShuffleIntrinsicTypeFragment(Type type);
std::string getReduxIntrinsicTypeFragment(Type type, Attribute signednessAttr);
Type getElementTypeFromVectorLike(Type type);
std::optional<int64_t> getElementCountFromVectorLike(Type type);
Value castIntegerLikeTo(Operation *anchor, Value value, Type targetType);
FailureOr<Value> reinterpretPointerToAddrSpace(Operation *anchor, Value value, unsigned targetAddressSpace);
FailureOr<Value> normalizeVdupScalarOperand(OpBuilder &builder, Location loc, Value input, Type resultType);
Value normalizeByteScalarOperandForCANN900VectorCall(OpBuilder &builder, Location loc, Value input,
Type semanticElementType);
bool isCompatibleScalarForSemanticType(Type semanticType, Type scalarType);
std::string getCopyElementFragment(Type elementType);
std::string getNd2NzCopyElementFragment(Type elementType);
std::optional<uint64_t> parsePredicatePatternImmediate(StringRef pattern);
std::optional<uint64_t> parseHiLoPartImmediate(StringRef part);
std::optional<uint64_t> parseRoundModeImmediate(StringRef roundMode);
std::optional<uint64_t> parseSaturationImmediate(StringRef sat);
std::optional<uint64_t> parsePartImmediate(StringRef part);
std::optional<uint64_t> parseVcvtPartImmediate(StringRef part);
std::optional<uint64_t> parsePredicateStoreDistImmediate(StringRef dist);
std::optional<uint64_t> parsePredicateLoadDistImmediate(StringRef dist);
std::optional<int32_t> parsePostModeImmediate(StringRef mode);
std::optional<uint64_t> parsePipeImmediate(StringRef pipe);
std::optional<uint64_t> parseEventImmediate(StringRef event);
Expand All @@ -208,13 +154,10 @@ std::optional<uint64_t> parseLoadDistImmediate(StringRef dist, Type elementType)
FailureOr<Value> packShiftedFields(Operation *anchor, Value base, ArrayRef<std::pair<Value, uint64_t>> fields);
std::optional<uint64_t> parseLoadX2DistImmediate(StringRef dist, Type elementType);
std::optional<uint64_t> parseStoreDistImmediate(StringRef dist, Type elementType);
bool isOnePointStoreDist(StringRef dist);
bool isMaskOnlyUsedByOnePointStores(Value mask);
std::optional<uint64_t> parseStoreX2DistImmediate(StringRef dist, Type elementType);
Value packBlockRepeatStride(Operation *anchor, Value blockStride, Value repeatStride);
std::optional<uint64_t> parseOrderImmediate(StringRef order);
FailureOr<Value> packLoopPair(Operation *anchor, Value low, Value high);
FailureOr<Value> packLoopSize(Operation *anchor, Value loop2, Value loop1);
FailureOr<Value> packCopyGmToUbConfig0(Operation *anchor, ValueRange operands);
FailureOr<Value> packCopyGmToUbConfig1(Operation *anchor, ValueRange operands);
FailureOr<Value> packCopyGmToUbConfig0(Operation *anchor, Value sid, Value nBurst, Value lenBurst, Value leftPadding,
Expand Down Expand Up @@ -294,7 +237,6 @@ FailureOr<StringRef> buildOrdinaryMadCallee(MLIRContext *context, pto::MadRawOpI
FailureOr<StringRef> buildMxMadCallee(MLIRContext *context, pto::MadRawOpInterface op);
FailureOr<StringRef> buildCopyGmToCbufCallee(MLIRContext *context, Type sourceType);
FailureOr<StringRef> buildCopyGmToCbufMultiNd2NzCallee(MLIRContext *context, Type sourceType);
std::string getDn2NzCopyElementFragment(Type type);
FailureOr<StringRef> buildCopyGmToCbufMultiDn2NzCallee(MLIRContext *context, Type sourceType);
FailureOr<StringRef> buildLoadCbufToCaCallee(MLIRContext *context, Type sourceType);
FailureOr<StringRef> buildLoadCbufToCbCallee(MLIRContext *context, Type sourceType);
Expand Down Expand Up @@ -351,7 +293,7 @@ FailureOr<StringRef> buildVmrgsort4Callee(MLIRContext *context, pto::Vmrgsort4Op
FailureOr<Value> packVmrgsort4SourceAddr(Operation *anchor, Value source0, Value source1, Value source2, Value source3,
Type elemType);
FailureOr<VcvtContract> buildVcvtContract(pto::VcvtOp op);
bool needsV300CtrlModeForVPTOFunc(func::FuncOp funcOp);
bool needsV300CtrlModeForCANN900Func(func::FuncOp funcOp);
FailureOr<Value> encodeMovPadValue(Location loc, Value value, ConversionPatternRewriter &rewriter);
StringRef buildMemBarCallee(MemBarKind kind, MLIRContext *context);
uint64_t getDsbMemImmediate(DsbMem kind);
Expand Down
Loading
Loading