diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 111847a1..afc92bac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -204,6 +204,15 @@ jobs: cp test/npu_validation/scripts/generate_testcase.py "${PAYLOAD_DIR}/test/npu_validation/scripts/" cp test/npu_validation/scripts/run_remote_npu_validation.sh "${PAYLOAD_DIR}/test/npu_validation/scripts/" cp test/npu_validation/templates/* "${PAYLOAD_DIR}/test/npu_validation/templates/" + while IFS= read -r -d '' file; do + dst="${PAYLOAD_DIR}/${file}" + mkdir -p "$(dirname "${dst}")" + cp "${file}" "${dst}" + done < <( + find test/samples \ + \( -path '*/npu_validation/*' -o -name '*_golden.py' -o -name '*_compare.py' -o -name 'validation_runtime.py' \) \ + -type f -print0 + ) chmod +x "${PAYLOAD_DIR}/test/npu_validation/scripts/run_remote_npu_validation.sh" tar -czf "${PAYLOAD_TGZ}" -C "${PAYLOAD_DIR}" . @@ -270,7 +279,7 @@ jobs: # suite (RUN_ONLY_CASES is empty), skip the non-matching variant based # on SOC_VERSION to keep the remote validation portable. A3_ONLY_CASES="partition5d,partition5d_dynamic,mrgsort,tmatmulk_autosync" - A5_ONLY_CASES="partition5d_a5,partition5d_dynamic_a5,mrgsort_a5,tmatmulk_autosync_a5" + A5_ONLY_CASES="partition5d_a5,partition5d_dynamic_a5,mrgsort_a5,tmatmulk_autosync_a5,plan_memory_scopes_independent" sv_lc="$(printf '%s' "${SOC_VERSION}" | tr '[:upper:]' '[:lower:]')" is_a5=0 diff --git a/lib/PTO/IR/PTO.cpp b/lib/PTO/IR/PTO.cpp index 02670518..5ac57919 100644 --- a/lib/PTO/IR/PTO.cpp +++ b/lib/PTO/IR/PTO.cpp @@ -2566,7 +2566,8 @@ mlir::LogicalResult mlir::pto::TPReluOp::verify() { Type e0 = getElemTy(t0), e1 = getElemTy(t1), et = getElemTy(tt), ed = getElemTy(td); if (!e0 || !e1 || !et || !ed) return emitOpError("failed to get element type for operands"); - // TPRELU C++ API (TPreluCheck): dst/src0/src1 same type (half or float); tmp must be uint8_t. + // TPRELU C++ API (TPreluCheck): dst/src0/src1 same type (half or float); + // tmp must be uint8_t. if (e0 != e1 || e0 != ed) return emitOpError("expects src0/src1/dst to have the same element type (f16 or f32)"); if (!e0.isa() || (!e0.isF16() && !e0.isF32())) @@ -2793,6 +2794,42 @@ mlir::LogicalResult mlir::pto::TRowExpandOp::verify() { return emitOpError("expects src/dst to have the same element type"); return mlir::success(); } + +static mlir::LogicalResult verifyTRowExpandLike(Operation *op, Type src0Ty, + Type src1Ty, Type dstTy, + Type elemTy) { + auto s0 = getShapeVec(src0Ty), s1 = getShapeVec(src1Ty), sd = getShapeVec(dstTy); + if (s0.size() != 2 || s1.size() != 2 || sd.size() != 2) + return op->emitError("expects rank-2 shaped operands"); + auto elemBytes = getElemBytes(elemTy); + if (!elemBytes || *elemBytes <= 0) + return op->emitError("unsupported element type"); + + int64_t blockCols = 32 / *elemBytes; + auto isPerRowShape = [&](ArrayRef shape) { + return shape[0] == sd[0] && (shape[1] == 1 || shape[1] == blockCols); + }; + + bool src0EqDst = s0 == sd; + bool src1EqDst = s1 == sd; + if (src0EqDst == src1EqDst) + return op->emitError( + "expects exactly one source to match dst shape and the other to provide one scalar per row"); + + if (src0EqDst) { + if (!isPerRowShape(s1)) + return op->emitError() << "expects src1 shape to be [" << sd[0] + << " x 1] or [" << sd[0] << " x " << blockCols + << "] when src0 matches dst"; + return success(); + } + + if (!isPerRowShape(s0)) + return op->emitError() << "expects src0 shape to be [" << sd[0] + << " x 1] or [" << sd[0] << " x " << blockCols + << "] when src1 matches dst"; + return success(); +} //===----------------------------------------------------------------------===// // PTO.cpp (add verifier for TROWEXPANDDIV DPS/tilebuf op) //===----------------------------------------------------------------------===// @@ -2811,7 +2848,7 @@ mlir::LogicalResult mlir::pto::TRowExpandDivOp::verify() { auto elemTy = e0.dyn_cast(); if (!elemTy || (!elemTy.isF16() && !elemTy.isF32())) return emitOpError("expects element type to be f16 or f32"); - return mlir::success(); + return verifyTRowExpandLike(getOperation(), t0, t1, td, e0); } //===----------------------------------------------------------------------===// // PTO.cpp (add verifier for TROWEXPANDMUL DPS/tilebuf op) @@ -2831,7 +2868,7 @@ mlir::LogicalResult mlir::pto::TRowExpandMulOp::verify() { auto ft = e0.dyn_cast(); if (!ft || (!ft.isF16() && !ft.isF32())) return emitOpError("expects element type to be f16 or f32"); - return mlir::success(); + return verifyTRowExpandLike(getOperation(), t0, t1, td, e0); } //===----------------------------------------------------------------------===// // PTO.cpp (add verifier for TROWEXPANDSUB DPS/tilebuf op) @@ -2851,7 +2888,7 @@ mlir::LogicalResult mlir::pto::TRowExpandSubOp::verify() { auto ft = e0.dyn_cast(); if (!ft || (!ft.isF16() && !ft.isF32())) return emitOpError("expects element type to be f16 or f32"); - return mlir::success(); + return verifyTRowExpandLike(getOperation(), t0, t1, td, e0); } //===----------------------------------------------------------------------===// // PTO.cpp (add verifier for TROWMAX DPS/tilebuf op) @@ -3013,19 +3050,22 @@ mlir::LogicalResult mlir::pto::TSelSOp::verify() { Type td = getDst().getType(); if (!isPTOShapedLike(t0) || !isPTOShapedLike(t1) || !isPTOShapedLike(td)) return emitOpError("expects src0/src1/dst to be memref/tensor/tile_buf/tile_view types"); - Type es = getElemTy(t0), ed = getElemTy(td); - if (!es || !ed) + Type e0 = getElemTy(t0), e1 = getElemTy(t1), ed = getElemTy(td); + if (!e0 || !e1 || !ed) return emitOpError("failed to get element type for operands"); - if (es != ed) - return emitOpError("expects src0 and dst to have the same element type"); + if (e0 != e1 || e0 != ed) + return emitOpError("expects src0/src1/dst to have the same element type"); + auto s0 = getShapeVec(t0), s1 = getShapeVec(t1), sd = getShapeVec(td); + if (s0 != s1 || s0 != sd) + return emitOpError("expects src0/src1/dst to have the same shape"); auto isAllowedElem = [&](mlir::Type t) -> bool { if (t.isF16() || t.isF32() || t.isBF16()) return true; if (auto it = mlir::dyn_cast(t)) return (it.getWidth() == 8 || it.getWidth() == 16 || it.getWidth() == 32); return false; }; - if (!isAllowedElem(es)) - return emitOpError("expects src0 and dst element type to be i8/i16/i32/f16/bf16/f32"); + if (!isAllowedElem(e0)) + return emitOpError("expects src0/src1/dst element type to be i8/i16/i32/f16/bf16/f32"); return mlir::success(); } //===----------------------------------------------------------------------===// diff --git a/lib/PTO/Transforms/PTOToEmitC.cpp b/lib/PTO/Transforms/PTOToEmitC.cpp index 939287dd..943ff0b1 100644 --- a/lib/PTO/Transforms/PTOToEmitC.cpp +++ b/lib/PTO/Transforms/PTOToEmitC.cpp @@ -1686,6 +1686,193 @@ static Value makeEmitCIntConstant(ConversionPatternRewriter &rewriter, return makeEmitCOpaqueConstant(rewriter, loc, type, std::to_string(value)); } +static bool isEmitCTileOpaqueType(Type type) { + auto opaqueType = dyn_cast(type); + if (!opaqueType) + return false; + StringRef typeName = opaqueType.getValue(); + return typeName.starts_with("Tile<") && typeName.ends_with(">"); +} + +static LogicalResult parseEmitCTileType(Value exemplar, + SmallVectorImpl &parts) { + auto tileTy = dyn_cast(exemplar.getType()); + if (!tileTy) + return failure(); + + StringRef tileTypeStr = tileTy.getValue(); + if (!tileTypeStr.starts_with("Tile<") || !tileTypeStr.ends_with(">")) + return failure(); + + StringRef body = tileTypeStr.drop_front(5).drop_back(1); + size_t partBegin = 0; + int angleDepth = 0; + for (size_t i = 0; i < body.size(); ++i) { + char c = body[i]; + if (c == '<') { + ++angleDepth; + } else if (c == '>') { + if (angleDepth > 0) + --angleDepth; + } else if (c == ',' && angleDepth == 0) { + parts.push_back(body.slice(partBegin, i).trim().str()); + partBegin = i + 1; + } + } + parts.push_back(body.drop_front(partBegin).trim().str()); + return success(parts.size() >= 10); +} + +static FailureOr getEmitCTileStorageSizeBytes(Value exemplar) { + SmallVector parts; + if (failed(parseEmitCTileType(exemplar, parts))) + return failure(); + + int64_t rows = 0; + int64_t cols = 0; + if (StringRef(parts[2]).trim().getAsInteger(10, rows) || + StringRef(parts[3]).trim().getAsInteger(10, cols)) + return failure(); + + int64_t elemBytes = 0; + StringRef elemTok = StringRef(parts[1]).trim(); + if (elemTok == "half" || elemTok == "float16_t" || elemTok == "bfloat16_t" || + elemTok == "int16_t" || elemTok == "uint16_t") { + elemBytes = 2; + } else if (elemTok == "float" || elemTok == "int32_t" || + elemTok == "uint32_t") { + elemBytes = 4; + } else if (elemTok == "double" || elemTok == "int64_t" || + elemTok == "uint64_t") { + elemBytes = 8; + } else if (elemTok == "int8_t" || elemTok == "uint8_t" || + elemTok == "bool") { + elemBytes = 1; + } else { + return failure(); + } + + return rows * cols * elemBytes; +} + +static FailureOr +buildIntegralAddressFromTileLike(Location loc, Value sourceValue, + ConversionPatternRewriter &rewriter) { + auto *ctx = rewriter.getContext(); + auto u64Ty = emitc::OpaqueType::get(ctx, "uint64_t"); + auto rcU64 = + rewriter.getArrayAttr({emitc::OpaqueAttr::get(ctx, "uint64_t")}); + + if (auto castOp = sourceValue.getDefiningOp()) + sourceValue = castOp.getOperand(); + + Value rawPtr = sourceValue; + if (isEmitCTileOpaqueType(sourceValue.getType())) { + SmallVector parts; + if (failed(parseEmitCTileType(sourceValue, parts))) + return failure(); + + StringRef roleTok = StringRef(parts[0]).trim(); + StringRef elemTok = StringRef(parts[1]).trim(); + std::string qualifier; + if (roleTok == "TileType::Vec") { + qualifier = "__ubuf__"; + } else if (roleTok == "TileType::Mat") { + qualifier = "__cbuf__"; + } else if (roleTok == "TileType::Left") { + qualifier = "__ca__"; + } else if (roleTok == "TileType::Right") { + qualifier = "__cb__"; + } else if (roleTok == "TileType::Acc") { + qualifier = "__cc__"; + } else if (roleTok == "TileType::Scaling") { + qualifier = "__fbuf__"; + } else { + qualifier = "__gm__"; + } + + auto rawPtrTy = + emitc::OpaqueType::get(ctx, qualifier + " " + elemTok.str() + "*"); + rawPtr = rewriter + .create(loc, rawPtrTy, "PTOAS__TILE_DATA", + ArrayAttr{}, ArrayAttr{}, + ValueRange{sourceValue}) + .getResult(0); + } + + if (isa(rawPtr.getType()) || + (isa(rawPtr.getType()) && + cast(rawPtr.getType()).getValue().ends_with("*"))) { + return rewriter + .create(loc, u64Ty, "reinterpret_cast", + ArrayAttr{}, rcU64, ValueRange{rawPtr}) + .getResult(0); + } + + if (rawPtr.getType() == u64Ty) + return rawPtr; + return rewriter.create(loc, u64Ty, rawPtr).getResult(); +} + +static FailureOr +createSiblingTileValue(Location loc, Value exemplar, + ConversionPatternRewriter &rewriter) { + auto opaqueTy = dyn_cast(exemplar.getType()); + if (!opaqueTy || !isEmitCTileOpaqueType(opaqueTy)) + return failure(); + + SmallVector parts; + if (failed(parseEmitCTileType(exemplar, parts))) + return failure(); + if (StringRef(parts[5]).trim() == "-1" || StringRef(parts[6]).trim() == "-1") + return failure(); + + return rewriter + .create(loc, opaqueTy, + emitc::OpaqueAttr::get(rewriter.getContext(), "")) + .getResult(); +} + +static FailureOr +materializeDisjointTempTile(Location loc, Value exemplar, + ArrayRef occupiedValues, + ConversionPatternRewriter &rewriter) { + if (occupiedValues.empty()) + return failure(); + + auto tmpTile = createSiblingTileValue(loc, exemplar, rewriter); + auto tileBytes = getEmitCTileStorageSizeBytes(exemplar); + if (failed(tmpTile) || failed(tileBytes)) + return failure(); + + auto *ctx = rewriter.getContext(); + auto u64Ty = emitc::OpaqueType::get(ctx, "uint64_t"); + SmallVector addrs; + addrs.reserve(occupiedValues.size()); + for (Value value : occupiedValues) { + auto addr = buildIntegralAddressFromTileLike(loc, value, rewriter); + if (failed(addr)) + return failure(); + addrs.push_back(*addr); + } + + Value maxAddr = addrs.front(); + for (Value addr : ArrayRef(addrs).drop_front()) { + Value isLess = rewriter.create( + loc, rewriter.getI1Type(), emitc::CmpPredicate::lt, maxAddr, addr); + maxAddr = rewriter.create(loc, u64Ty, isLess, addr, + maxAddr); + } + + Value tmpAddr = rewriter.create( + loc, u64Ty, maxAddr, + makeEmitCIntConstant(rewriter, loc, u64Ty, *tileBytes)); + rewriter.create(loc, TypeRange{}, "TASSIGN", ArrayAttr{}, + ArrayAttr{}, + ValueRange{*tmpTile, tmpAddr}); + return *tmpTile; +} + static Value emitCCast(ConversionPatternRewriter &rewriter, Location loc, Type dstType, Value src) { if (src.getType() == dstType) @@ -5420,18 +5607,44 @@ struct PTOPreluToEmitC : public OpConversionPattern { LogicalResult matchAndRewrite(pto::TPReluOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { auto loc = op.getLoc(); + auto *ctx = rewriter.getContext(); Value src0 = peelUnrealized(adaptor.getSrc0()); Value src1 = peelUnrealized(adaptor.getSrc1()); - Value tmp = peelUnrealized(adaptor.getTmp()); Value dst = peelUnrealized(adaptor.getDst()); - - // C++ interface: TPRELU(dst, src0, src1, tmp) — last parameter is tmp. - SmallVector operands{dst, src0, src1, tmp}; - rewriter.create( - loc, TypeRange{}, "TPRELU", - /*args=*/ArrayAttr{}, /*templateArgs=*/ArrayAttr{}, - /*operands=*/operands); + auto tmp = materializeDisjointTempTile(loc, dst, {src0, src1, dst}, rewriter); + if (failed(tmp)) + return op.emitOpError("failed to materialize disjoint temp tile"); + + SmallVector parts; + if (failed(parseEmitCTileType(dst, parts))) + return op.emitOpError("failed to infer element type for tprelu lowering"); + + auto scalarTy = + emitc::OpaqueType::get(ctx, StringRef(parts[1]).trim().str()); + auto zero = rewriter.create( + loc, scalarTy, emitc::OpaqueAttr::get(ctx, "0")); + auto pipeVArgs = + rewriter.getArrayAttr({emitc::OpaqueAttr::get(ctx, "PIPE_V")}); + + rewriter.create(loc, TypeRange{}, "TMINS", + ArrayAttr{}, ArrayAttr{}, + ValueRange{*tmp, src0, zero}); + rewriter.create(loc, TypeRange{}, "pipe_barrier", + pipeVArgs, ArrayAttr{}, ValueRange{}); + rewriter.create(loc, TypeRange{}, "TMUL", + ArrayAttr{}, ArrayAttr{}, + ValueRange{dst, *tmp, src1}); + rewriter.create(loc, TypeRange{}, "pipe_barrier", + pipeVArgs, ArrayAttr{}, ValueRange{}); + rewriter.create(loc, TypeRange{}, "TMAXS", + ArrayAttr{}, ArrayAttr{}, + ValueRange{*tmp, src0, zero}); + rewriter.create(loc, TypeRange{}, "pipe_barrier", + pipeVArgs, ArrayAttr{}, ValueRange{}); + rewriter.create(loc, TypeRange{}, "TADD", + ArrayAttr{}, ArrayAttr{}, + ValueRange{dst, dst, *tmp}); rewriter.eraseOp(op); return success(); @@ -5910,11 +6123,25 @@ struct PTOSelSToEmitC : public OpConversionPattern { Value selectMode = peelUnrealized(adaptor.getSelectMode()); Value dst = peelUnrealized(adaptor.getDst()); - SmallVector operands{dst, src0, src1, selectMode}; - rewriter.create( - loc, TypeRange{}, "TSELS", - /*args=*/ArrayAttr{}, /*templateArgs=*/ArrayAttr{}, - /*operands=*/operands); + auto src0Addr = buildIntegralAddressFromTileLike(loc, src0, rewriter); + auto src1Addr = buildIntegralAddressFromTileLike(loc, src1, rewriter); + if (failed(src0Addr) || failed(src1Addr)) + return rewriter.notifyMatchFailure(op, + "failed to materialize selected tile address"); + + Value selectOne = + makeEmitCIntConstant(rewriter, loc, selectMode.getType(), 1); + Value chooseSrc0 = rewriter.create( + loc, rewriter.getI1Type(), emitc::CmpPredicate::eq, selectMode, + selectOne); + auto *ctx = rewriter.getContext(); + auto u64Ty = emitc::OpaqueType::get(ctx, "uint64_t"); + Value selectedAddr = rewriter.create( + loc, u64Ty, chooseSrc0, *src0Addr, *src1Addr); + + rewriter.create(loc, TypeRange{}, "TASSIGN", + ArrayAttr{}, ArrayAttr{}, + ValueRange{dst, selectedAddr}); rewriter.eraseOp(op); return success(); @@ -6218,9 +6445,12 @@ struct PTOXORToEmitC : public OpConversionPattern { Value src1 = peelUnrealized(adaptor.getSrc1()); Value dst = peelUnrealized(adaptor.getDst()); - // pto-isa TXOR requires a tmp tile argument. Current NPU implementation - // does not use tmp, so we safely pass dst as tmp for compatibility. - SmallVector operands{dst, src0, src1, dst}; + auto tmp = materializeDisjointTempTile(loc, dst, {src0, src1, dst}, rewriter); + if (failed(tmp)) + return rewriter.notifyMatchFailure(op, + "failed to materialize disjoint tmp tile for TXOR"); + + SmallVector operands{dst, src0, src1, *tmp}; rewriter.create( loc, TypeRange{}, "TXOR", /*args=*/ArrayAttr{}, /*templateArgs=*/ArrayAttr{}, @@ -6266,9 +6496,12 @@ struct PTOXORSToEmitC : public OpConversionPattern { Value scalar = peelUnrealized(adaptor.getScalar()); Value dst = peelUnrealized(adaptor.getDst()); - // pto-isa TXORS requires a tmp tile argument. Current NPU implementation - // does not use tmp, so we safely pass dst as tmp for compatibility. - SmallVector operands{dst, src, scalar, dst}; + auto tmp = materializeDisjointTempTile(loc, dst, {src, dst}, rewriter); + if (failed(tmp)) + return rewriter.notifyMatchFailure(op, + "failed to materialize disjoint tmp tile for TXORS"); + + SmallVector operands{dst, src, scalar, *tmp}; rewriter.create( loc, TypeRange{}, "TXORS", /*args=*/ArrayAttr{}, /*templateArgs=*/ArrayAttr{}, diff --git a/test/npu_validation/scripts/generate_testcase.py b/test/npu_validation/scripts/generate_testcase.py index 217a4eaf..619582f7 100644 --- a/test/npu_validation/scripts/generate_testcase.py +++ b/test/npu_validation/scripts/generate_testcase.py @@ -4,6 +4,7 @@ import argparse import ast import re +import shutil from pathlib import Path from typing import Optional @@ -266,6 +267,33 @@ def _derive_testcase_name(input_cpp: Path) -> str: return name +def _resolve_sample_root(input_cpp: Path) -> Path: + parent = input_cpp.parent + if parent.name == "npu_validation": + return parent.parent + if parent.parent.name == "npu_validation": + return parent.parent.parent + return parent + + +def _find_custom_case_asset(sample_root: Path, testcase: str, filename: str) -> Optional[Path]: + candidates = ( + sample_root / f"{testcase}_{filename}", + sample_root / "npu_validation" / testcase / filename, + sample_root / "npu_validation" / filename, + ) + for candidate in candidates: + if candidate.is_file(): + return candidate + return None + + +def _copy_asset_if_needed(src: Path, dst: Path): + if src.resolve() == dst.resolve(): + return + shutil.copy2(src, dst) + + def _replace_includes(text: str) -> str: if "#include \"common/pto_instr.hpp\"" in text: return text.replace("#include \"common/pto_instr.hpp\"", INCLUDE_REPLACEMENT.rstrip()) @@ -814,13 +842,17 @@ def generate_testcase( soc_version: str, aicore_arch: Optional[str] = None, ): - sample_dir = input_cpp.parent + sample_root = _resolve_sample_root(input_cpp) if output_root: - output_dir = output_root / sample_dir.name / testcase + output_dir = output_root / sample_root.name / testcase else: - output_dir = sample_dir / "npu_validation" / testcase + output_dir = sample_root / "npu_validation" / testcase output_dir.mkdir(parents=True, exist_ok=True) + custom_golden = _find_custom_case_asset(sample_root, testcase, "golden.py") + custom_compare = _find_custom_case_asset(sample_root, testcase, "compare.py") + shared_validation_runtime = sample_root.parent / "validation_runtime.py" + raw_kernel = input_cpp.read_text(encoding="utf-8") raw_kernel_for_analysis = raw_kernel # pto.tcmp / pto.tcmps produce packed predicate masks and leave parts of the @@ -1137,8 +1169,14 @@ def generate_testcase( input_generate.append(f" {name} = np.random.random(size=({size},)).astype({np_dtype})") input_generate.append(f" {name}.tofile(\"{name}.bin\")") - golden_py = golden_template.replace("@INPUT_GENERATE@", "\n".join(input_generate)) - (output_dir / "golden.py").write_text(golden_py, encoding="utf-8") + golden_dst = output_dir / "golden.py" + if custom_golden is not None: + _copy_asset_if_needed(custom_golden, golden_dst) + else: + golden_py = golden_template.replace("@INPUT_GENERATE@", "\n".join(input_generate)) + golden_dst.write_text(golden_py, encoding="utf-8") + if (custom_golden is not None or custom_compare is not None) and shared_validation_runtime.is_file(): + _copy_asset_if_needed(shared_validation_runtime, output_dir / "validation_runtime.py") # Emit the kernel source, optionally injecting a packed-predicate preload to # make TCMP/TCMPS outputs deterministic for byte-wise compares. @@ -1381,8 +1419,23 @@ def generate_testcase( compare_lines.append( f" ok = compare_bin(\"golden_{name}.bin\", \"{name}.bin\", {np_dtype}, {eps}) and ok" ) - compare_py = compare_template.replace("@COMPARES@", "\n".join(compare_lines)) - (output_dir / "compare.py").write_text(compare_py, encoding="utf-8") + compare_dst = output_dir / "compare.py" + if custom_compare is not None: + _copy_asset_if_needed(custom_compare, compare_dst) + else: + compare_py = compare_template.replace("@COMPARES@", "\n".join(compare_lines)) + compare_dst.write_text(compare_py, encoding="utf-8") + + (output_dir / "validation_meta.env").write_text( + "\n".join( + [ + f"CUSTOM_GOLDEN={1 if custom_golden is not None else 0}", + f"CUSTOM_COMPARE={1 if custom_compare is not None else 0}", + "", + ] + ), + encoding="utf-8", + ) # Let the runner know which bins are outputs (for sim->golden copying). (output_dir / "outputs.txt").write_text( diff --git a/test/npu_validation/scripts/run_remote_npu_validation.sh b/test/npu_validation/scripts/run_remote_npu_validation.sh index 43f766dd..20000114 100644 --- a/test/npu_validation/scripts/run_remote_npu_validation.sh +++ b/test/npu_validation/scripts/run_remote_npu_validation.sh @@ -233,6 +233,13 @@ while IFS= read -r -d '' cpp; do cd "${nv_dir}" export ACL_DEVICE_ID="${DEVICE_ID}" + CUSTOM_GOLDEN=0 + CUSTOM_COMPARE=0 + if [[ -f "./validation_meta.env" ]]; then + # shellcheck disable=SC1091 + source "./validation_meta.env" + fi + enable_sim_golden="OFF" [[ "${GOLDEN_MODE}" == "sim" ]] && enable_sim_golden="ON" cmake -S . -B ./build \ @@ -264,12 +271,23 @@ while IFS= read -r -d '' cpp; do case "${GOLDEN_MODE}" in sim) python3 ./golden.py - LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SIM}" ./build/${testcase}_sim - copy_outputs_as_golden - if [[ "${RUN_MODE}" == "npu" ]]; then - LD_LIBRARY_PATH="${LD_LIBRARY_PATH_NPU}" ./build/${testcase} + if [[ "${CUSTOM_GOLDEN}" == "1" ]]; then + log "Using custom golden for ${testcase}" + LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SIM}" ./build/${testcase}_sim + COMPARE_STRICT=1 python3 ./compare.py + if [[ "${RUN_MODE}" == "npu" ]]; then + python3 ./golden.py + LD_LIBRARY_PATH="${LD_LIBRARY_PATH_NPU}" ./build/${testcase} + COMPARE_STRICT=1 python3 ./compare.py + fi + else + LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SIM}" ./build/${testcase}_sim + copy_outputs_as_golden + if [[ "${RUN_MODE}" == "npu" ]]; then + LD_LIBRARY_PATH="${LD_LIBRARY_PATH_NPU}" ./build/${testcase} + fi + COMPARE_STRICT=1 python3 ./compare.py fi - COMPARE_STRICT=1 python3 ./compare.py ;; npu) if [[ "${RUN_MODE}" != "npu" ]]; then @@ -278,9 +296,13 @@ while IFS= read -r -d '' cpp; do fi python3 ./golden.py LD_LIBRARY_PATH="${LD_LIBRARY_PATH_NPU}" ./build/${testcase} - copy_outputs_as_golden - python3 ./golden.py - LD_LIBRARY_PATH="${LD_LIBRARY_PATH_NPU}" ./build/${testcase} + if [[ "${CUSTOM_GOLDEN}" != "1" ]]; then + copy_outputs_as_golden + python3 ./golden.py + LD_LIBRARY_PATH="${LD_LIBRARY_PATH_NPU}" ./build/${testcase} + else + log "Using custom golden for ${testcase}" + fi COMPARE_STRICT=1 python3 ./compare.py ;; skip) diff --git a/test/samples/Abs/abs_compare.py b/test/samples/Abs/abs_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Abs/abs_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Abs/abs_golden.py b/test/samples/Abs/abs_golden.py new file mode 100755 index 00000000..d009ea94 --- /dev/null +++ b/test/samples/Abs/abs_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.abs(src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/AddPtr/addptr_chain_compare.py b/test/samples/AddPtr/addptr_chain_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/AddPtr/addptr_chain_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/AddPtr/addptr_chain_golden.py b/test/samples/AddPtr/addptr_chain_golden.py new file mode 100644 index 00000000..49f5ea2f --- /dev/null +++ b/test/samples/AddPtr/addptr_chain_golden.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + offset = 24 + out = src[offset:offset + meta.elem_counts[out_name]] + write_golden(meta, {out_name: np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/AddPtr/addptr_compare.py b/test/samples/AddPtr/addptr_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/AddPtr/addptr_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/AddPtr/addptr_f16_compare.py b/test/samples/AddPtr/addptr_f16_compare.py new file mode 100644 index 00000000..0c36d972 --- /dev/null +++ b/test/samples/AddPtr/addptr_f16_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float16, atol=0.0) diff --git a/test/samples/AddPtr/addptr_f16_golden.py b/test/samples/AddPtr/addptr_f16_golden.py new file mode 100644 index 00000000..0e2b25ed --- /dev/null +++ b/test/samples/AddPtr/addptr_f16_golden.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed').astype(np.float16) + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small').astype(np.float16) + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + offset = 32 + out = src[offset:offset + meta.elem_counts[out_name]] + write_golden(meta, {out_name: np.asarray(out, dtype=np.float16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/AddPtr/addptr_golden.py b/test/samples/AddPtr/addptr_golden.py new file mode 100644 index 00000000..b4d640d3 --- /dev/null +++ b/test/samples/AddPtr/addptr_golden.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + offset = 32 + out = src[offset:offset + meta.elem_counts[out_name]] + write_golden(meta, {out_name: np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Addc/addc_compare.py b/test/samples/Addc/addc_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Addc/addc_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Addc/addc_golden.py b/test/samples/Addc/addc_golden.py new file mode 100755 index 00000000..e897dc7a --- /dev/null +++ b/test/samples/Addc/addc_golden.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + a_name, b_name, c_name = meta.inputs + generator = rng() + a = float_values(generator, meta.elem_counts[a_name], style='signed') + b = float_values(generator, meta.elem_counts[b_name], style='signed') + c = float_values(generator, meta.elem_counts[c_name], style='signed_small') + buffers = default_buffers(meta) + buffers[a_name] = a + buffers[b_name] = b + buffers[c_name] = c + write_buffers(meta, buffers) + out = a + b + c + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Adds/adds_compare.py b/test/samples/Adds/adds_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Adds/adds_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Adds/adds_golden.py b/test/samples/Adds/adds_golden.py new file mode 100755 index 00000000..e98a225f --- /dev/null +++ b/test/samples/Adds/adds_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src + np.float32(3.14) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Addsc/addsc_compare.py b/test/samples/Addsc/addsc_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Addsc/addsc_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Addsc/addsc_golden.py b/test/samples/Addsc/addsc_golden.py new file mode 100755 index 00000000..b2fb27d4 --- /dev/null +++ b/test/samples/Addsc/addsc_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src + np.float32(3.14) + src + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/And/and_compare.py b/test/samples/And/and_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/And/and_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/And/and_golden.py b/test/samples/And/and_golden.py new file mode 100755 index 00000000..5306267a --- /dev/null +++ b/test/samples/And/and_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_and(src, src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Ands/ands_compare.py b/test/samples/Ands/ands_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/Ands/ands_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/Ands/ands_golden.py b/test/samples/Ands/ands_golden.py new file mode 100755 index 00000000..0cc1060d --- /dev/null +++ b/test/samples/Ands/ands_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_and(src, np.asarray(88, dtype=np.int16).item()) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Ci/ci_compare.py b/test/samples/Ci/ci_compare.py new file mode 100644 index 00000000..b93e8b9e --- /dev/null +++ b/test/samples/Ci/ci_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int32, atol=0.0) diff --git a/test/samples/Ci/ci_golden.py b/test/samples/Ci/ci_golden.py new file mode 100644 index 00000000..93976ed3 --- /dev/null +++ b/test/samples/Ci/ci_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, load_case_meta, load_int32_assignments, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + out_name = single_output(meta) + start, = load_int32_assignments() + buffers = default_buffers(meta) + buffers[out_name] = np.full(meta.elem_counts[out_name], -123, dtype=np.int32) + write_buffers(meta, buffers) + cols = meta.elem_counts[out_name] + out = np.asarray([start - index for index in range(cols)], dtype=np.int32) + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Cmp/cmp_compare.py b/test/samples/Cmp/cmp_compare.py new file mode 100755 index 00000000..4c411476 --- /dev/null +++ b/test/samples/Cmp/cmp_compare.py @@ -0,0 +1,13 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_packed_mask_outputs + +if __name__ == '__main__': + compare_packed_mask_outputs() diff --git a/test/samples/Cmp/cmp_golden.py b/test/samples/Cmp/cmp_golden.py new file mode 100755 index 00000000..48639b6f --- /dev/null +++ b/test/samples/Cmp/cmp_golden.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ( + default_buffers, + float_values, + load_case_meta, + matrix32, + pack_predicate_mask_for_buffer, + rng, + single_output, + write_buffers, + write_golden, +) + + +def main(): + meta = load_case_meta() + src0_name, src1_name = meta.inputs + generator = rng() + src0 = float_values(generator, meta.elem_counts[src0_name], style='cmp') + src1 = float_values(generator, meta.elem_counts[src1_name], style='cmp') + pred = matrix32(src0) < matrix32(src1) + buffers = default_buffers(meta) + buffers[src0_name] = src0 + buffers[src1_name] = src1 + write_buffers(meta, buffers) + out_name = single_output(meta) + packed = pack_predicate_mask_for_buffer(pred, elem_count=meta.elem_counts[out_name], dtype=meta.np_types[out_name]) + write_golden(meta, {out_name: packed}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Cmps/cmps_compare.py b/test/samples/Cmps/cmps_compare.py new file mode 100755 index 00000000..4c411476 --- /dev/null +++ b/test/samples/Cmps/cmps_compare.py @@ -0,0 +1,13 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_packed_mask_outputs + +if __name__ == '__main__': + compare_packed_mask_outputs() diff --git a/test/samples/Cmps/cmps_golden.py b/test/samples/Cmps/cmps_golden.py new file mode 100755 index 00000000..c9172a52 --- /dev/null +++ b/test/samples/Cmps/cmps_golden.py @@ -0,0 +1,39 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ( + default_buffers, + float_values, + load_case_meta, + matrix32, + pack_predicate_mask_for_buffer, + rng, + single_output, + write_buffers, + write_golden, +) + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='cmp') + pred = matrix32(src) > np.float32(1.0) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out_name = single_output(meta) + packed = pack_predicate_mask_for_buffer(pred, elem_count=meta.elem_counts[out_name], dtype=meta.np_types[out_name]) + write_golden(meta, {out_name: packed}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Colexpand/colexpand_compare.py b/test/samples/Colexpand/colexpand_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Colexpand/colexpand_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Colexpand/colexpand_golden.py b/test/samples/Colexpand/colexpand_golden.py new file mode 100755 index 00000000..119d6392 --- /dev/null +++ b/test/samples/Colexpand/colexpand_golden.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.repeat(src_m[:1, :], 32, axis=0) + write_golden(meta, {single_output(meta): out.astype(np.float32).reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Colmax/colmax_compare.py b/test/samples/Colmax/colmax_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Colmax/colmax_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Colmax/colmax_golden.py b/test/samples/Colmax/colmax_golden.py new file mode 100755 index 00000000..992ae5f1 --- /dev/null +++ b/test/samples/Colmax/colmax_golden.py @@ -0,0 +1,38 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, COLS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + reduced = np.asarray(src_m.max(axis=0), dtype=np.float32) + out = np.asarray(buffers.get(out_name, np.zeros(meta.elem_counts[out_name], dtype=np.float32)), dtype=np.float32).reshape(-1).copy() + if out.size == ROWS * COLS: + out_m = matrix32(out) + out_m[0, :] = reduced + out = out_m.reshape(-1) + elif out.size == COLS: + out = reduced + else: + raise ValueError(f'unsupported col-reduce output size: {out.size}') + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Colmin/colmin_compare.py b/test/samples/Colmin/colmin_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Colmin/colmin_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Colmin/colmin_golden.py b/test/samples/Colmin/colmin_golden.py new file mode 100755 index 00000000..d8081173 --- /dev/null +++ b/test/samples/Colmin/colmin_golden.py @@ -0,0 +1,38 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, COLS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + reduced = np.asarray(src_m.min(axis=0), dtype=np.float32) + out = np.asarray(buffers.get(out_name, np.zeros(meta.elem_counts[out_name], dtype=np.float32)), dtype=np.float32).reshape(-1).copy() + if out.size == ROWS * COLS: + out_m = matrix32(out) + out_m[0, :] = reduced + out = out_m.reshape(-1) + elif out.size == COLS: + out = reduced + else: + raise ValueError(f'unsupported col-reduce output size: {out.size}') + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Colsum/colsum_compare.py b/test/samples/Colsum/colsum_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Colsum/colsum_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Colsum/colsum_golden.py b/test/samples/Colsum/colsum_golden.py new file mode 100755 index 00000000..b148730c --- /dev/null +++ b/test/samples/Colsum/colsum_golden.py @@ -0,0 +1,37 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, COLS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name, tmp_name = meta.inputs + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[tmp_name] = np.zeros(meta.elem_counts[tmp_name], dtype=meta.np_types[tmp_name]) + write_buffers(meta, buffers) + reduced = np.asarray(src_m.sum(axis=0, dtype=np.float32), dtype=np.float32) + out = np.zeros(meta.elem_counts[out_name], dtype=np.float32) + if out.size == ROWS * COLS: + out[:COLS] = reduced + elif out.size == COLS: + out = reduced + else: + raise ValueError(f'unsupported colsum output size: {out.size}') + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Div/div_compare.py b/test/samples/Div/div_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Div/div_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Div/div_golden.py b/test/samples/Div/div_golden.py new file mode 100755 index 00000000..a5eafc1a --- /dev/null +++ b/test/samples/Div/div_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='nonzero_signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs / rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Divs/divs_compare.py b/test/samples/Divs/divs_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Divs/divs_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Divs/divs_golden.py b/test/samples/Divs/divs_golden.py new file mode 100755 index 00000000..af2ac1a0 --- /dev/null +++ b/test/samples/Divs/divs_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src / np.float32(3.14) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Divs2/divs2_compare.py b/test/samples/Divs2/divs2_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Divs2/divs2_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Divs2/divs2_golden.py b/test/samples/Divs2/divs2_golden.py new file mode 100755 index 00000000..5fb49556 --- /dev/null +++ b/test/samples/Divs2/divs2_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='nonzero_signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src / np.float32(3.14) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Exp/exp_compare.py b/test/samples/Exp/exp_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Exp/exp_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Exp/exp_golden.py b/test/samples/Exp/exp_golden.py new file mode 100755 index 00000000..2f0dcbeb --- /dev/null +++ b/test/samples/Exp/exp_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='exp') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.exp(src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Expands/expand_compare.py b/test/samples/Expands/expand_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Expands/expand_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Expands/expand_golden.py b/test/samples/Expands/expand_golden.py new file mode 100755 index 00000000..d46d860d --- /dev/null +++ b/test/samples/Expands/expand_golden.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, load_case_meta, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + write_buffers(meta, default_buffers(meta)) + out_name = single_output(meta) + out = np.full(meta.elem_counts[out_name], np.float32(3.14), dtype=np.float32) + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Expands/expands_compare.py b/test/samples/Expands/expands_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Expands/expands_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Expands/expands_golden.py b/test/samples/Expands/expands_golden.py new file mode 100755 index 00000000..d46d860d --- /dev/null +++ b/test/samples/Expands/expands_golden.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, load_case_meta, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + write_buffers(meta, default_buffers(meta)) + out_name = single_output(meta) + out = np.full(meta.elem_counts[out_name], np.float32(3.14), dtype=np.float32) + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Fillpad/fillpad_compare.py b/test/samples/Fillpad/fillpad_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Fillpad/fillpad_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Fillpad/fillpad_expand_compare.py b/test/samples/Fillpad/fillpad_expand_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Fillpad/fillpad_expand_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Fillpad/fillpad_expand_golden.py b/test/samples/Fillpad/fillpad_expand_golden.py new file mode 100644 index 00000000..4a407b69 --- /dev/null +++ b/test/samples/Fillpad/fillpad_expand_golden.py @@ -0,0 +1,34 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + src_rows = 32 + src_cols = meta.elem_counts[src_name] // src_rows + dst_cols = meta.elem_counts[out_name] // src_rows + out = np.zeros((src_rows, dst_cols), dtype=np.float32) + out[:, :src_cols] = np.asarray(src, dtype=np.float32).reshape(src_rows, src_cols) + write_golden(meta, {out_name: out.reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Fillpad/fillpad_golden.py b/test/samples/Fillpad/fillpad_golden.py new file mode 100644 index 00000000..1484e1e2 --- /dev/null +++ b/test/samples/Fillpad/fillpad_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + write_golden(meta, {out_name: np.asarray(src, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Layout/tensor_view_infer_layout_dn_compare.py b/test/samples/Layout/tensor_view_infer_layout_dn_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Layout/tensor_view_infer_layout_dn_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Layout/tensor_view_infer_layout_dn_golden.py b/test/samples/Layout/tensor_view_infer_layout_dn_golden.py new file mode 100644 index 00000000..1484e1e2 --- /dev/null +++ b/test/samples/Layout/tensor_view_infer_layout_dn_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + write_golden(meta, {out_name: np.asarray(src, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Layout/tensor_view_layout_dn_compare.py b/test/samples/Layout/tensor_view_layout_dn_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Layout/tensor_view_layout_dn_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Layout/tensor_view_layout_dn_golden.py b/test/samples/Layout/tensor_view_layout_dn_golden.py new file mode 100644 index 00000000..1484e1e2 --- /dev/null +++ b/test/samples/Layout/tensor_view_layout_dn_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + write_golden(meta, {out_name: np.asarray(src, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Log/log_compare.py b/test/samples/Log/log_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Log/log_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Log/log_golden.py b/test/samples/Log/log_golden.py new file mode 100755 index 00000000..8474aeb1 --- /dev/null +++ b/test/samples/Log/log_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='positive') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.log(src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Lrelu/lrelu_compare.py b/test/samples/Lrelu/lrelu_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Lrelu/lrelu_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Lrelu/lrelu_golden.py b/test/samples/Lrelu/lrelu_golden.py new file mode 100755 index 00000000..119e8711 --- /dev/null +++ b/test/samples/Lrelu/lrelu_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.where(src > 0.0, src, src * np.float32(3.14)) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Max/max_compare.py b/test/samples/Max/max_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Max/max_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Max/max_golden.py b/test/samples/Max/max_golden.py new file mode 100755 index 00000000..e925a6a6 --- /dev/null +++ b/test/samples/Max/max_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = np.maximum(lhs, rhs) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Maxs/maxs_compare.py b/test/samples/Maxs/maxs_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Maxs/maxs_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Maxs/maxs_golden.py b/test/samples/Maxs/maxs_golden.py new file mode 100755 index 00000000..2a18be2c --- /dev/null +++ b/test/samples/Maxs/maxs_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.maximum(src, np.float32(3.14)) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Min/min_compare.py b/test/samples/Min/min_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Min/min_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Min/min_golden.py b/test/samples/Min/min_golden.py new file mode 100755 index 00000000..d620b49a --- /dev/null +++ b/test/samples/Min/min_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = np.minimum(lhs, rhs) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Mins/mins_compare.py b/test/samples/Mins/mins_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Mins/mins_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Mins/mins_golden.py b/test/samples/Mins/mins_golden.py new file mode 100755 index 00000000..e0f85b23 --- /dev/null +++ b/test/samples/Mins/mins_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.minimum(src, np.float32(3.14)) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Mul/mul_compare.py b/test/samples/Mul/mul_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Mul/mul_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Mul/mul_golden.py b/test/samples/Mul/mul_golden.py new file mode 100755 index 00000000..d100daa5 --- /dev/null +++ b/test/samples/Mul/mul_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs * rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Muls/muls_compare.py b/test/samples/Muls/muls_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Muls/muls_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Muls/muls_golden.py b/test/samples/Muls/muls_golden.py new file mode 100755 index 00000000..320cd2be --- /dev/null +++ b/test/samples/Muls/muls_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src * np.float32(3.14) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Neg/neg_compare.py b/test/samples/Neg/neg_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Neg/neg_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Neg/neg_golden.py b/test/samples/Neg/neg_golden.py new file mode 100755 index 00000000..90012ad8 --- /dev/null +++ b/test/samples/Neg/neg_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = -src + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Not/not_compare.py b/test/samples/Not/not_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/Not/not_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/Not/not_golden.py b/test/samples/Not/not_golden.py new file mode 100755 index 00000000..fc1a6745 --- /dev/null +++ b/test/samples/Not/not_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_not(src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Or/or_compare.py b/test/samples/Or/or_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/Or/or_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/Or/or_golden.py b/test/samples/Or/or_golden.py new file mode 100755 index 00000000..d5b15199 --- /dev/null +++ b/test/samples/Or/or_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_or(src, src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Ors/ors_compare.py b/test/samples/Ors/ors_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/Ors/ors_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/Ors/ors_golden.py b/test/samples/Ors/ors_golden.py new file mode 100755 index 00000000..8f5cb3c5 --- /dev/null +++ b/test/samples/Ors/ors_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_or(src, np.asarray(88, dtype=np.int16).item()) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Partadd/partadd_compare.py b/test/samples/Partadd/partadd_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Partadd/partadd_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Partadd/partadd_golden.py b/test/samples/Partadd/partadd_golden.py new file mode 100755 index 00000000..d6832130 --- /dev/null +++ b/test/samples/Partadd/partadd_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs + rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Partition5D/partition5d_a5_compare.py b/test/samples/Partition5D/partition5d_a5_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Partition5D/partition5d_a5_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Partition5D/partition5d_a5_golden.py b/test/samples/Partition5D/partition5d_a5_golden.py new file mode 100644 index 00000000..1ecb70fa --- /dev/null +++ b/test/samples/Partition5D/partition5d_a5_golden.py @@ -0,0 +1,39 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + + src_array = np.asarray(src, dtype=np.float32) + out_array = np.asarray(dst_init, dtype=np.float32).copy() + touched = [] + for depth in range(16): + for row in range(16): + base = depth * 1048576 + row * 1024 + touched.extend(base + col for col in range(16)) + touched = np.asarray(touched, dtype=np.int64) + out_array[touched] = src_array[touched] + write_golden(meta, {out_name: out_array}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Partition5D/partition5d_compare.py b/test/samples/Partition5D/partition5d_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Partition5D/partition5d_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Partition5D/partition5d_golden.py b/test/samples/Partition5D/partition5d_golden.py new file mode 100644 index 00000000..1ecb70fa --- /dev/null +++ b/test/samples/Partition5D/partition5d_golden.py @@ -0,0 +1,39 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + + src_array = np.asarray(src, dtype=np.float32) + out_array = np.asarray(dst_init, dtype=np.float32).copy() + touched = [] + for depth in range(16): + for row in range(16): + base = depth * 1048576 + row * 1024 + touched.extend(base + col for col in range(16)) + touched = np.asarray(touched, dtype=np.int64) + out_array[touched] = src_array[touched] + write_golden(meta, {out_name: out_array}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Partmax/partmax_compare.py b/test/samples/Partmax/partmax_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Partmax/partmax_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Partmax/partmax_golden.py b/test/samples/Partmax/partmax_golden.py new file mode 100755 index 00000000..e925a6a6 --- /dev/null +++ b/test/samples/Partmax/partmax_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = np.maximum(lhs, rhs) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Partmin/partmin_compare.py b/test/samples/Partmin/partmin_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Partmin/partmin_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Partmin/partmin_golden.py b/test/samples/Partmin/partmin_golden.py new file mode 100755 index 00000000..d620b49a --- /dev/null +++ b/test/samples/Partmin/partmin_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = np.minimum(lhs, rhs) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Prelu/prelu.py b/test/samples/Prelu/prelu.py index 312f0432..f41a7ead 100644 --- a/test/samples/Prelu/prelu.py +++ b/test/samples/Prelu/prelu.py @@ -23,7 +23,6 @@ def build(): fractal_ab_size = pto.TileConfig.fractalABSize cfg = pto.TileBufConfigAttr.get(bl, sl, fractal_ab_size, pd, ctx) tile_buf_32 = pto.TileBufType.get([32, 32], f32, vec, [32, 32], cfg, ctx) - # pto.tprelu verifier: tmp must be uint8 (TPreluCheck in pto-isa). u8 = IntegerType.get_unsigned(8, ctx) tile_buf_u8 = pto.TileBufType.get([32, 32], u8, vec, [32, 32], cfg, ctx) @@ -50,7 +49,6 @@ def build(): sv0 = pto.PartitionViewOp(tile_view_32, tv0, offsets=[c0, c0], sizes=[c32, c32]).result sv1 = pto.PartitionViewOp(tile_view_32, tv1, offsets=[c0, c0], sizes=[c32, c32]).result - # tb0/tb1/tb2: f32; tb_tmp: uint8 (pto.tprelu requires tmp to be uint8_t). tb0 = pto.AllocTileOp(tile_buf_32).result tb1 = pto.AllocTileOp(tile_buf_32).result tb_tmp = pto.AllocTileOp(tile_buf_u8).result @@ -77,4 +75,4 @@ def build(): if __name__ == "__main__": - print(build()) \ No newline at end of file + print(build()) diff --git a/test/samples/Prelu/prelu_compare.py b/test/samples/Prelu/prelu_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Prelu/prelu_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Prelu/prelu_golden.py b/test/samples/Prelu/prelu_golden.py new file mode 100755 index 00000000..4d14cf76 --- /dev/null +++ b/test/samples/Prelu/prelu_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name, slope_name = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + slope = float_values(generator, meta.elem_counts[slope_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[slope_name] = slope + write_buffers(meta, buffers) + out = np.where(src > 0.0, src, src * slope) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Recip/recip_compare.py b/test/samples/Recip/recip_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Recip/recip_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Recip/recip_golden.py b/test/samples/Recip/recip_golden.py new file mode 100755 index 00000000..267b826c --- /dev/null +++ b/test/samples/Recip/recip_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='positive') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = 1.0 / src + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Relu/relu_compare.py b/test/samples/Relu/relu_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Relu/relu_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Relu/relu_golden.py b/test/samples/Relu/relu_golden.py new file mode 100755 index 00000000..0f8dba16 --- /dev/null +++ b/test/samples/Relu/relu_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.maximum(src, np.float32(0.0)) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rem/rem_compare.py b/test/samples/Rem/rem_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Rem/rem_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Rem/rem_golden.py b/test/samples/Rem/rem_golden.py new file mode 100755 index 00000000..f567b585 --- /dev/null +++ b/test/samples/Rem/rem_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='nonzero_signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs - np.floor(lhs / rhs) * rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rems/rems_compare.py b/test/samples/Rems/rems_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Rems/rems_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Rems/rems_golden.py b/test/samples/Rems/rems_golden.py new file mode 100755 index 00000000..eb66d43c --- /dev/null +++ b/test/samples/Rems/rems_golden.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + scalar = np.float32(3.14) + out = src - np.floor(src / scalar) * scalar + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowexpand/rowexpand_compare.py b/test/samples/Rowexpand/rowexpand_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Rowexpand/rowexpand_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Rowexpand/rowexpand_golden.py b/test/samples/Rowexpand/rowexpand_golden.py new file mode 100755 index 00000000..2f839f67 --- /dev/null +++ b/test/samples/Rowexpand/rowexpand_golden.py @@ -0,0 +1,30 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import COLS, ROWS, default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + row_scalars = src[::COLS][:ROWS] + if row_scalars.size != ROWS: + raise ValueError(f'rowexpand: expected at least {ROWS} row scalars, got {row_scalars.size}') + out = np.repeat(row_scalars[:, None], COLS, axis=1) + write_golden(meta, {single_output(meta): out.astype(np.float32).reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowexpanddiv/rowexpanddiv.py b/test/samples/Rowexpanddiv/rowexpanddiv.py index 282f2cbc..f2935e1f 100644 --- a/test/samples/Rowexpanddiv/rowexpanddiv.py +++ b/test/samples/Rowexpanddiv/rowexpanddiv.py @@ -15,14 +15,18 @@ def build(): tv2_f32 = pto.TensorViewType.get(2, f32, ctx) tile_view_32 = pto.PartitionTensorViewType.get([32, 32], f32, ctx) + tile_view_rowvec = pto.PartitionTensorViewType.get([32, 1], f32, ctx) vec = pto.AddressSpaceAttr.get(pto.AddressSpace.VEC, ctx) bl = pto.BLayoutAttr.get(pto.BLayout.RowMajor, ctx) + bl_col = pto.BLayoutAttr.get(pto.BLayout.ColMajor, ctx) sl = pto.SLayoutAttr.get(pto.SLayout.NoneBox, ctx) pd = pto.PadValueAttr.get(pto.PadValue.Null, ctx) fractal_ab_size = pto.TileConfig.fractalABSize cfg = pto.TileBufConfigAttr.get(bl, sl, fractal_ab_size, pd, ctx) + cfg_rowvec = pto.TileBufConfigAttr.get(bl_col, sl, fractal_ab_size, pd, ctx) tile_buf_32 = pto.TileBufType.get([32, 32], f32, vec, [32, 32], cfg, ctx) + tile_buf_rowvec = pto.TileBufType.get([32, 1], f32, vec, [32, 1], cfg_rowvec, ctx) fn_ty = func.FunctionType.get([ptr_f32, ptr_f32, ptr_f32], []) with InsertionPoint(m.body): @@ -40,16 +44,16 @@ def build(): # %0/%1/%2 = pto.make_tensor_view %arg?, shape=[%c32,%c32] strides=[%c32,%c1] # 这里用原生 builder:通常签名会是 (result_type, ptr, shape, strides) tv0 = pto.MakeTensorViewOp(tv2_f32, arg0, [c32, c32], [c32, c1]).result - tv1 = pto.MakeTensorViewOp(tv2_f32, arg1, [c32, c32], [c32, c1]).result + tv1 = pto.MakeTensorViewOp(tv2_f32, arg1, [c32, c1], [c1, c1]).result tv2 = pto.MakeTensorViewOp(tv2_f32, arg2, [c32, c32], [c32, c1]).result # Replaced immediate numbers with constants c0 and c32 sv0 = pto.PartitionViewOp(tile_view_32, tv0, offsets=[c0, c0], sizes=[c32, c32]).result - sv1 = pto.PartitionViewOp(tile_view_32, tv1, offsets=[c0, c0], sizes=[c32, c32]).result + sv1 = pto.PartitionViewOp(tile_view_rowvec, tv1, offsets=[c0, c0], sizes=[c32, c1]).result # %5/%6/%7 = pto.alloc_tile : <32x32xf32> tb0 = pto.AllocTileOp(tile_buf_32).result - tb1 = pto.AllocTileOp(tile_buf_32).result + tb1 = pto.AllocTileOp(tile_buf_rowvec).result tb2 = pto.AllocTileOp(tile_buf_32).result pto.TLoadOp(None, sv0, tb0) # result=None @@ -71,4 +75,4 @@ def build(): if __name__ == "__main__": - print(build()) \ No newline at end of file + print(build()) diff --git a/test/samples/Rowexpanddiv/rowexpanddiv_compare.py b/test/samples/Rowexpanddiv/rowexpanddiv_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Rowexpanddiv/rowexpanddiv_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Rowexpanddiv/rowexpanddiv_golden.py b/test/samples/Rowexpanddiv/rowexpanddiv_golden.py new file mode 100755 index 00000000..51ead2a5 --- /dev/null +++ b/test/samples/Rowexpanddiv/rowexpanddiv_golden.py @@ -0,0 +1,34 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src0_name, src1_name = meta.inputs + generator = rng() + src0 = float_values(generator, meta.elem_counts[src0_name], style='signed') + src1 = float_values(generator, meta.elem_counts[src1_name], style='nonzero_signed') + src0_m = matrix32(src0) + row_scalars = src1.astype(np.float32).reshape(-1) + if row_scalars.size < ROWS: + raise ValueError(f'expected at least {ROWS} row scalars, got {row_scalars.size}') + row_scalars = row_scalars[:ROWS] + buffers = default_buffers(meta) + buffers[src0_name] = src0 + buffers[src1_name] = src1 + write_buffers(meta, buffers) + out = src0_m / row_scalars[:, None] + write_golden(meta, {single_output(meta): out.astype(np.float32).reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowexpandmul/rowexpandmul.py b/test/samples/Rowexpandmul/rowexpandmul.py index 54e93259..c1bdba31 100644 --- a/test/samples/Rowexpandmul/rowexpandmul.py +++ b/test/samples/Rowexpandmul/rowexpandmul.py @@ -15,14 +15,18 @@ def build(): tv2_f32 = pto.TensorViewType.get(2, f32, ctx) tile_view_32 = pto.PartitionTensorViewType.get([32, 32], f32, ctx) + tile_view_rowvec = pto.PartitionTensorViewType.get([32, 1], f32, ctx) vec = pto.AddressSpaceAttr.get(pto.AddressSpace.VEC, ctx) bl = pto.BLayoutAttr.get(pto.BLayout.RowMajor, ctx) + bl_col = pto.BLayoutAttr.get(pto.BLayout.ColMajor, ctx) sl = pto.SLayoutAttr.get(pto.SLayout.NoneBox, ctx) pd = pto.PadValueAttr.get(pto.PadValue.Null, ctx) fractal_ab_size = pto.TileConfig.fractalABSize cfg = pto.TileBufConfigAttr.get(bl, sl, fractal_ab_size, pd, ctx) + cfg_rowvec = pto.TileBufConfigAttr.get(bl_col, sl, fractal_ab_size, pd, ctx) tile_buf_32 = pto.TileBufType.get([32, 32], f32, vec, [32, 32], cfg, ctx) + tile_buf_rowvec = pto.TileBufType.get([32, 1], f32, vec, [32, 1], cfg_rowvec, ctx) fn_ty = func.FunctionType.get([ptr_f32, ptr_f32, ptr_f32], []) with InsertionPoint(m.body): @@ -39,16 +43,16 @@ def build(): # %0/%1/%2 = pto.make_tensor_view %arg?, shape=[%c32,%c32] strides=[%c32,%c1] tv0 = pto.MakeTensorViewOp(tv2_f32, arg0, [c32, c32], [c32, c1]).result - tv1 = pto.MakeTensorViewOp(tv2_f32, arg1, [c32, c32], [c32, c1]).result + tv1 = pto.MakeTensorViewOp(tv2_f32, arg1, [c32, c1], [c1, c1]).result tv2 = pto.MakeTensorViewOp(tv2_f32, arg2, [c32, c32], [c32, c1]).result # %3/%4/%8 = pto.subview %tv, offsets=[%c0,%c0], sizes=[32,32] sv0 = pto.PartitionViewOp(tile_view_32, tv0, offsets=[c0, c0], sizes=[c32, c32]).result - sv1 = pto.PartitionViewOp(tile_view_32, tv1, offsets=[c0, c0], sizes=[c32, c32]).result + sv1 = pto.PartitionViewOp(tile_view_rowvec, tv1, offsets=[c0, c0], sizes=[c32, c1]).result # %5/%6/%7 = pto.alloc_tile : <32x32xf32> tb0 = pto.AllocTileOp(tile_buf_32).result - tb1 = pto.AllocTileOp(tile_buf_32).result + tb1 = pto.AllocTileOp(tile_buf_rowvec).result tb2 = pto.AllocTileOp(tile_buf_32).result # pto.load_dps_tb ins(%sv) outs(%tb) diff --git a/test/samples/Rowexpandmul/rowexpandmul_compare.py b/test/samples/Rowexpandmul/rowexpandmul_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Rowexpandmul/rowexpandmul_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Rowexpandmul/rowexpandmul_golden.py b/test/samples/Rowexpandmul/rowexpandmul_golden.py new file mode 100755 index 00000000..f13fc9bc --- /dev/null +++ b/test/samples/Rowexpandmul/rowexpandmul_golden.py @@ -0,0 +1,34 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src0_name, src1_name = meta.inputs + generator = rng() + src0 = float_values(generator, meta.elem_counts[src0_name], style='signed') + src1 = float_values(generator, meta.elem_counts[src1_name], style='signed') + src0_m = matrix32(src0) + row_scalars = src1.astype(np.float32).reshape(-1) + if row_scalars.size < ROWS: + raise ValueError(f'expected at least {ROWS} row scalars, got {row_scalars.size}') + row_scalars = row_scalars[:ROWS] + buffers = default_buffers(meta) + buffers[src0_name] = src0 + buffers[src1_name] = src1 + write_buffers(meta, buffers) + out = src0_m * row_scalars[:, None] + write_golden(meta, {single_output(meta): out.astype(np.float32).reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowexpandsub/rowexpandsub.py b/test/samples/Rowexpandsub/rowexpandsub.py index bc99e685..5427d0c2 100644 --- a/test/samples/Rowexpandsub/rowexpandsub.py +++ b/test/samples/Rowexpandsub/rowexpandsub.py @@ -15,14 +15,18 @@ def build(): tv2_f32 = pto.TensorViewType.get(2, f32, ctx) tile_view_32 = pto.PartitionTensorViewType.get([32, 32], f32, ctx) + tile_view_rowvec = pto.PartitionTensorViewType.get([32, 1], f32, ctx) vec = pto.AddressSpaceAttr.get(pto.AddressSpace.VEC, ctx) bl = pto.BLayoutAttr.get(pto.BLayout.RowMajor, ctx) + bl_col = pto.BLayoutAttr.get(pto.BLayout.ColMajor, ctx) sl = pto.SLayoutAttr.get(pto.SLayout.NoneBox, ctx) pd = pto.PadValueAttr.get(pto.PadValue.Null, ctx) fractal_ab_size = pto.TileConfig.fractalABSize cfg = pto.TileBufConfigAttr.get(bl, sl, fractal_ab_size, pd, ctx) + cfg_rowvec = pto.TileBufConfigAttr.get(bl_col, sl, fractal_ab_size, pd, ctx) tile_buf_32 = pto.TileBufType.get([32, 32], f32, vec, [32, 32], cfg, ctx) + tile_buf_rowvec = pto.TileBufType.get([32, 1], f32, vec, [32, 1], cfg_rowvec, ctx) fn_ty = func.FunctionType.get([ptr_f32, ptr_f32, ptr_f32], []) with InsertionPoint(m.body): @@ -39,17 +43,17 @@ def build(): # %0/%1/%2 = pto.make_tensor_view %arg?, shape=[%c32,%c32] strides=[%c32,%c1] tv0 = pto.MakeTensorViewOp(tv2_f32, arg0, [c32, c32], [c32, c1]).result - tv1 = pto.MakeTensorViewOp(tv2_f32, arg1, [c32, c32], [c32, c1]).result + tv1 = pto.MakeTensorViewOp(tv2_f32, arg1, [c32, c1], [c1, c1]).result tv2 = pto.MakeTensorViewOp(tv2_f32, arg2, [c32, c32], [c32, c1]).result # %3/%4/%8 = pto.subview %tv, offsets=[%c0,%c0], sizes=[32,32] # Replaced the immediate numbers with constants (c0 and c32) sv0 = pto.PartitionViewOp(tile_view_32, tv0, offsets=[c0, c0], sizes=[c32, c32]).result - sv1 = pto.PartitionViewOp(tile_view_32, tv1, offsets=[c0, c0], sizes=[c32, c32]).result + sv1 = pto.PartitionViewOp(tile_view_rowvec, tv1, offsets=[c0, c0], sizes=[c32, c1]).result # %5/%6/%7 = pto.alloc_tile : <32x32xf32> tb0 = pto.AllocTileOp(tile_buf_32).result - tb1 = pto.AllocTileOp(tile_buf_32).result + tb1 = pto.AllocTileOp(tile_buf_rowvec).result tb2 = pto.AllocTileOp(tile_buf_32).result # pto.load_dps_tb ins(%sv) outs(%tb) @@ -73,4 +77,4 @@ def build(): if __name__ == "__main__": - print(build()) \ No newline at end of file + print(build()) diff --git a/test/samples/Rowexpandsub/rowexpandsub_compare.py b/test/samples/Rowexpandsub/rowexpandsub_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Rowexpandsub/rowexpandsub_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Rowexpandsub/rowexpandsub_golden.py b/test/samples/Rowexpandsub/rowexpandsub_golden.py new file mode 100755 index 00000000..c7743ff6 --- /dev/null +++ b/test/samples/Rowexpandsub/rowexpandsub_golden.py @@ -0,0 +1,34 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src0_name, src1_name = meta.inputs + generator = rng() + src0 = float_values(generator, meta.elem_counts[src0_name], style='signed') + src1 = float_values(generator, meta.elem_counts[src1_name], style='signed') + src0_m = matrix32(src0) + row_scalars = src1.astype(np.float32).reshape(-1) + if row_scalars.size < ROWS: + raise ValueError(f'expected at least {ROWS} row scalars, got {row_scalars.size}') + row_scalars = row_scalars[:ROWS] + buffers = default_buffers(meta) + buffers[src0_name] = src0 + buffers[src1_name] = src1 + write_buffers(meta, buffers) + out = src0_m - row_scalars[:, None] + write_golden(meta, {single_output(meta): out.astype(np.float32).reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowmax/rowmax_compare.py b/test/samples/Rowmax/rowmax_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Rowmax/rowmax_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Rowmax/rowmax_golden.py b/test/samples/Rowmax/rowmax_golden.py new file mode 100755 index 00000000..85f590c2 --- /dev/null +++ b/test/samples/Rowmax/rowmax_golden.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, COLS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + reduced = np.asarray(src_m.max(axis=1), dtype=np.float32) + out = np.zeros(meta.elem_counts[out_name], dtype=np.float32) + if out.size == ROWS * COLS: + out[:ROWS] = reduced + elif out.size == ROWS: + out = reduced + else: + raise ValueError(f'unsupported row-reduce output size: {out.size}') + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowmin/rowmin_compare.py b/test/samples/Rowmin/rowmin_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Rowmin/rowmin_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Rowmin/rowmin_golden.py b/test/samples/Rowmin/rowmin_golden.py new file mode 100755 index 00000000..f93d70ef --- /dev/null +++ b/test/samples/Rowmin/rowmin_golden.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, COLS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + reduced = np.asarray(src_m.min(axis=1), dtype=np.float32) + out = np.zeros(meta.elem_counts[out_name], dtype=np.float32) + if out.size == ROWS * COLS: + out[:ROWS] = reduced + elif out.size == ROWS: + out = reduced + else: + raise ValueError(f'unsupported row-reduce output size: {out.size}') + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rowsum/rowsum_compare.py b/test/samples/Rowsum/rowsum_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Rowsum/rowsum_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Rowsum/rowsum_golden.py b/test/samples/Rowsum/rowsum_golden.py new file mode 100755 index 00000000..b975a71e --- /dev/null +++ b/test/samples/Rowsum/rowsum_golden.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ROWS, COLS, default_buffers, float_values, load_case_meta, matrix32, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + src_m = matrix32(src) + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + reduced = np.asarray(src_m.sum(axis=1, dtype=np.float32), dtype=np.float32) + out = np.zeros(meta.elem_counts[out_name], dtype=np.float32) + if out.size == ROWS * COLS: + out[:ROWS] = reduced + elif out.size == ROWS: + out = reduced + else: + raise ValueError(f'unsupported row-reduce output size: {out.size}') + write_golden(meta, {out_name: out}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Rsqrt/rsqrt_compare.py b/test/samples/Rsqrt/rsqrt_compare.py new file mode 100755 index 00000000..870671d3 --- /dev/null +++ b/test/samples/Rsqrt/rsqrt_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.005) diff --git a/test/samples/Rsqrt/rsqrt_golden.py b/test/samples/Rsqrt/rsqrt_golden.py new file mode 100755 index 00000000..fc44506e --- /dev/null +++ b/test/samples/Rsqrt/rsqrt_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='positive') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = 1.0 / np.sqrt(src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Sel/sel_compare.py b/test/samples/Sel/sel_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Sel/sel_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Sel/sel_golden.py b/test/samples/Sel/sel_golden.py new file mode 100755 index 00000000..d561ac4a --- /dev/null +++ b/test/samples/Sel/sel_golden.py @@ -0,0 +1,46 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import ( + ROWS, + COLS, + default_buffers, + float_values, + load_case_meta, + matrix32, + pack_predicate_mask_for_buffer, + rng, + single_output, + write_buffers, + write_golden, +) + + +def main(): + meta = load_case_meta() + mask_name, src0_name, src1_name = meta.inputs + generator = rng() + mask_bits = generator.integers(0, 2, size=(ROWS, COLS), dtype=np.uint8).astype(np.bool_) + mask = pack_predicate_mask_for_buffer( + mask_bits, elem_count=meta.elem_counts[mask_name], dtype=meta.np_types[mask_name] + ) + src0 = float_values(generator, meta.elem_counts[src0_name], style='signed') + src1 = float_values(generator, meta.elem_counts[src1_name], style='signed') + buffers = default_buffers(meta) + buffers[mask_name] = mask + buffers[src0_name] = src0 + buffers[src1_name] = src1 + write_buffers(meta, buffers) + out = np.where(mask_bits, matrix32(src0), matrix32(src1)) + write_golden(meta, {single_output(meta): out.astype(np.float32).reshape(-1)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Sels/sels_compare.py b/test/samples/Sels/sels_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Sels/sels_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Sels/sels_golden.py b/test/samples/Sels/sels_golden.py new file mode 100755 index 00000000..f4830932 --- /dev/null +++ b/test/samples/Sels/sels_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src0_name, src1_name = meta.inputs + generator = rng() + src0 = float_values(generator, meta.elem_counts[src0_name], style='signed') + src1 = float_values(generator, meta.elem_counts[src1_name], style='signed') + buffers = default_buffers(meta) + buffers[src0_name] = src0 + buffers[src1_name] = src1 + write_buffers(meta, buffers) + out = src0 if 64 == 1 else src1 + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Shl/shl_compare.py b/test/samples/Shl/shl_compare.py new file mode 100755 index 00000000..8abe2165 --- /dev/null +++ b/test/samples/Shl/shl_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int32, atol=0.0) diff --git a/test/samples/Shl/shl_golden.py b/test/samples/Shl/shl_golden.py new file mode 100755 index 00000000..4d5c8139 --- /dev/null +++ b/test/samples/Shl/shl_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int32, style='shift_small') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.left_shift(src, src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Shls/shls_compare.py b/test/samples/Shls/shls_compare.py new file mode 100755 index 00000000..8abe2165 --- /dev/null +++ b/test/samples/Shls/shls_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int32, atol=0.0) diff --git a/test/samples/Shls/shls_golden.py b/test/samples/Shls/shls_golden.py new file mode 100755 index 00000000..1cef4efe --- /dev/null +++ b/test/samples/Shls/shls_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int32, style='shift_small') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.left_shift(src, np.asarray(2, dtype=np.int32).item()) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Shr/shr_compare.py b/test/samples/Shr/shr_compare.py new file mode 100755 index 00000000..8abe2165 --- /dev/null +++ b/test/samples/Shr/shr_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int32, atol=0.0) diff --git a/test/samples/Shr/shr_golden.py b/test/samples/Shr/shr_golden.py new file mode 100755 index 00000000..e2affab7 --- /dev/null +++ b/test/samples/Shr/shr_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int32, style='shift_small') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.right_shift(src, src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Shrs/shrs_compare.py b/test/samples/Shrs/shrs_compare.py new file mode 100755 index 00000000..8abe2165 --- /dev/null +++ b/test/samples/Shrs/shrs_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int32, atol=0.0) diff --git a/test/samples/Shrs/shrs_golden.py b/test/samples/Shrs/shrs_golden.py new file mode 100755 index 00000000..4b6320a2 --- /dev/null +++ b/test/samples/Shrs/shrs_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int32, style='shift_small') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.right_shift(src, np.asarray(2, dtype=np.int32).item()) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Sqrt/sqrt_compare.py b/test/samples/Sqrt/sqrt_compare.py new file mode 100755 index 00000000..03205d0a --- /dev/null +++ b/test/samples/Sqrt/sqrt_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.001) diff --git a/test/samples/Sqrt/sqrt_golden.py b/test/samples/Sqrt/sqrt_golden.py new file mode 100755 index 00000000..f441092a --- /dev/null +++ b/test/samples/Sqrt/sqrt_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='positive') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.sqrt(src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Sub/sub_compare.py b/test/samples/Sub/sub_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Sub/sub_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Sub/sub_golden.py b/test/samples/Sub/sub_golden.py new file mode 100755 index 00000000..593d8070 --- /dev/null +++ b/test/samples/Sub/sub_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs - rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Subc/subc_compare.py b/test/samples/Subc/subc_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Subc/subc_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Subc/subc_golden.py b/test/samples/Subc/subc_golden.py new file mode 100755 index 00000000..f782b058 --- /dev/null +++ b/test/samples/Subc/subc_golden.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + a_name, b_name, c_name = meta.inputs + generator = rng() + a = float_values(generator, meta.elem_counts[a_name], style='signed') + b = float_values(generator, meta.elem_counts[b_name], style='signed') + c = float_values(generator, meta.elem_counts[c_name], style='signed_small') + buffers = default_buffers(meta) + buffers[a_name] = a + buffers[b_name] = b + buffers[c_name] = c + write_buffers(meta, buffers) + out = a - b + c + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Subs/subs_compare.py b/test/samples/Subs/subs_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Subs/subs_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Subs/subs_golden.py b/test/samples/Subs/subs_golden.py new file mode 100755 index 00000000..daf6cc27 --- /dev/null +++ b/test/samples/Subs/subs_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src - np.float32(3.14) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Subsc/subsc_compare.py b/test/samples/Subsc/subsc_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/Subsc/subsc_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/Subsc/subsc_golden.py b/test/samples/Subsc/subsc_golden.py new file mode 100755 index 00000000..7d625d7e --- /dev/null +++ b/test/samples/Subsc/subsc_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = src - np.float32(3.14) + src + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Sync/test_dynamic_valid_shape_compare.py b/test/samples/Sync/test_dynamic_valid_shape_compare.py new file mode 100644 index 00000000..6764bd08 --- /dev/null +++ b/test/samples/Sync/test_dynamic_valid_shape_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0) diff --git a/test/samples/Sync/test_dynamic_valid_shape_golden.py b/test/samples/Sync/test_dynamic_valid_shape_golden.py new file mode 100644 index 00000000..82e8ff15 --- /dev/null +++ b/test/samples/Sync/test_dynamic_valid_shape_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + src_name = meta.inputs[0] + out_name = single_output(meta) + generator = rng() + src = float_values(generator, meta.elem_counts[src_name], style='signed') + dst_init = float_values(generator, meta.elem_counts[out_name], style='signed_small') + buffers = default_buffers(meta) + buffers[src_name] = src + buffers[out_name] = dst_init + write_buffers(meta, buffers) + write_golden(meta, {out_name: np.asarray(dst_init, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/VectorAddition/vadd_pto_ir_compare.py b/test/samples/VectorAddition/vadd_pto_ir_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/VectorAddition/vadd_pto_ir_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/VectorAddition/vadd_pto_ir_golden.py b/test/samples/VectorAddition/vadd_pto_ir_golden.py new file mode 100755 index 00000000..d6832130 --- /dev/null +++ b/test/samples/VectorAddition/vadd_pto_ir_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs + rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/VectorAddition/vectorAddition_compare.py b/test/samples/VectorAddition/vectorAddition_compare.py new file mode 100755 index 00000000..2a923d5f --- /dev/null +++ b/test/samples/VectorAddition/vectorAddition_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.float32, atol=0.0001) diff --git a/test/samples/VectorAddition/vectorAddition_golden.py b/test/samples/VectorAddition/vectorAddition_golden.py new file mode 100755 index 00000000..d6832130 --- /dev/null +++ b/test/samples/VectorAddition/vectorAddition_golden.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, float_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + lhs_name, rhs_name = meta.inputs + generator = rng() + lhs = float_values(generator, meta.elem_counts[lhs_name], style='signed') + rhs = float_values(generator, meta.elem_counts[rhs_name], style='signed') + buffers = default_buffers(meta) + buffers[lhs_name] = lhs + buffers[rhs_name] = rhs + write_buffers(meta, buffers) + out = lhs + rhs + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.float32)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Xor/xor_compare.py b/test/samples/Xor/xor_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/Xor/xor_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/Xor/xor_golden.py b/test/samples/Xor/xor_golden.py new file mode 100755 index 00000000..77eb0dc1 --- /dev/null +++ b/test/samples/Xor/xor_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_xor(src, src) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/Xors/xors_compare.py b/test/samples/Xors/xors_compare.py new file mode 100755 index 00000000..6173882b --- /dev/null +++ b/test/samples/Xors/xors_compare.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +import numpy as np +from validation_runtime import compare_outputs + +if __name__ == '__main__': + compare_outputs(np.int16, atol=0.0) diff --git a/test/samples/Xors/xors_golden.py b/test/samples/Xors/xors_golden.py new file mode 100755 index 00000000..267946bf --- /dev/null +++ b/test/samples/Xors/xors_golden.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import numpy as np +from pathlib import Path +import sys + +for search_root in (Path(__file__).resolve().parent, Path(__file__).resolve().parents[1]): + if (search_root / 'validation_runtime.py').is_file(): + sys.path.insert(0, str(search_root)) + break + +from validation_runtime import default_buffers, int_values, load_case_meta, rng, single_output, write_buffers, write_golden + + +def main(): + meta = load_case_meta() + [src_name] = meta.inputs + generator = rng() + src = int_values(generator, meta.elem_counts[src_name], dtype=np.int16, style='bitwise') + buffers = default_buffers(meta) + buffers[src_name] = src + write_buffers(meta, buffers) + out = np.bitwise_xor(src, np.asarray(88, dtype=np.int16).item()) + write_golden(meta, {single_output(meta): np.asarray(out, dtype=np.int16)}) + + +if __name__ == '__main__': + main() diff --git a/test/samples/runop.sh b/test/samples/runop.sh index ee50e931..d6345d5f 100755 --- a/test/samples/runop.sh +++ b/test/samples/runop.sh @@ -180,6 +180,11 @@ process_one_dir() { local f mlir ptobc_file decoded_pto cpp base overall=0 for f in "$dir"/*.py; do [[ -f "$f" ]] || continue + case "$(basename "$f")" in + *_golden.py|*_compare.py|validation_runtime.py) + continue + ;; + esac base="$(basename "$f" .py)" local expect_fail=0 case "$base" in diff --git a/test/samples/validation_runtime.py b/test/samples/validation_runtime.py new file mode 100644 index 00000000..8b02b843 --- /dev/null +++ b/test/samples/validation_runtime.py @@ -0,0 +1,306 @@ +#!/usr/bin/python3 +import os +import re +import sys +from dataclasses import dataclass +from pathlib import Path +from typing import Dict, List + +import numpy as np + +SEED = 19 +ROWS = 32 +COLS = 32 + +_HOST_TYPE_TO_NP = { + "aclFloat16": np.float16, + "bfloat16_t": np.uint16, + "bool": np.bool_, + "double": np.float64, + "float": np.float32, + "half": np.float16, + "int": np.int32, + "int8_t": np.int8, + "int16_t": np.int16, + "int32_t": np.int32, + "int64_t": np.int64, + "size_t": np.uint64, + "uint8_t": np.uint8, + "uint16_t": np.uint16, + "uint32_t": np.uint32, + "uint64_t": np.uint64, + "unsigned": np.uint32, +} + + +@dataclass +class CaseMeta: + elem_counts: Dict[str, int] + np_types: Dict[str, np.dtype] + read_order: List[str] + outputs: List[str] + + @property + def inputs(self) -> List[str]: + return [name for name in self.read_order if name not in self.outputs] + + +def load_case_meta(main_cpp: str = 'main.cpp', outputs_txt: str = 'outputs.txt') -> CaseMeta: + text = Path(main_cpp).read_text(encoding='utf-8') + elem_counts = { + match.group(1): int(match.group(2)) + for match in re.finditer(r'size_t\s+elemCount_(\w+)\s*=\s*(\d+);', text) + } + np_types = { + match.group(1): np.dtype(_HOST_TYPE_TO_NP[match.group(2).strip()]) + for match in re.finditer( + r'size_t\s+fileSize_(\w+)\s*=\s*elemCount_\1\s*\*\s*sizeof\(([^)]+)\);', + text, + ) + } + read_order = re.findall(r'ReadFile\("\./([^"]+)\.bin"', text) + outputs_path = Path(outputs_txt) + outputs = [] + if outputs_path.is_file(): + outputs = [line.strip() for line in outputs_path.read_text(encoding='utf-8').splitlines() if line.strip()] + return CaseMeta(elem_counts=elem_counts, np_types=np_types, read_order=read_order, outputs=outputs) + + +def load_scalar_assignments(ctype: str, main_cpp: str = 'main.cpp') -> List[int]: + text = Path(main_cpp).read_text(encoding='utf-8') + pattern = rf'{re.escape(ctype)}\s+\w+\s*=\s*(-?\d+);' + return [int(value) for value in re.findall(pattern, text)] + + +def load_int32_assignments(main_cpp: str = 'main.cpp') -> List[int]: + return load_scalar_assignments('int32_t', main_cpp=main_cpp) + + +def rng(): + return np.random.default_rng(SEED) + + +def float_values(generator, count: int, *, style: str) -> np.ndarray: + if style == 'signed': + values = generator.uniform(-3.0, 3.0, size=count).astype(np.float32) + elif style == 'signed_small': + values = generator.uniform(-1.5, 1.5, size=count).astype(np.float32) + elif style == 'nonzero_signed': + values = generator.uniform(-3.0, 3.0, size=count).astype(np.float32) + mask = np.abs(values) < np.float32(0.25) + values[mask] = np.where(values[mask] >= 0.0, np.float32(0.25), np.float32(-0.25)) + elif style == 'positive': + values = generator.uniform(0.25, 4.0, size=count).astype(np.float32) + elif style in {'exp', 'cmp'}: + values = generator.uniform(-2.0, 2.0, size=count).astype(np.float32) + else: + raise ValueError(f'unsupported float style: {style}') + return values + + +def int_values(generator, count: int, dtype: np.dtype, *, style: str) -> np.ndarray: + dtype = np.dtype(dtype) + if dtype == np.dtype(np.int16): + if style != 'bitwise': + raise ValueError(f'unsupported int16 style: {style}') + values = generator.integers(-256, 256, size=count, dtype=np.int32) + elif dtype == np.dtype(np.int32): + if style == 'bitwise': + values = generator.integers(-256, 256, size=count, dtype=np.int32) + elif style == 'shift_small': + values = generator.integers(0, 4, size=count, dtype=np.int32) + else: + raise ValueError(f'unsupported int32 style: {style}') + else: + raise ValueError(f'unsupported dtype/style pair: {dtype}/{style}') + return values.astype(dtype, copy=False) + + +def matrix32(values: np.ndarray, rows: int = ROWS, cols: int = COLS) -> np.ndarray: + flat = np.asarray(values).reshape(-1) + expected = rows * cols + if flat.size != expected: + raise ValueError(f'expected {expected} elements, got {flat.size}') + return flat.reshape(rows, cols) + + +def default_buffers(meta: CaseMeta): + return {name: np.zeros(meta.elem_counts[name], dtype=meta.np_types[name]) for name in meta.read_order} + + +def write_buffers(meta: CaseMeta, buffers): + for name in meta.read_order: + if name not in buffers: + raise KeyError(f'missing buffer for {name}') + array = np.asarray(buffers[name], dtype=meta.np_types[name]).reshape(-1) + expected = meta.elem_counts[name] + if array.size != expected: + raise ValueError(f'{name}: expected {expected} elements, got {array.size}') + array.tofile(f'{name}.bin') + + +def write_golden(meta: CaseMeta, outputs): + for name in meta.outputs: + if name not in outputs: + raise KeyError(f'missing golden for {name}') + array = np.asarray(outputs[name], dtype=meta.np_types[name]).reshape(-1) + expected = meta.elem_counts[name] + if array.size != expected: + raise ValueError(f'{name}: expected {expected} golden elements, got {array.size}') + array.tofile(f'golden_{name}.bin') + + +def single_output(meta: CaseMeta) -> str: + if len(meta.outputs) != 1: + raise ValueError(f'expected exactly one output, got {meta.outputs}') + return meta.outputs[0] + + +def packed_row_bytes(cols: int) -> int: + return (cols + 7) // 8 + + +def packed_mask_storage_bytes(elem_count: int, dtype) -> int: + return int(elem_count) * np.dtype(dtype).itemsize + + +def packed_mask_storage_cols(*, elem_count: int, dtype, rows: int = ROWS) -> int: + storage_bytes = packed_mask_storage_bytes(elem_count, dtype) + if storage_bytes % rows != 0: + raise ValueError(f'packed mask storage {storage_bytes} bytes is not divisible by rows={rows}') + return storage_bytes // rows + + +def pack_predicate_mask(bits: np.ndarray, *, storage_cols: int) -> np.ndarray: + bits = np.asarray(bits, dtype=np.bool_) + if bits.ndim != 2: + raise ValueError('mask bits must be a 2D array') + rows, cols = bits.shape + used_cols = packed_row_bytes(cols) + if storage_cols < used_cols: + raise ValueError(f'storage_cols={storage_cols} is too small for cols={cols}') + packed = np.zeros((rows, storage_cols), dtype=np.uint8) + for row in range(rows): + for byte_index, base_col in enumerate(range(0, cols, 8)): + width = min(8, cols - base_col) + packed_byte = 0 + for bit_index in range(width): + if bits[row, base_col + bit_index]: + packed_byte |= 1 << bit_index + packed[row, byte_index] = packed_byte + return packed.reshape(-1) + + +def pack_predicate_mask_for_buffer(bits: np.ndarray, *, elem_count: int, dtype, rows: int = ROWS) -> np.ndarray: + dtype = np.dtype(dtype) + storage_cols = packed_mask_storage_cols(elem_count=elem_count, dtype=dtype, rows=rows) + packed_bytes = pack_predicate_mask(bits, storage_cols=storage_cols) + expected_bytes = packed_mask_storage_bytes(elem_count, dtype) + if packed_bytes.nbytes != expected_bytes: + raise ValueError( + f'packed mask byte size mismatch: expected {expected_bytes}, got {packed_bytes.nbytes}' + ) + return np.frombuffer(packed_bytes.tobytes(), dtype=dtype).copy() + + +def _report_compare_failure(golden: np.ndarray, output: np.ndarray, golden_path: str, output_path: str): + if golden.size == 0: + print(f'[ERROR] Mismatch: {golden_path} vs {output_path}, empty buffers') + return + if np.issubdtype(golden.dtype, np.integer) or np.issubdtype(golden.dtype, np.unsignedinteger): + golden_cmp = golden.astype(np.int64, copy=False) + output_cmp = output.astype(np.int64, copy=False) + else: + golden_cmp = golden.astype(np.float64, copy=False) + output_cmp = output.astype(np.float64, copy=False) + diff = np.abs(golden_cmp - output_cmp) + index = int(np.argmax(diff)) + print( + f'[ERROR] Mismatch: {golden_path} vs {output_path}, max diff={float(diff[index])} at idx={index} ' + f'(golden={golden_cmp[index]}, out={output_cmp[index]}, dtype={golden.dtype})' + ) + + +def compare_file(golden_path: str, output_path: str, dtype, atol: float) -> bool: + if not os.path.exists(output_path): + print(f'[ERROR] Output missing: {output_path}') + return False + if not os.path.exists(golden_path): + print(f'[ERROR] Golden missing: {golden_path}') + return False + dtype = np.dtype(dtype) + golden = np.fromfile(golden_path, dtype=dtype) + output = np.fromfile(output_path, dtype=dtype) + if golden.shape != output.shape: + print(f'[ERROR] Shape mismatch: {golden_path} {golden.shape} vs {output_path} {output.shape}') + return False + if np.issubdtype(dtype, np.integer) or np.issubdtype(dtype, np.unsignedinteger): + if atol == 0.0: + ok = np.array_equal(golden, output) + else: + ok = np.allclose(golden, output, atol=atol, rtol=atol) + else: + ok = np.allclose(golden, output, atol=atol, rtol=atol, equal_nan=True) + if not ok: + _report_compare_failure(golden, output, golden_path, output_path) + return False + return True + + +def compare_packed_mask_file(golden_path: str, output_path: str, *, rows: int = ROWS, cols: int = COLS) -> bool: + if not os.path.exists(output_path): + print(f'[ERROR] Output missing: {output_path}') + return False + if not os.path.exists(golden_path): + print(f'[ERROR] Golden missing: {golden_path}') + return False + golden = np.fromfile(golden_path, dtype=np.uint8) + output = np.fromfile(output_path, dtype=np.uint8) + if golden.size % rows != 0 or output.size % rows != 0: + print(f'[ERROR] Packed mask buffer size is not divisible by rows={rows}') + return False + golden_cols = golden.size // rows + output_cols = output.size // rows + used_cols = packed_row_bytes(cols) + if golden_cols < used_cols or output_cols < used_cols: + print(f'[ERROR] Packed mask storage is too small: need {used_cols} bytes per row') + return False + golden_view = golden.reshape(rows, golden_cols)[:, :used_cols].reshape(-1) + output_view = output.reshape(rows, output_cols)[:, :used_cols].reshape(-1) + if not np.array_equal(golden_view, output_view): + diff = np.nonzero(golden_view != output_view)[0] + index = int(diff[0]) if diff.size else 0 + print( + f'[ERROR] Packed mask mismatch: {golden_path} vs {output_path}, idx={index} ' + f'(golden={int(golden_view[index])}, out={int(output_view[index])})' + ) + return False + return True + + +def finalize_compare(ok: bool): + strict = os.getenv('COMPARE_STRICT', '1') != '0' + if not ok: + if strict: + print('[ERROR] compare failed') + sys.exit(2) + print('[WARN] compare failed (non-gating)') + return False + print('[INFO] compare passed') + return True + + +def compare_outputs(dtype, atol: float): + meta = load_case_meta() + ok = True + for name in meta.outputs: + ok = compare_file(f'golden_{name}.bin', f'{name}.bin', dtype, atol) and ok + return finalize_compare(ok) + + +def compare_packed_mask_outputs(*, rows: int = ROWS, cols: int = COLS): + meta = load_case_meta() + ok = True + for name in meta.outputs: + ok = compare_packed_mask_file(f'golden_{name}.bin', f'{name}.bin', rows=rows, cols=cols) and ok + return finalize_compare(ok)