diff --git a/.github/workflows/build-custom-llvm-tools.yaml b/.github/workflows/build-custom-llvm-tools.yaml index 618240848..fa87307f5 100644 --- a/.github/workflows/build-custom-llvm-tools.yaml +++ b/.github/workflows/build-custom-llvm-tools.yaml @@ -86,7 +86,7 @@ jobs: REF="$(python3 -c "import json; print(json.load(open('${CONFIG}'))['llvm_ref'])")" LLVM_REMOTE="$(python3 -c "import json; print(json.load(open('${CONFIG}')).get('llvm_remote', '${LLVM_REMOTE}'))")" else - REF="$(tr -d '[:space:]' < flydsl/thirdparty/llvm-hash.txt)" + REF="$(python3 -c "import json; print(json.load(open('flydsl/thirdparty/llvm-build-info.json'))['upstream']['llvm_hash'])")" fi # Resolve branch/tag to commit SHA for stable cache key diff --git a/.github/workflows/build-whl.yaml b/.github/workflows/build-whl.yaml index e7d654e31..cb8560d5b 100644 --- a/.github/workflows/build-whl.yaml +++ b/.github/workflows/build-whl.yaml @@ -103,7 +103,7 @@ jobs: uses: actions/cache@v4 with: path: mlir_install.tgz - key: mlir-install-manylinux228-${{ hashFiles('flydsl/thirdparty/llvm-hash.txt', 'flydsl/scripts/build_llvm.sh', 'flydsl/CMakeLists.txt') }} + key: mlir-install-manylinux228-${{ hashFiles('flydsl/thirdparty/llvm-build-info.json', 'flydsl/scripts/build_llvm.sh', 'flydsl/CMakeLists.txt') }} - name: Use cached MLIR install tarball if: steps.mlir-cache.outputs.cache-hit == 'true' @@ -163,7 +163,7 @@ jobs: SUMMARY_RELEASE_TYPE: ${{ inputs.release_type }} SUMMARY_WHEEL_DIR: dist run: | - SUMMARY_LLVM_COMMIT="$(tr -d '[:space:]' < flydsl/thirdparty/llvm-hash.txt)" + SUMMARY_LLVM_COMMIT="$(python3 -c "import json; print(json.load(open('flydsl/thirdparty/llvm-build-info.json'))['upstream']['llvm_hash'])")" export SUMMARY_LLVM_COMMIT python3 flydsl/scripts/generate_summary.py build diff --git a/.github/workflows/flydsl.yaml b/.github/workflows/flydsl.yaml index 2d038cefb..de6eb4983 100644 --- a/.github/workflows/flydsl.yaml +++ b/.github/workflows/flydsl.yaml @@ -147,7 +147,7 @@ jobs: uses: actions/cache/restore@v4 with: path: mlir_install.tgz - key: mlir-install-${{ runner.os }}-${{ runner.arch }}-${{ env.MLIR_CACHE_VERSION }}-${{ hashFiles('flydsl-test/thirdparty/llvm-hash.txt', 'flydsl-test/scripts/build_llvm.sh') }} + key: mlir-install-${{ runner.os }}-${{ runner.arch }}-${{ env.MLIR_CACHE_VERSION }}-${{ hashFiles('flydsl-test/thirdparty/llvm-build-info.json', 'flydsl-test/scripts/build_llvm.sh') }} - name: Start MLIR build container if: steps.mlir-cache.outputs.cache-hit != 'true' diff --git a/kernels/common/buffer_ops.py b/kernels/common/buffer_ops.py index 625f4ca88..f7c57e924 100644 --- a/kernels/common/buffer_ops.py +++ b/kernels/common/buffer_ops.py @@ -555,11 +555,11 @@ def buffer_load( if not isinstance(soffset.type, ir.IntegerType) or soffset.type.width != 32: op = std_arith.IndexCastOp(T.i32(), soffset) soffset = _unwrap_value(op.result) - aux_flags = _create_i32_constant(cache_modifier) + aux_attr = ir.IntegerAttr.get(ir.IntegerType.get_signless(32), cache_modifier) if cache_modifier else None # Emit buffer load load_op = rocdl.RawPtrBufferLoadOp( - result_type, rsrc, offset, soffset, aux_flags # soffset (scalar byte offset) # aux (cache modifiers) + result_type, rsrc, offset, soffset, aux=aux_attr ) return load_op.result @@ -642,9 +642,9 @@ def buffer_store( if not isinstance(soffset.type, ir.IntegerType) or soffset.type.width != 32: op = std_arith.IndexCastOp(T.i32(), soffset) soffset = _unwrap_value(op.result) - aux_flags = _create_i32_constant(cache_modifier) + aux_attr = ir.IntegerAttr.get(ir.IntegerType.get_signless(32), cache_modifier) if cache_modifier else None # Emit buffer store rocdl.RawPtrBufferStoreOp( - data, rsrc, offset, soffset, aux_flags # soffset (scalar byte offset) # aux (cache modifiers) + data, rsrc, offset, soffset, aux=aux_attr ) diff --git a/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp b/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp index 698564cc9..fe7098a76 100644 --- a/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp +++ b/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp @@ -378,10 +378,11 @@ class PtrLoadOpLowering : public OpConversionPattern { if (isTargetAddressSpace(flyPtrTy.getAddressSpace())) { BufferFatPtr bp(flyPtrTy, ptr); Value zero = arith::ConstantIntOp::create(rewriter, loc, 0, 32); + auto auxAttr = rewriter.getI32IntegerAttr(0); ArrayAttr noAttrs; Value loaded = ROCDL::RawPtrBufferLoadOp::create( rewriter, loc, loadTy, bp.bufferRsrc(rewriter, loc), bp.swizzleByteOffset(rewriter, loc), - zero, zero, noAttrs, noAttrs, noAttrs); + zero, auxAttr, noAttrs, noAttrs, noAttrs); rewriter.replaceOp(op, loaded); return success(); } else { @@ -423,10 +424,11 @@ class PtrStoreOpLowering : public OpConversionPattern { if (isTargetAddressSpace(flyPtrTy.getAddressSpace())) { BufferFatPtr bp(flyPtrTy, ptr); Value zero = arith::ConstantIntOp::create(rewriter, loc, 0, 32); + auto auxAttr = rewriter.getI32IntegerAttr(0); ArrayAttr noAttrs; ROCDL::RawPtrBufferStoreOp::create(rewriter, loc, value, bp.bufferRsrc(rewriter, loc), - bp.swizzleByteOffset(rewriter, loc), zero, zero, noAttrs, - noAttrs, noAttrs); + bp.swizzleByteOffset(rewriter, loc), zero, auxAttr, + noAttrs, noAttrs, noAttrs); rewriter.eraseOp(op); return success(); } else { diff --git a/lib/Dialect/Fly/IR/FlyOps.cpp b/lib/Dialect/Fly/IR/FlyOps.cpp index 41b02b1b9..10ff7a42d 100644 --- a/lib/Dialect/Fly/IR/FlyOps.cpp +++ b/lib/Dialect/Fly/IR/FlyOps.cpp @@ -190,9 +190,8 @@ Type applyOffsetOnTensorLike(LayoutBuilder &builder, Type tensorLike #define FLY_INFER_RETURN_TYPES(OP) \ llvm::LogicalResult OP::inferReturnTypes( \ mlir::MLIRContext *context, std::optional<::mlir::Location> location, \ - mlir::ValueRange operands, mlir::DictionaryAttr attributes, \ - mlir::OpaqueProperties properties, mlir::RegionRange regions, \ - llvm::SmallVectorImpl &inferredReturnTypes) + mlir::ValueRange operands, mlir::DictionaryAttr attributes, mlir::PropertyRef properties, \ + mlir::RegionRange regions, llvm::SmallVectorImpl &inferredReturnTypes) //===----------------------------------------------------------------------===// // Constructors diff --git a/lib/Dialect/Fly/Transforms/PromoteRegMemToVectorSSA.cpp b/lib/Dialect/Fly/Transforms/PromoteRegMemToVectorSSA.cpp index 7ef326586..28e73cfd6 100644 --- a/lib/Dialect/Fly/Transforms/PromoteRegMemToVectorSSA.cpp +++ b/lib/Dialect/Fly/Transforms/PromoteRegMemToVectorSSA.cpp @@ -27,14 +27,12 @@ using namespace mlir::fly; namespace llvm { -template <> struct DenseMapInfo : DenseMapInfo { - using Base = DenseMapInfo; - - static mlir::fly::MakePtrOp getEmptyKey() { return mlir::fly::MakePtrOp(Base::getEmptyKey()); } - - static mlir::fly::MakePtrOp getTombstoneKey() { - return mlir::fly::MakePtrOp(Base::getTombstoneKey()); +template <> struct DenseMapInfo { + static unsigned getHashValue(mlir::fly::MakePtrOp op) { + return DenseMapInfo::getHashValue(op.getAsOpaquePointer()); } + + static bool isEqual(mlir::fly::MakePtrOp lhs, mlir::fly::MakePtrOp rhs) { return lhs == rhs; } }; } // namespace llvm diff --git a/lib/Dialect/FlyROCDL/CDNA3/CopyAtom.cpp b/lib/Dialect/FlyROCDL/CDNA3/CopyAtom.cpp index 4b16116cb..22ab125f8 100644 --- a/lib/Dialect/FlyROCDL/CDNA3/CopyAtom.cpp +++ b/lib/Dialect/FlyROCDL/CDNA3/CopyAtom.cpp @@ -89,7 +89,7 @@ FailureOr CopyOpCDNA3BufferCopyType::emitAtomCallSSA(OpBuilder &builder, }; // raw buffer load/store cachepolicy (0=cached, 2=nt) - Value aux = arith::ConstantIntOp::create(builder, loc, getCacheModifier(), 32); + auto aux = builder.getI32IntegerAttr(getCacheModifier()); ArrayAttr noAttrs; auto srcMemTy = srcTyArg ? dyn_cast(srcTyArg) : fly::MemRefType(); @@ -321,8 +321,9 @@ LogicalResult CopyOpCDNA3BufferCopyLDSType::emitAtomCall(OpBuilder &builder, Loc Value srcOff = bp.swizzleByteOffset(builder, loc); ArrayAttr noAttrs; + auto auxAttr = builder.getI32IntegerAttr(0); ROCDL::RawPtrBufferLoadLdsOp::create(builder, loc, srcRsrc, dst, size, srcOff, soffset, immOffset, - zero, noAttrs, noAttrs, noAttrs); + auxAttr, noAttrs, noAttrs, noAttrs); return success(); } @@ -428,7 +429,7 @@ FailureOr CopyOpCDNA3BufferAtomicType::emitAtomCallSSA(OpBuilder &builder soffset = arith::DivUIOp::create(builder, loc, bits, eight); } - Value zero = arith::ConstantIntOp::create(builder, loc, 0, 32); + auto auxAttr = builder.getI32IntegerAttr(0); ArrayAttr noAttrs; AtomicOp op = getAtomicOp().getValue(); @@ -437,22 +438,22 @@ FailureOr CopyOpCDNA3BufferAtomicType::emitAtomCallSSA(OpBuilder &builder case AtomicOp::Add: if (!isFloat) return failure(); - ROCDL::RawPtrBufferAtomicFaddOp::create(builder, loc, src, dstRsrc, dstOff, soffset, zero, - noAttrs, noAttrs, noAttrs); + ROCDL::RawPtrBufferAtomicFaddOp::create(builder, loc, src.getType(), src, dstRsrc, dstOff, + soffset, auxAttr, noAttrs, noAttrs, noAttrs); break; case AtomicOp::Max: if (isFloat) - ROCDL::RawPtrBufferAtomicFmaxOp::create(builder, loc, src, dstRsrc, dstOff, soffset, zero, - noAttrs, noAttrs, noAttrs); + ROCDL::RawPtrBufferAtomicFmaxOp::create(builder, loc, src.getType(), src, dstRsrc, dstOff, + soffset, auxAttr, noAttrs, noAttrs, noAttrs); else - ROCDL::RawPtrBufferAtomicSmaxOp::create(builder, loc, src, dstRsrc, dstOff, soffset, zero, - noAttrs, noAttrs, noAttrs); + ROCDL::RawPtrBufferAtomicSmaxOp::create(builder, loc, src.getType(), src, dstRsrc, dstOff, + soffset, auxAttr, noAttrs, noAttrs, noAttrs); break; case AtomicOp::Min: if (isFloat) return failure(); - ROCDL::RawPtrBufferAtomicUminOp::create(builder, loc, src, dstRsrc, dstOff, soffset, zero, - noAttrs, noAttrs, noAttrs); + ROCDL::RawPtrBufferAtomicUminOp::create(builder, loc, src.getType(), src, dstRsrc, dstOff, + soffset, auxAttr, noAttrs, noAttrs, noAttrs); break; default: return failure(); diff --git a/lib/Dialect/FlyROCDL/CDNA3/MmaAtom.cpp b/lib/Dialect/FlyROCDL/CDNA3/MmaAtom.cpp index 25be7ceab..698fa27d7 100644 --- a/lib/Dialect/FlyROCDL/CDNA3/MmaAtom.cpp +++ b/lib/Dialect/FlyROCDL/CDNA3/MmaAtom.cpp @@ -169,8 +169,8 @@ FailureOr MmaOpCDNA3_MFMAType::emitAtomCallSSA(OpBuilder &builder, Locati #define DISPATCH_MFMA_SSA(M_, K_, PRED, OP) \ if (m == M_ && n == M_ && k == K_ && (PRED)) { \ - auto zeroAttr = builder.getI32IntegerAttr(0); \ - return ROCDL::OP::create(builder, loc, accTy, a, b, c, zeroAttr, zeroAttr, zeroAttr) \ + return ROCDL::OP::create(builder, loc, accTy, a, b, c, (uint32_t)0, (uint32_t)0, \ + ROCDL::MFMAPermB::none) \ .getResult(); \ } diff --git a/lib/Dialect/FlyROCDL/CDNA4/MmaAtom.cpp b/lib/Dialect/FlyROCDL/CDNA4/MmaAtom.cpp index c96cca662..01ee8eb8d 100644 --- a/lib/Dialect/FlyROCDL/CDNA4/MmaAtom.cpp +++ b/lib/Dialect/FlyROCDL/CDNA4/MmaAtom.cpp @@ -237,21 +237,19 @@ FailureOr MmaOpCDNA4_MFMAScaleType::emitAtomCallSSA(OpBuilder &builder, L Value scaleB = LLVM::ExtractValueOp::create( builder, loc, atomVal, ArrayRef{*getFieldIndex(AtomStateField::ScaleB)}); - auto cbszAttr = builder.getI32IntegerAttr(*aTypeCode); - auto blgpAttr = builder.getI32IntegerAttr(*bTypeCode); - auto opselAAttr = builder.getI32IntegerAttr(getOpselA()); - auto opselBAttr = builder.getI32IntegerAttr(getOpselB()); + auto cbsz = static_cast(*aTypeCode); + auto blgp = static_cast(*bTypeCode); + uint32_t opselA = getOpselA(); + uint32_t opselB = getOpselB(); if (m == 16 && n == 16 && k == 128) { - return ROCDL::mfma_scale_f32_16x16x128_f8f6f4::create(builder, loc, accTy, a, b, c, cbszAttr, - blgpAttr, opselAAttr, scaleA, opselBAttr, - scaleB) + return ROCDL::mfma_scale_f32_16x16x128_f8f6f4::create(builder, loc, accTy, a, b, c, cbsz, blgp, + opselA, scaleA, opselB, scaleB) .getResult(); } if (m == 32 && n == 32 && k == 64) { - return ROCDL::mfma_scale_f32_32x32x64_f8f6f4::create(builder, loc, accTy, a, b, c, cbszAttr, - blgpAttr, opselAAttr, scaleA, opselBAttr, - scaleB) + return ROCDL::mfma_scale_f32_32x32x64_f8f6f4::create(builder, loc, accTy, a, b, c, cbsz, blgp, + opselA, scaleA, opselB, scaleB) .getResult(); } diff --git a/lib/Dialect/FlyROCDL/GFX1250/CopyAtom.cpp b/lib/Dialect/FlyROCDL/GFX1250/CopyAtom.cpp index 676be7155..434d198e5 100644 --- a/lib/Dialect/FlyROCDL/GFX1250/CopyAtom.cpp +++ b/lib/Dialect/FlyROCDL/GFX1250/CopyAtom.cpp @@ -503,7 +503,7 @@ LogicalResult CopyOpGFX1250TDMType::emitAtomCall(OpBuilder &builder, Location lo vector::FromElementsOp::create(builder, loc, VectorType::get({8}, builder.getI32Type()), ValueRange{zero, zero, zero, zero, zero, zero, zero, zero}); - uint32_t cachePolicy = static_cast(getCacheModifier()); + auto cachePolicy = builder.getI32IntegerAttr(static_cast(getCacheModifier())); ArrayAttr noAliasScopes; if (isLoad) ROCDL::TensorLoadToLDSOp::create(builder, loc, dgroup0, dgroup1, dg2, dg3, dg4, cachePolicy, diff --git a/lib/Dialect/FlyROCDL/GFX1250/MmaAtom.cpp b/lib/Dialect/FlyROCDL/GFX1250/MmaAtom.cpp index 224cf74c9..ca7d87a03 100644 --- a/lib/Dialect/FlyROCDL/GFX1250/MmaAtom.cpp +++ b/lib/Dialect/FlyROCDL/GFX1250/MmaAtom.cpp @@ -238,24 +238,18 @@ static FailureOr emitWmmaSSA(OpBuilder &builder, Location loc, VectorType bool clamp = false) { Value res; if constexpr (Variant == WmmaVariant::ModsAllReuse) { - // Float path: no sign/clamp operands. - res = WmmaOp::create(builder, loc, accTy, - /*signA=*/false, a, /*signB=*/false, b, - /*modC=*/(uint16_t)0, c) + res = WmmaOp::create(builder, loc, accTy, a, b, ROCDL::WMMACModifier::none, c, + /*reuseA=*/false, /*reuseB=*/false) .getResult(); } else if constexpr (Variant == WmmaVariant::ModsC) { - // fp8 path: no sign/clamp operands. - res = WmmaOp::create(builder, loc, accTy, a, b, - /*modC=*/(uint16_t)0, c, + res = WmmaOp::create(builder, loc, accTy, a, b, ROCDL::WMMACModifier::none, c, /*reuseA=*/false, /*reuseB=*/false) .getResult(); } else if constexpr (Variant == WmmaVariant::ModsABClamp) { - // iu8: sign + reuse + clamp controls. res = WmmaOp::create(builder, loc, accTy, signA, a, signB, b, c, /*reuseA=*/false, /*reuseB=*/false, clamp) .getResult(); } else { - // IU form (e.g. iu4): sign/clamp controls but no reuseA/reuseB operands. static_assert(Variant == WmmaVariant::ModsIUClamp); res = WmmaOp::create(builder, loc, accTy, signA, a, signB, b, c, clamp).getResult(); } diff --git a/lib/Dialect/FlyROCDL/GFX1250/MmaAtomScale.cpp b/lib/Dialect/FlyROCDL/GFX1250/MmaAtomScale.cpp index fa2bdce5b..b4d173409 100644 --- a/lib/Dialect/FlyROCDL/GFX1250/MmaAtomScale.cpp +++ b/lib/Dialect/FlyROCDL/GFX1250/MmaAtomScale.cpp @@ -240,20 +240,20 @@ FailureOr MmaOpGFX1250_WMMAScaleType::emitAtomCallSSA(OpBuilder &builder, // the atom's compile-time params. block-16 selects the V_WMMA_SCALE16 form // (i64 scale operands); block-32 the V_WMMA_SCALE form (i32 scale operands). bool block16 = getBlockSize() == 16; + auto modC = static_cast(getModC()); + auto scaleAType = static_cast(getOpselA()); + auto scaleBType = static_cast(getOpselB()); + auto fmtScale0 = static_cast(0); + if (m == 32 && n == 16 && k == 128) { - // fp4-only form; no fmtA/fmtB operands. if (block16) return ROCDL::wmma_scale16_f32_32x16x128_f4::create( - builder, loc, accTy, a, b, /*modC=*/(uint16_t)getModC(), c, - /*scaleAType=*/(uint32_t)getOpselA(), /*fmtScaleA=*/(uint32_t)0, scaleA, - /*scaleBType=*/(uint32_t)getOpselB(), /*fmtScaleB=*/(uint32_t)0, scaleB, - /*reuseA=*/getReuseA(), /*reuseB=*/getReuseB()) + builder, loc, accTy, a, b, modC, c, scaleAType, fmtScale0, scaleA, scaleBType, + fmtScale0, scaleB, getReuseA(), getReuseB()) .getResult(); - return ROCDL::wmma_scale_f32_32x16x128_f4::create( - builder, loc, accTy, a, b, /*modC=*/(uint16_t)getModC(), c, - /*scaleAType=*/(uint32_t)getOpselA(), /*fmtScaleA=*/(uint32_t)0, scaleA, - /*scaleBType=*/(uint32_t)getOpselB(), /*fmtScaleB=*/(uint32_t)0, scaleB, - /*reuseA=*/getReuseA(), /*reuseB=*/getReuseB()) + return ROCDL::wmma_scale_f32_32x16x128_f4::create(builder, loc, accTy, a, b, modC, c, + scaleAType, fmtScale0, scaleA, scaleBType, + fmtScale0, scaleB, getReuseA(), getReuseB()) .getResult(); } @@ -262,20 +262,17 @@ FailureOr MmaOpGFX1250_WMMAScaleType::emitAtomCallSSA(OpBuilder &builder, if (!aFmt || !bFmt) return failure(); + auto fmtA = static_cast(*aFmt); + auto fmtB = static_cast(*bFmt); + if (block16) return ROCDL::wmma_scale16_f32_16x16x128_f8f6f4::create( - builder, loc, accTy, /*fmtA=*/*aFmt, a, /*fmtB=*/*bFmt, b, - /*modC=*/(uint16_t)getModC(), c, - /*scaleAType=*/(uint32_t)getOpselA(), /*fmtScaleA=*/(uint32_t)0, scaleA, - /*scaleBType=*/(uint32_t)getOpselB(), /*fmtScaleB=*/(uint32_t)0, scaleB, - /*reuseA=*/getReuseA(), /*reuseB=*/getReuseB()) + builder, loc, accTy, fmtA, a, fmtB, b, modC, c, scaleAType, fmtScale0, scaleA, + scaleBType, fmtScale0, scaleB, getReuseA(), getReuseB()) .getResult(); return ROCDL::wmma_scale_f32_16x16x128_f8f6f4::create( - builder, loc, accTy, /*fmtA=*/*aFmt, a, /*fmtB=*/*bFmt, b, - /*modC=*/(uint16_t)getModC(), c, - /*scaleAType=*/(uint32_t)getOpselA(), /*fmtScaleA=*/(uint32_t)0, scaleA, - /*scaleBType=*/(uint32_t)getOpselB(), /*fmtScaleB=*/(uint32_t)0, scaleB, - /*reuseA=*/getReuseA(), /*reuseB=*/getReuseB()) + builder, loc, accTy, fmtA, a, fmtB, b, modC, c, scaleAType, fmtScale0, scaleA, + scaleBType, fmtScale0, scaleB, getReuseA(), getReuseB()) .getResult(); } diff --git a/lib/Dialect/FlyROCDL/Ops.cpp b/lib/Dialect/FlyROCDL/Ops.cpp index a7440b4bc..c33db625d 100644 --- a/lib/Dialect/FlyROCDL/Ops.cpp +++ b/lib/Dialect/FlyROCDL/Ops.cpp @@ -15,7 +15,7 @@ using namespace mlir::fly_rocdl; LogicalResult GetBufferRsrcOp::inferReturnTypes(MLIRContext *context, std::optional location, ValueRange operands, DictionaryAttr attributes, - OpaqueProperties properties, RegionRange regions, + PropertyRef properties, RegionRange regions, SmallVectorImpl &inferredReturnTypes) { auto ptrTy = dyn_cast(operands[0].getType()); if (!ptrTy) diff --git a/python/flydsl/expr/rocdl/__init__.py b/python/flydsl/expr/rocdl/__init__.py index 4b18f15cc..d798836ec 100644 --- a/python/flydsl/expr/rocdl/__init__.py +++ b/python/flydsl/expr/rocdl/__init__.py @@ -54,6 +54,52 @@ mask_dsrd = 0x100 mask_dswr = 0x200 +_ods_sched_barrier = globals().get("sched_barrier") +_ods_sched_group_barrier = globals().get("sched_group_barrier") + +_SCHED_MASK_INT_TO_KW = { + 0x000: "none", + 0x001: "non_mem_non_sideeffect", + 0x002: "valu", + 0x004: "salu", + 0x008: "mfma_wmma", + 0x010: "all_vmem", + 0x020: "vmem_read", + 0x040: "vmem_write", + 0x080: "all_ds", + 0x100: "ds_read", + 0x200: "ds_write", + 0x400: "transcendental", + 0x800: "ldsdma", +} + + +def _mask_to_attr(mask): + """Convert an int or keyword mask to a SchedGroupMask attribute.""" + from ..._mlir import ir as _ir + + if isinstance(mask, _ir.Attribute): + return mask + if isinstance(mask, str): + return _ir.Attribute.parse(f"#rocdl") + val = int(mask) + if val == 0: + return _ir.Attribute.parse("#rocdl") + parts = [kw for bit, kw in _SCHED_MASK_INT_TO_KW.items() if bit and val & bit] + if not parts: + return _ir.Attribute.parse("#rocdl") + return _ir.Attribute.parse(f"#rocdl") + + +@dsl_loc_tracing +def sched_barrier(mask, **kw): + return _ods_sched_barrier(_mask_to_attr(mask), **kw) + + +@dsl_loc_tracing +def sched_group_barrier(mask, size, group_id, **kw): + return _ods_sched_group_barrier(_mask_to_attr(mask), size, group_id, **kw) + @dsl_loc_tracing def sched_mfma(cnt): @@ -201,6 +247,42 @@ def mfma_scale_f32_16x16x128_f8f6f4(result_type, operands): ).result +_WMMA_FMT_INT_TO_KW = {0: "fp8_e4m3", 1: "fp8_e5m2", 2: "fp6_e2m3", 3: "fp6_e3m2", 4: "fp4_e2m1"} +_WMMA_MODC_INT_TO_KW = {0: "none", 1: "neg", 2: "abs", 3: "neg_abs"} +_WMMA_SCALE_TYPE_INT_TO_KW = {0: "row0", 1: "row1"} +_WMMA_SCALE_FMT_INT_TO_KW = {0: "e8", 1: "e5m3", 2: "e4m3"} + + +def _wmma_attr(val, mapping, attr_name): + """Convert an int to a parsed ROCDL enum attribute for WMMA ops.""" + from ..._mlir import ir as _ir + + if val is None or isinstance(val, _ir.Attribute): + return val + if isinstance(val, bool): + return val + kw = mapping.get(int(val)) + if kw is None: + return val + return _ir.Attribute.parse(f"#rocdl<{attr_name} {kw}>") + + +def _wmma_fmt(val): + return _wmma_attr(val, _WMMA_FMT_INT_TO_KW, "matrix_format") + + +def _wmma_modc(val): + return _wmma_attr(val, _WMMA_MODC_INT_TO_KW, "wmma_c_modifier") + + +def _wmma_scale_type(val): + return _wmma_attr(val, _WMMA_SCALE_TYPE_INT_TO_KW, "wmma_matrix_scale") + + +def _wmma_scale_fmt(val): + return _wmma_attr(val, _WMMA_SCALE_FMT_INT_TO_KW, "wmma_matrix_scale_format") + + @dsl_loc_tracing def wmma_scale_f32_16x16x128_f8f6f4( result_type, @@ -247,13 +329,13 @@ def wmma_scale_f32_16x16x128_f8f6f4( c_v, sA, sB, - fmtA=fmtA, - fmtB=fmtB, - modC=modC, - scaleAType=scaleAType, - fmtScaleA=fmtScaleA, - scaleBType=scaleBType, - fmtScaleB=fmtScaleB, + fmtA=_wmma_fmt(fmtA), + fmtB=_wmma_fmt(fmtB), + modC=_wmma_modc(modC), + scaleAType=_wmma_scale_type(scaleAType), + fmtScaleA=_wmma_scale_fmt(fmtScaleA), + scaleBType=_wmma_scale_type(scaleBType), + fmtScaleB=_wmma_scale_fmt(fmtScaleB), reuseA=reuseA, reuseB=reuseB, ).result @@ -299,11 +381,11 @@ def wmma_scale_f32_32x16x128_f4( c_v, sA, sB, - modC=modC, - scaleAType=scaleAType, - fmtScaleA=fmtScaleA, - scaleBType=scaleBType, - fmtScaleB=fmtScaleB, + modC=_wmma_modc(modC), + scaleAType=_wmma_scale_type(scaleAType), + fmtScaleA=_wmma_scale_fmt(fmtScaleA), + scaleBType=_wmma_scale_type(scaleBType), + fmtScaleB=_wmma_scale_fmt(fmtScaleB), reuseA=reuseA, reuseB=reuseB, ).result @@ -323,7 +405,7 @@ def wmma_f32_16x16x128_fp8_fp8(result_type, a, b, c, *, modC=0, reuseA=False, re a_v = _unwrap_mfma_operand(a) b_v = _unwrap_mfma_operand(b) c_v = _unwrap_mfma_operand(c) - return _ods_wmma_f32_16x16x128_fp8_fp8(result_type, a_v, b_v, c_v, modC=modC, reuseA=reuseA, reuseB=reuseB).result + return _ods_wmma_f32_16x16x128_fp8_fp8(result_type, a_v, b_v, c_v, modC=_wmma_modc(modC), reuseA=reuseA, reuseB=reuseB).result @dsl_loc_tracing @@ -573,11 +655,30 @@ def perm_b32(src_hi, src_lo, sel, **kw): @dsl_loc_tracing -def raw_ptr_buffer_load_lds(rsrc, lds_ptr, size, voffset, soffset, offset, aux, **kw): +def raw_ptr_buffer_load(res, rsrc, offset, soffset, aux=None, **kw): + from ..._mlir import ir as _ir + from ..._mlir.dialects.rocdl import raw_ptr_buffer_load as _op + + if aux is not None and not isinstance(aux, _ir.Attribute): + if isinstance(aux, int): + aux = _ir.IntegerAttr.get(_ir.IntegerType.get_signless(32), aux) + else: + aux = None + return _op(res=res, rsrc=_to_ir(rsrc), offset=_to_ir(offset), soffset=_to_ir(soffset), aux=aux, **kw) + + +@dsl_loc_tracing +def raw_ptr_buffer_load_lds(rsrc, lds_ptr, size, voffset, soffset, offset, aux=None, **kw): + from ..._mlir import ir as _ir from ..._mlir.dialects.rocdl import raw_ptr_buffer_load_lds as _op + if aux is not None and not isinstance(aux, _ir.Attribute): + if isinstance(aux, int): + aux = _ir.IntegerAttr.get(_ir.IntegerType.get_signless(32), aux) + else: + aux = None return _op( - _to_ir(rsrc), _to_ir(lds_ptr), _to_ir(size), _to_ir(voffset), _to_ir(soffset), _to_ir(offset), _to_ir(aux), **kw + _to_ir(rsrc), _to_ir(lds_ptr), _to_ir(size), _to_ir(voffset), _to_ir(soffset), _to_ir(offset), aux=aux, **kw ) @@ -592,6 +693,32 @@ def buffer_load_to_lds(rsrc, lds_ptr, voffset, size_bytes=4, soffset=0, offset=0 return raw_ptr_buffer_load_lds(rsrc, lds_ptr, size_bytes, voffset, soffset, offset, 0, **kw) +@dsl_loc_tracing +def tensor_load_to_lds(dgroup0, dgroup1, dgroup2, dgroup3, dgroup4, cache_policy=None, **kw): + from ..._mlir import ir as _ir + from ..._mlir.dialects.rocdl import tensor_load_to_lds as _op + + if cache_policy is not None and not isinstance(cache_policy, _ir.Attribute): + if isinstance(cache_policy, int): + cache_policy = _ir.IntegerAttr.get(_ir.IntegerType.get_signless(32), cache_policy) + else: + cache_policy = None + return _op(dgroup0, dgroup1, dgroup2, dgroup3, dgroup4, cache_policy=cache_policy, **kw) + + +@dsl_loc_tracing +def tensor_store_from_lds(dgroup0, dgroup1, dgroup2, dgroup3, dgroup4, cache_policy=None, **kw): + from ..._mlir import ir as _ir + from ..._mlir.dialects.rocdl import tensor_store_from_lds as _op + + if cache_policy is not None and not isinstance(cache_policy, _ir.Attribute): + if isinstance(cache_policy, int): + cache_policy = _ir.IntegerAttr.get(_ir.IntegerType.get_signless(32), cache_policy) + else: + cache_policy = None + return _op(dgroup0, dgroup1, dgroup2, dgroup3, dgroup4, cache_policy=cache_policy, **kw) + + @dsl_loc_tracing def ds_bpermute(res, index, src, **kw): from ..._mlir.dialects.rocdl import ds_bpermute as _op diff --git a/python/flydsl/expr/rocdl/tdm_ops.py b/python/flydsl/expr/rocdl/tdm_ops.py index bea968c74..9d31fd904 100644 --- a/python/flydsl/expr/rocdl/tdm_ops.py +++ b/python/flydsl/expr/rocdl/tdm_ops.py @@ -70,6 +70,13 @@ ] +def _cache_policy_attr(val): + """Convert an int cache-policy to an IntegerAttr for TDM ops.""" + if val is None or isinstance(val, ir.Attribute): + return val + return ir.IntegerAttr.get(ir.IntegerType.get_signless(32), int(val)) + + # --------------------------------------------------------------------------- # Pure-Python helpers (compile-time, no IR emission) # --------------------------------------------------------------------------- @@ -769,7 +776,7 @@ def tensor_load_gather( _raw(desc.dgroup2), _raw(desc.dgroup3), dg4, - cache_policy, + cache_policy=_cache_policy_attr(cache_policy), ) @@ -794,7 +801,7 @@ def tensor_store_gather( _raw(desc.dgroup2), _raw(desc.dgroup3), dg4, - cache_policy, + cache_policy=_cache_policy_attr(cache_policy), ) @@ -1110,7 +1117,7 @@ def tensor_load_2d( dg2 = _raw(_zero_dgroup_v4i32()) dg3 = _raw(_zero_dgroup_v4i32()) dg4 = _raw(_zero_dgroup_v8i32()) - rocdl.tensor_load_to_lds(_raw(desc.dgroup0), _raw(desc.dgroup1), dg2, dg3, dg4, cache_policy) + rocdl.tensor_load_to_lds(_raw(desc.dgroup0), _raw(desc.dgroup1), dg2, dg3, dg4, cache_policy=_cache_policy_attr(cache_policy)) @dsl_loc_tracing @@ -1130,7 +1137,7 @@ def tensor_store_2d( dg2 = _raw(_zero_dgroup_v4i32()) dg3 = _raw(_zero_dgroup_v4i32()) dg4 = _raw(_zero_dgroup_v8i32()) - rocdl.tensor_store_from_lds(_raw(desc.dgroup0), _raw(desc.dgroup1), dg2, dg3, dg4, cache_policy) + rocdl.tensor_store_from_lds(_raw(desc.dgroup0), _raw(desc.dgroup1), dg2, dg3, dg4, cache_policy=_cache_policy_attr(cache_policy)) @dsl_loc_tracing @@ -1224,4 +1231,4 @@ def l2_prefetch_tile( # NOTE: rocdl.global_prefetch lowers to llvm.amdgcn.global.prefetch, which # requires LLVM ISel support for gfx1250 global_prefetch_b8. If the LLVM # build lacks this pattern, the instruction will be silently dropped. - rocdl.global_prefetch(ptr_val, scope) + rocdl.global_prefetch(ptr_val, cache_policy=_cache_policy_attr(scope)) diff --git a/scripts/build_internal_flydsl.sh b/scripts/build_internal_flydsl.sh new file mode 100755 index 000000000..1eaba4ee9 --- /dev/null +++ b/scripts/build_internal_flydsl.sh @@ -0,0 +1,151 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2025 FlyDSL Project Contributors +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +BASE_DIR="$(cd "${REPO_ROOT}/.." && pwd)" + +# --------------------------------------------------------------------------- +# Build directory (default: build-fly-internal/, overridable via FLY_BUILD_DIR) +# --------------------------------------------------------------------------- +BUILD_DIR="${FLY_BUILD_DIR:-${REPO_ROOT}/build-fly-internal}" +if [[ "${BUILD_DIR}" != /* ]]; then + BUILD_DIR="${REPO_ROOT}/${BUILD_DIR}" +fi + +# --------------------------------------------------------------------------- +# Parallelism: default $(nproc), overridable via -jN argument +# --------------------------------------------------------------------------- +PARALLEL_JOBS=$(nproc) +for arg in "$@"; do + if [[ "$arg" =~ ^-j([0-9]+)$ ]]; then + PARALLEL_JOBS="${BASH_REMATCH[1]}" + fi +done + +# --------------------------------------------------------------------------- +# Discover MLIR_PATH +# --------------------------------------------------------------------------- +# Read LLVM commit short hash for internal build path matching +LLVM_BUILD_INFO="${REPO_ROOT}/thirdparty/llvm-build-info.json" +LLVM_SHORT=$(python3 -c "import json; print(json.load(open('${LLVM_BUILD_INFO}'))['internal']['llvm_hash'][:8])") + +if [ -z "${MLIR_PATH:-}" ]; then + candidates=( + "${BASE_DIR}/llvm-project-internal/mlir_install-${LLVM_SHORT}" + "${BASE_DIR}/llvm-project-flydsl/build-flydsl/mlir_install" + "${BASE_DIR}/llvm-project/build-flydsl/mlir_install" + "${BASE_DIR}/llvm-project/mlir_install" + ) + for p in "${candidates[@]}"; do + if [ -d "${p}/lib/cmake/mlir" ]; then + echo "Auto-detected MLIR_PATH: ${p}" + export MLIR_PATH="${p}" + break + fi + done +fi + +if [ -z "${MLIR_PATH:-}" ]; then + echo "Error: MLIR_PATH not set and could not be auto-detected." >&2 + echo "Build LLVM/MLIR first: bash scripts/build_llvm.sh" >&2 + echo "Or set: export MLIR_PATH=/path/to/mlir_install" >&2 + exit 1 +fi + +# --------------------------------------------------------------------------- +# CMake generator: prefer Ninja, fall back to Unix Makefiles. +# If a CMakeCache.txt already exists, reuse its generator to avoid mismatch. +# --------------------------------------------------------------------------- +_CMAKE_CACHE="${BUILD_DIR}/CMakeCache.txt" +if [ -f "${_CMAKE_CACHE}" ]; then + CACHED_GENERATOR=$(awk '/^CMAKE_GENERATOR:INTERNAL=/{sub(/^CMAKE_GENERATOR:INTERNAL=/, ""); print; exit}' "${_CMAKE_CACHE}" || true) + if [ -n "${CACHED_GENERATOR}" ]; then + GENERATOR="${CACHED_GENERATOR}" + fi +else + GENERATOR="Unix Makefiles" + if command -v ninja &> /dev/null; then + GENERATOR="Ninja" + fi +fi + +echo "==============================================" +echo "FlyDSL Build" +echo " REPO_ROOT: ${REPO_ROOT}" +echo " BUILD_DIR: ${BUILD_DIR}" +echo " MLIR_PATH: ${MLIR_PATH}" +echo " PARALLEL: -j${PARALLEL_JOBS}" +echo " GENERATOR: ${GENERATOR}" +echo " HIP_PLATFORM: ${HIP_PLATFORM:-amd (default)}" +echo "==============================================" + +# --------------------------------------------------------------------------- +# Initialize git submodules if needed +# --------------------------------------------------------------------------- +if [ ! -f "${REPO_ROOT}/thirdparty/dlpack/include/dlpack/dlpack.h" ]; then + echo "Initializing git submodules..." + git -C "${REPO_ROOT}" submodule update --init --recursive +fi + +# --------------------------------------------------------------------------- +# Remove editable-install symlink that would cause CopyFlyPythonSources to +# overwrite the freshly built _mlir_libs with files from a different build. +# --------------------------------------------------------------------------- +_EDITABLE_MLIR_LINK="${REPO_ROOT}/python/flydsl/_mlir" +if [ -L "${_EDITABLE_MLIR_LINK}" ]; then + echo "Removing editable-install symlink: ${_EDITABLE_MLIR_LINK}" + rm -f "${_EDITABLE_MLIR_LINK}" +fi + +# --------------------------------------------------------------------------- +# CMake configure +# --------------------------------------------------------------------------- +NANOBIND_DIR=$(python3 -c "import nanobind; import os; print(os.path.dirname(nanobind.__file__) + '/cmake')" 2>/dev/null || true) + +mkdir -p "${BUILD_DIR}" +cd "${BUILD_DIR}" + +# HIP_PLATFORM: required by /opt/rocm/lib/cmake/hip/hip-config.cmake. +# The shipped hip-config.cmake has `if("OFF") ... set(hip_HIPCONFIG_EXECUTABLE) ...` +# so it cannot auto-detect the platform and relies on HIP_PLATFORM being +# provided as a CMake cache variable or environment variable. +HIP_PLATFORM="${HIP_PLATFORM:-amd}" + +cmake_args=( + -G "${GENERATOR}" + "${REPO_ROOT}" + -DMLIR_DIR="${MLIR_PATH}/lib/cmake/mlir" + -DPython3_EXECUTABLE="$(which python3)" + -DHIP_PLATFORM="${HIP_PLATFORM}" +) +if [ -n "${NANOBIND_DIR}" ]; then + cmake_args+=(-Dnanobind_DIR="${NANOBIND_DIR}") +fi + +echo "Configuring CMake..." +cmake "${cmake_args[@]}" + +# --------------------------------------------------------------------------- +# Build +# --------------------------------------------------------------------------- +echo "Building with -j${PARALLEL_JOBS}..." +cmake --build . -j"${PARALLEL_JOBS}" + +# --------------------------------------------------------------------------- +# Done +# --------------------------------------------------------------------------- +PYTHON_PKG_DIR="${BUILD_DIR}/python_packages" + +echo "" +echo "==============================================" +echo "Build complete!" +echo "" +echo "Usage (no install):" +echo " export PYTHONPATH=${PYTHON_PKG_DIR}:\${PYTHONPATH}" +echo "" +echo "Or install as editable package:" +echo " cd ${REPO_ROOT} && pip install -e ." +echo "==============================================" diff --git a/scripts/build_internal_llvm.sh b/scripts/build_internal_llvm.sh new file mode 100755 index 000000000..2e0edc540 --- /dev/null +++ b/scripts/build_internal_llvm.sh @@ -0,0 +1,149 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2025 FlyDSL Project Contributors +set -e + +# Default to downloading llvm-project in the parent directory of flydsl +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +BASE_DIR="$(cd "${REPO_ROOT}/.." && pwd)" +# Read LLVM commit hash and repository from thirdparty/llvm-build-info.json (internal entry) +LLVM_BUILD_INFO="${REPO_ROOT}/thirdparty/llvm-build-info.json" +LLVM_COMMIT_DEFAULT=$(python3 -c "import json; print(json.load(open('${LLVM_BUILD_INFO}'))['internal']['llvm_hash'])") +LLVM_REMOTE_DEFAULT=$(python3 -c "import json; print(json.load(open('${LLVM_BUILD_INFO}'))['internal']['repository'])") +LLVM_REF="${LLVM_REF:-${LLVM_COMMIT:-$LLVM_COMMIT_DEFAULT}}" +LLVM_SHORT="${LLVM_REF:0:8}" + +LLVM_SRC_DIR="$BASE_DIR/llvm-project-internal" +LLVM_BUILD_DIR="$LLVM_SRC_DIR/build-flydsl-${LLVM_SHORT}" +LLVM_INSTALL_DIR="${LLVM_INSTALL_DIR:-$LLVM_SRC_DIR/mlir_install-${LLVM_SHORT}}" +LLVM_INSTALL_TGZ="${LLVM_INSTALL_TGZ:-$LLVM_SRC_DIR/mlir_install-${LLVM_SHORT}.tgz}" +LLVM_PACKAGE_INSTALL="${LLVM_PACKAGE_INSTALL:-1}" + +echo "Base directory: $BASE_DIR" +echo "LLVM Source: $LLVM_SRC_DIR" +echo "LLVM Build: $LLVM_BUILD_DIR" +echo "LLVM Install: $LLVM_INSTALL_DIR" +echo "LLVM Tarball: $LLVM_INSTALL_TGZ" +echo "LLVM Ref: $LLVM_REF" + +# 1. Clone LLVM +LLVM_REMOTE="${LLVM_REMOTE:-$LLVM_REMOTE_DEFAULT}" + +if [ ! -d "$LLVM_SRC_DIR" ]; then + echo "Preparing llvm-project checkout for ${LLVM_REF} ..." + git init "$LLVM_SRC_DIR" + pushd "$LLVM_SRC_DIR" + git remote add origin "$LLVM_REMOTE" +else + pushd "$LLVM_SRC_DIR" +fi + +if [[ "$LLVM_REF" =~ ^[0-9a-fA-F]{40}$ ]]; then + if ! git cat-file -e "${LLVM_REF}^{commit}" 2>/dev/null; then + echo "Fetching commit ${LLVM_REF} ..." + git fetch --depth 1 origin "${LLVM_REF}" + fi + git checkout -f "${LLVM_REF}" +else + echo "Fetching ref ${LLVM_REF} ..." + git fetch --depth 1 origin "${LLVM_REF}" + git checkout -f FETCH_HEAD +fi +LLVM_COMMIT_RESOLVED=$(git rev-parse HEAD) +popd +echo "LLVM Commit: $LLVM_COMMIT_RESOLVED" + +# 2. Create Build Directory +mkdir -p "$LLVM_BUILD_DIR" +cd "$LLVM_BUILD_DIR" + +# 3. Configure CMake +echo "Configuring LLVM..." + +# Install dependencies for Python bindings +echo "Installing Python dependencies..." +pip install nanobind numpy pybind11 + +# Check for ninja +GENERATOR="Unix Makefiles" +if command -v ninja &>/dev/null; then + GENERATOR="Ninja" + echo "Using Ninja generator." +else + echo "Ninja not found. Using Unix Makefiles (this might be slower)." +fi + +# Build only MLIR and necessary Clang tools, targeting native architecture, in Release mode +# Explicitly set nanobind directory if found to help CMake locate it +NANOBIND_DIR=$(python3 -c "import nanobind; import os; print(os.path.dirname(nanobind.__file__) + '/cmake')") + +cmake -G "$GENERATOR" \ + -S "$LLVM_SRC_DIR/llvm" \ + -B "$LLVM_BUILD_DIR" \ + -DLLVM_ENABLE_PROJECTS="mlir;clang;lld" \ + -DLLVM_TARGETS_TO_BUILD="${LLVM_TARGETS_TO_BUILD:-X86;NVPTX;AMDGPU}" \ + -DLLVM_ENABLE_RUNTIMES="compiler-rt" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_STANDARD=17 \ + -DLLVM_ENABLE_ASSERTIONS=ON \ + -DLLVM_INSTALL_UTILS=ON \ + -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ + -DMLIR_BINDINGS_PYTHON_NB_DOMAIN=mlir \ + -DPython3_EXECUTABLE=$(which python3) \ + -Dnanobind_DIR="$NANOBIND_DIR" \ + -DBUILD_SHARED_LIBS=OFF \ + -DLLVM_BUILD_LLVM_DYLIB=OFF \ + -DLLVM_LINK_LLVM_DYLIB=OFF \ + -DMLIR_INCLUDE_TESTS=OFF \ + -DHIP_PLATFORM=amd \ + -DCMAKE_INSTALL_RPATH="\$ORIGIN" + +# 4. Build +PARALLEL_JOBS=$(($(nproc) / 2)) +for arg in "$@"; do + if [[ "$arg" =~ ^-j([0-9]+)$ ]]; then + PARALLEL_JOBS="${BASH_REMATCH[1]}" + elif [[ "$arg" == "--no-install" ]]; then + LLVM_PACKAGE_INSTALL=0 + fi +done +echo "Starting build with ${PARALLEL_JOBS} parallel jobs..." +cmake --build . -j${PARALLEL_JOBS} + +if [[ "${LLVM_PACKAGE_INSTALL}" == "1" ]]; then + echo "==============================================" + echo "Installing MLIR/LLVM to a clean prefix..." + rm -rf "${LLVM_INSTALL_DIR}" + mkdir -p "${LLVM_INSTALL_DIR}" + cmake --install "${LLVM_BUILD_DIR}" --prefix "${LLVM_INSTALL_DIR}" + + if [[ ! -d "${LLVM_INSTALL_DIR}/lib/cmake/mlir" ]]; then + echo "Error: install prefix missing lib/cmake/mlir: ${LLVM_INSTALL_DIR}" >&2 + exit 1 + fi + + echo "Creating tarball..." + # The install tree may still have files whose mtimes change (e.g. Python bytecode caches), + # which can cause GNU tar to exit(1) with "file changed as we read it". Treat those as + # non-fatal for packaging. + tar --warning=no-file-changed --warning=no-file-removed --ignore-failed-read \ + -C "$(dirname "${LLVM_INSTALL_DIR}")" \ + -czf "${LLVM_INSTALL_TGZ}" "$(basename "${LLVM_INSTALL_DIR}")" +fi + +echo "==============================================" +echo "LLVM/MLIR build completed successfully!" +echo "" +echo "To configure flydsl, use:" +echo "cmake .. -DMLIR_DIR=$LLVM_BUILD_DIR/lib/cmake/mlir" +if [[ "${LLVM_PACKAGE_INSTALL}" == "1" ]]; then + echo "" + echo "Packaged install prefix:" + echo " ${LLVM_INSTALL_DIR}" + echo "Use with:" + echo " export MLIR_PATH=${LLVM_INSTALL_DIR}" + echo "Tarball:" + echo " ${LLVM_INSTALL_TGZ}" +fi +echo "==============================================" diff --git a/scripts/build_llvm.sh b/scripts/build_llvm.sh index 3d5f3eff8..04d201fd1 100755 --- a/scripts/build_llvm.sh +++ b/scripts/build_llvm.sh @@ -13,9 +13,9 @@ LLVM_INSTALL_DIR="${LLVM_INSTALL_DIR:-$LLVM_SRC_DIR/mlir_install}" LLVM_INSTALL_TGZ="${LLVM_INSTALL_TGZ:-$LLVM_SRC_DIR/mlir_install.tgz}" LLVM_PACKAGE_INSTALL="${LLVM_PACKAGE_INSTALL:-1}" -# Read LLVM commit hash from thirdparty/llvm-hash.txt -LLVM_HASH_FILE="${REPO_ROOT}/thirdparty/llvm-hash.txt" -LLVM_COMMIT_DEFAULT=$(cat "${LLVM_HASH_FILE}" | tr -d '[:space:]') +# Read LLVM commit hash from thirdparty/llvm-build-info.json (upstream entry) +LLVM_BUILD_INFO="${REPO_ROOT}/thirdparty/llvm-build-info.json" +LLVM_COMMIT_DEFAULT=$(python3 -c "import json; print(json.load(open('${LLVM_BUILD_INFO}'))['upstream']['llvm_hash'])") LLVM_REF="${LLVM_REF:-${LLVM_COMMIT:-$LLVM_COMMIT_DEFAULT}}" echo "Base directory: $BASE_DIR" diff --git a/thirdparty/llvm-build-info.json b/thirdparty/llvm-build-info.json new file mode 100644 index 000000000..94808c943 --- /dev/null +++ b/thirdparty/llvm-build-info.json @@ -0,0 +1,14 @@ +{ + "upstream": { + "repository": "https://github.com/llvm/llvm-project.git", + "llvm_hash": "e2a39f504fee836e4def9581bed817ecc327b9dc" + }, + "internal": { + "repository": "https://github.com/AMD-Lightning-Internal/llvm-project.git", + "llvm_hash": "bb14ae08181afd90001877331f5515aa844e647e" + }, + "custom1" :{ + "repository": "https://github.com/AMD-Lightning-Internal/llvm-project.git", + "branch": "" + } +} diff --git a/thirdparty/llvm-hash.txt b/thirdparty/llvm-hash.txt deleted file mode 100644 index 34f77b2e4..000000000 --- a/thirdparty/llvm-hash.txt +++ /dev/null @@ -1 +0,0 @@ -7f77ca0dbda4abbf9af06537b2c475f20ccd6007