From bcc027ea713935bb38bfa7e00cf79e9299f2ebff Mon Sep 17 00:00:00 2001 From: Daniel-Schenker Date: Thu, 30 Jul 2026 15:46:01 -0400 Subject: [PATCH 1/4] Add runai-model-streamer build script and metadata --- r/runai-model-streamer/LICENSE | 201 +++++ r/runai-model-streamer/build_info.json | 24 + .../runai-model-streamer_0.16.1_ubi_10.2.sh | 747 ++++++++++++++++++ 3 files changed, 972 insertions(+) create mode 100644 r/runai-model-streamer/LICENSE create mode 100644 r/runai-model-streamer/build_info.json create mode 100644 r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh diff --git a/r/runai-model-streamer/LICENSE b/r/runai-model-streamer/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/r/runai-model-streamer/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/r/runai-model-streamer/build_info.json b/r/runai-model-streamer/build_info.json new file mode 100644 index 0000000000..4b987c83c5 --- /dev/null +++ b/r/runai-model-streamer/build_info.json @@ -0,0 +1,24 @@ +{ + "maintainer":"Daniel-Schenker", + "package_name" : "runai-model-streamer", + "github_url":"https://github.com/run-ai/runai-model-streamer", + "version": "0.16.1", + "default_branch": "master", + "category": "default", + "package_dir": "r/runai-model-streamer", + "docker_cmd":"NA", + "build_script": "runai-model-streamer_0.16.1_ubi_10.2.sh", + "docker_build": "false", + "validate_build_script": "true", + "use_non_root_user": "false", + "wheel_build": "true", + "wheel_name": "runai-model-streamer", + + "required_versions": { + "Releases": "[0.16.1]", + "Tags": "[0.16.1]" + }, + "*": { + "build_script":"runai-model-streamer_0.16.1_ubi_10.2.sh" + } +} diff --git a/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh b/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh new file mode 100644 index 0000000000..c0008d843d --- /dev/null +++ b/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh @@ -0,0 +1,747 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# +# Package : runai-model-streamer +# Version : 0.16.1 +# Source repo : https://github.com/run-ai/runai-model-streamer +# Tested on : UBI 10 (ppc64le) +# Language : Python, C++ +# Ci-Check : True +# Script License: Apache License, Version 2 or later +# Maintainer : Daniel Schenker +# +# Disclaimer: This script has been tested in root mode on given +# ========== platform using the mentioned version of the package. +# It may not work as expected with newer versions of the +# package and/or distribution. In such case, please +# contact "Maintainer" of this script. +# +# ---------------------------------------------------------------------------- +# +# Clones runai-model-streamer, applies all ppc64le patches, and builds the two +# wheel files: +# runai_model_streamer--py3-none-manylinux2014_ppc64le.whl +# runai_model_streamer_s3--py3-none-manylinux2014_ppc64le.whl +# +# Bazel is not available as a pre-built binary for ppc64le. This script +# bootstraps Bazel 7.6.1 from the official source distribution (dist.zip) +# using only the JDK and GCC Toolset 15. The resulting binary is installed +# to /usr/local/bin/bazel. Pass --skip-bazel-build if it is already present. +# +# Usage: +# ./runai-model-streamer_0.16.1_ubi_10.2.sh [--version 0.16.1] [--workdir $HOME] +# [--output-dir $HOME/vllm-wheels] +# [--skip-bazel-build] +# [--skip-aws-build] [--bazel-clean] +# +set -Eeuo pipefail + +SCRIPT_NAME="$(basename "$0")" + +# ─── Defaults ───────────────────────────────────────────────────────────────── +PACKAGE_VERSION="0.16.1" +BAZEL_VERSION="7.6.1" +WORK_DIR="${HOME}" +OUTPUT_DIR="" # resolved to ${WORK_DIR}/vllm-wheels after arg parsing +SKIP_BAZEL_BUILD=0 +SKIP_AWS_BUILD=0 +BAZEL_CLEAN=0 + +# ─── Helpers ────────────────────────────────────────────────────────────────── +die() { echo "ERROR: $*" >&2; exit 1; } +info() { echo "==> $*"; } + +usage() { + cat </vllm-wheels) + --skip-bazel-build skip Bazel bootstrap (requires bazel already on PATH) + --skip-aws-build skip cloning/building aws-sdk-cpp (if already installed) + --bazel-clean run 'bazel clean --expunge' before the main build + -h, --help show this help and exit +EOF +} + +# ─── Argument parsing ───────────────────────────────────────────────────────── +while [[ $# -gt 0 ]]; do + case "$1" in + --version) PACKAGE_VERSION="$2"; shift 2 ;; + --bazel-version) BAZEL_VERSION="$2"; shift 2 ;; + --workdir) WORK_DIR="$2"; shift 2 ;; + --output-dir) OUTPUT_DIR="$2"; shift 2 ;; + --skip-bazel-build) SKIP_BAZEL_BUILD=1; shift ;; + --skip-aws-build) SKIP_AWS_BUILD=1; shift ;; + --bazel-clean) BAZEL_CLEAN=1; shift ;; + -h|--help) usage; exit 0 ;; + *) die "Unknown option: $1" ;; + esac +done + +# Resolve OUTPUT_DIR now that WORK_DIR is final +OUTPUT_DIR="${OUTPUT_DIR:-${WORK_DIR}/vllm-wheels}" + +# ─── System packages ────────────────────────────────────────────────────────── +info "Installing system dependencies" +dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm +dnf install -y \ + git \ + gcc-toolset-15 \ + gcc-c++ \ + cmake \ + ninja-build \ + java-21-openjdk-devel \ + libcurl-devel \ + openssl-devel \ + libuuid-devel \ + unzip \ + zip \ + patch \ + python3.13 \ + python3.13-devel + +REPO_DIR="$WORK_DIR/runai-model-streamer" + +# ─── Environment setup ──────────────────────────────────────────────────────── +info "Configuring environment" +export JAVA_HOME=/usr/lib/jvm/java-21-openjdk +export BAZEL_JAVAC_OPTS="-J-Xmx2g -J-Xms200m" +export PATH="$JAVA_HOME/bin:$PATH" +export PACKAGE_VERSION + +# Enable GCC Toolset 15. +# Some installations provide an 'enable' script; others only have the bin dir. +GCC_TOOLSET_BIN="/opt/rh/gcc-toolset-15/root/usr/bin" +if [[ -f /opt/rh/gcc-toolset-15/enable ]]; then + # shellcheck disable=SC1091 + source /opt/rh/gcc-toolset-15/enable +elif [[ -d "$GCC_TOOLSET_BIN" ]]; then + export PATH="$GCC_TOOLSET_BIN:$PATH" +else + die "/opt/rh/gcc-toolset-15 not found — install gcc-toolset-15" +fi + +# ─── Step 0: Bootstrap Bazel from source ────────────────────────────────────── +# No pre-built Bazel binary exists for ppc64le. We bootstrap from the official +# source distribution (dist.zip), which only requires a JDK and a C++ compiler. +# The compiled binary is installed to /usr/local/bin/bazel. +if [[ "$SKIP_BAZEL_BUILD" -eq 1 ]]; then + command -v bazel &>/dev/null \ + || die "--skip-bazel-build set but bazel not found on PATH" + info "Skipping Bazel bootstrap — using $(command -v bazel) ($(bazel version 2>/dev/null | head -1))" +else + BAZEL_DIST_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-dist.zip" + BAZEL_DIST_ZIP="$WORK_DIR/bazel-${BAZEL_VERSION}-dist.zip" + BAZEL_BUILD_DIR="$WORK_DIR/bazel-${BAZEL_VERSION}-src" + + if [[ -x /usr/local/bin/bazel ]]; then + INSTALLED_VER="$(/usr/local/bin/bazel version 2>/dev/null | awk '/Build label/{print $NF}')" + if [[ "$INSTALLED_VER" == "$BAZEL_VERSION" ]]; then + info "Bazel $BAZEL_VERSION already installed at /usr/local/bin/bazel — skipping bootstrap" + SKIP_BAZEL_BUILD=1 + fi + fi + + if [[ "$SKIP_BAZEL_BUILD" -eq 0 ]]; then + info "Downloading Bazel $BAZEL_VERSION source distribution" + [[ -f "$BAZEL_DIST_ZIP" ]] \ + || curl -fL "$BAZEL_DIST_URL" -o "$BAZEL_DIST_ZIP" + + info "Extracting Bazel source distribution" + if [[ ! -d "$BAZEL_BUILD_DIR" ]]; then + mkdir -p "$BAZEL_BUILD_DIR" + unzip -q "$BAZEL_DIST_ZIP" -d "$BAZEL_BUILD_DIR" + fi + + info "Bootstrapping Bazel (this may take 10–20 minutes)" + cd "$BAZEL_BUILD_DIR" + # Bazel 7.6.1 sources are not compatible with GCC 15 (missing + # transitive includes). RHEL 10 ships GCC 14 as the system compiler + # (/usr/bin/gcc from gcc-c++), which builds Bazel cleanly. We + # temporarily shadow the toolset-15 gcc/g++ with the system versions + # just for this bootstrap, then restore PATH afterwards. + # + # EXTRA_BAZEL_ARGS is forwarded to the inner 'bazel build' call: + # --tool_java_runtime_version=local_jdk prevents the bootstrap from + # downloading a hermetic JDK; it uses the system JDK instead. + # --jobs=N caps parallel actions so the bootstrap does not exhaust + # the system thread limit (EAGAIN from pthread_create). Each + # parallel JVM action needs ~10 threads; 4 jobs keeps peak thread + # count well within default container limits. + # + # ulimit -u raises the per-user max processes/threads ceiling for this + # shell; the kernel default in many container runtimes is low (1024). + ulimit -u unlimited 2>/dev/null || ulimit -u 65536 2>/dev/null || true + SAVED_PATH="$PATH" + export PATH="/usr/bin:/usr/sbin:${PATH}" + export CC=/usr/bin/gcc + export CXX=/usr/bin/g++ + export EXTRA_BAZEL_ARGS="--tool_java_runtime_version=local_jdk --jobs=4" + bash compile.sh + export PATH="$SAVED_PATH" + unset CC CXX + + install -m 0755 output/bazel /usr/local/bin/bazel + info "Bazel installed: $(bazel version 2>/dev/null | head -1)" + cd "$WORK_DIR" + fi +fi + +# ─── Step 1: Clone the repository and checkout the requested version ────────── +info "Cloning runai-model-streamer into $REPO_DIR" +if [[ -d "$REPO_DIR" ]]; then + info "Directory already exists — skipping clone" +else + git clone https://github.com/run-ai/runai-model-streamer "$REPO_DIR" +fi + +cd "$REPO_DIR" + +# Checkout the tag that matches PACKAGE_VERSION. +# The repo uses tags like "v0.15.7"; fall back to bare "0.15.7" if not found. +info "Checking out version $PACKAGE_VERSION" +if git rev-parse "v${PACKAGE_VERSION}" &>/dev/null; then + git checkout "v${PACKAGE_VERSION}" +elif git rev-parse "${PACKAGE_VERSION}" &>/dev/null; then + git checkout "${PACKAGE_VERSION}" +else + die "No git tag found for version '$PACKAGE_VERSION' (tried v${PACKAGE_VERSION} and ${PACKAGE_VERSION})" +fi + +info "HEAD commit: $(git log --oneline -1)" + +# ─── Step 2: Patch top-level Makefile ───────────────────────────────────────── +# The upstream Makefile uses TABS for recipe indentation. +# "build:" has a trailing space: "build: " +info "Patching Makefile (ppc64le arch + build target)" + +python3 - <<'PYEOF' +path = "Makefile" +with open(path) as fh: + src = fh.read() + +changed = False + +# 1) Insert PPC64LE_ARCH variable after AARCH64_ARCH line +if "PPC64LE_ARCH" not in src: + src = src.replace( + "AARCH64_ARCH := aarch64", + "AARCH64_ARCH := aarch64\nPPC64LE_ARCH := ppc64le" + ) + changed = True + +# 2) Insert build_ppc64le target after build_aarch64 block (tab-indented) +OLD_AARCH64 = ( + "build_aarch64:\n" + "\tmake -C cpp build ARCH=${AARCH64_ARCH} && \\\n" + "\tmake -C py build ARCH=${AARCH64_ARCH}" +) +NEW_AARCH64_PLUS_PPC = ( + "build_aarch64:\n" + "\tmake -C cpp build ARCH=${AARCH64_ARCH} && \\\n" + "\tmake -C py build ARCH=${AARCH64_ARCH}\n" + "\n" + "build_ppc64le:\n" + "\tmake -C cpp build ARCH=${PPC64LE_ARCH} && \\\n" + "\tmake -C py build ARCH=${PPC64LE_ARCH}" +) +if "build_ppc64le:" not in src: + if OLD_AARCH64 in src: + src = src.replace(OLD_AARCH64, NEW_AARCH64_PLUS_PPC) + changed = True + else: + print(" WARNING: could not find build_aarch64 block — dumping for diagnosis:") + idx = src.find("build_aarch64") + print(repr(src[idx:idx+200]) if idx >= 0 else " (not found)") + +# 3) Replace the build: recipe — note the trailing space after "build:" +OLD_BUILD = ( + "build: \n" + "\tmake -C py clean && \\\n" + "\tmake build_x86_64 && \\\n" + "\tmake build_aarch64" +) +NEW_BUILD = ( + "build: \n" + "\tmake -C py clean && \\\n" + "\tmake build_ppc64le" +) +if NEW_BUILD not in src: + if OLD_BUILD in src: + src = src.replace(OLD_BUILD, NEW_BUILD) + changed = True + else: + print(" WARNING: could not find expected build: recipe — dumping for diagnosis:") + idx = src.find("build:") + print(repr(src[idx:idx+200]) if idx >= 0 else " (not found)") + +with open(path, "w") as fh: + fh.write(src) +print(" Makefile patched OK" if changed else " Makefile already fully patched — skipping") +PYEOF + +# ─── Step 3: Patch cpp/.bazelrc ─────────────────────────────────────────────── +info "Patching cpp/.bazelrc (ppc64le platform suffix)" + +python3 - <<'PYEOF' +path = "cpp/.bazelrc" +with open(path) as fh: + src = fh.read() + +if "build:ppc64le" not in src: + src = src.rstrip("\n") + "\n\nbuild:ppc64le --platform_suffix=ppc64le\n" + with open(path, "w") as fh: + fh.write(src) + print(" cpp/.bazelrc patched OK") +else: + print(" cpp/.bazelrc already patched — skipping") +PYEOF + +# ─── Step 4: Patch cpp/cc/freeres/freeres.cc ────────────────────────────────── +# Removes the hidden visibility attribute that causes link errors on ppc64le. +info "Patching cpp/cc/freeres/freeres.cc (__freeres visibility)" + +python3 - <<'PYEOF' +path = "cpp/cc/freeres/freeres.cc" +with open(path) as fh: + src = fh.read() + +old = ' __attribute__((visibility("hidden"))) void __freeres();' +new = ' void __freeres();' +if old in src: + src = src.replace(old, new) + with open(path, "w") as fh: + fh.write(src) + print(" freeres.cc patched OK") +else: + print(" freeres.cc already patched — skipping") +PYEOF + +# ─── Step 5: Patch cpp/third_party/aws.bzl ──────────────────────────────────── +# Replaces the original static-only linkopts with a dynamic/static select() +# block that also adds the /usr/local/lib64 search path for the system-installed +# aws-sdk-cpp. Uses exact literal replacement against the known upstream content. +info "Patching cpp/third_party/aws.bzl (linkopts)" + +python3 - <<'PYEOF' +path = "cpp/third_party/aws.bzl" +with open(path) as fh: + src = fh.read() + +if '"-L/usr/local/lib64"' in src: + print(" aws.bzl already patched — skipping") + raise SystemExit(0) + +# Exact upstream linkopts block (no -L lines, simple static list + small select) +OLD_LINKOPTS = ( + " linkopts = [\n" + ' "-lpthread",\n' + ' "-l:libaws-cpp-sdk-s3-crt.a",\n' + ' "-l:libaws-cpp-sdk-core.a",\n' + ' "-l:libaws-crt-cpp.a",\n' + ' "-l:libaws-c-mqtt.a",\n' + ' "-l:libaws-c-event-stream.a",\n' + ' "-l:libaws-c-s3.a",\n' + ' "-l:libaws-c-auth.a",\n' + ' "-l:libaws-c-http.a",\n' + ' "-l:libaws-c-io.a",\n' + ' "-l:libs2n.a",\n' + ' "-l:libaws-c-compression.a",\n' + ' "-l:libaws-c-cal.a",\n' + ' "-l:libaws-c-sdkutils.a",\n' + ' "-l:libaws-checksums.a",\n' + ' "-l:libaws-c-common.a",\n' + ' "-ldl -lm -lrt",\n' + ' "-L/opt/%s-curl/lib" % arch,\n' + ' "-L/opt/%s-ssl/lib" % arch,\n' + ' "-L/opt/%s-zlib/lib" % arch,\n' + ' "-L/opt/%s-aws/lib" % arch,\n' + " ] + select({\n" + ' "//:dynamic_link": ["-lz", "-lssl", "-lcrypto", "-lcurl"],\n' + ' "//conditions:default": [\n' + ' "-l:libz.a",\n' + ' "-l:libcurl.a",\n' + ' "-l:libssl.a",\n' + ' "-l:libcrypto.a",\n' + " ],\n" + " })," +) +NEW_LINKOPTS = ( + " linkopts = [\n" + ' "-lpthread",\n' + ' "-L/usr/local/lib64",\n' + ' "-L/opt/%s-curl/lib" % arch,\n' + ' "-L/opt/%s-ssl/lib" % arch,\n' + ' "-L/opt/%s-zlib/lib" % arch,\n' + ' "-L/opt/%s-aws/lib" % arch,\n' + ' "-Wl,-rpath,/usr/local/lib64",\n' + " ] + select({\n" + ' "//:dynamic_link": [\n' + ' # Dynamic linking for all libraries\n' + ' "-laws-cpp-sdk-s3-crt",\n' + ' "-laws-cpp-sdk-core",\n' + ' "-laws-crt-cpp",\n' + ' "-laws-c-mqtt",\n' + ' "-laws-c-event-stream",\n' + ' "-laws-c-s3",\n' + ' "-laws-c-auth",\n' + ' "-laws-c-http",\n' + ' "-laws-c-io",\n' + ' "-ls2n",\n' + ' "-laws-c-compression",\n' + ' "-laws-c-cal",\n' + ' "-laws-c-sdkutils",\n' + ' "-laws-checksums",\n' + ' "-laws-c-common",\n' + ' "-lz",\n' + ' "-lssl",\n' + ' "-lcrypto",\n' + ' "-lcurl",\n' + ' "-ldl",\n' + ' "-lm",\n' + ' "-lrt",\n' + ' ],\n' + ' "//conditions:default": [\n' + ' # Static linking (original)\n' + ' "-l:libaws-cpp-sdk-s3-crt.a",\n' + ' "-l:libaws-cpp-sdk-core.a",\n' + ' "-l:libaws-crt-cpp.a",\n' + ' "-l:libaws-c-mqtt.a",\n' + ' "-l:libaws-c-event-stream.a",\n' + ' "-l:libaws-c-s3.a",\n' + ' "-l:libaws-c-auth.a",\n' + ' "-l:libaws-c-http.a",\n' + ' "-l:libaws-c-io.a",\n' + ' "-l:libs2n.a",\n' + ' "-l:libaws-c-compression.a",\n' + ' "-l:libaws-c-cal.a",\n' + ' "-l:libaws-c-sdkutils.a",\n' + ' "-l:libaws-checksums.a",\n' + ' "-l:libaws-c-common.a",\n' + ' "-l:libz.a",\n' + ' "-l:libcurl.a",\n' + ' "-l:libssl.a",\n' + ' "-l:libcrypto.a",\n' + ' "-ldl",\n' + ' "-lm",\n' + ' "-lrt",\n' + ' ],\n' + " })," +) + +if OLD_LINKOPTS in src: + src = src.replace(OLD_LINKOPTS, NEW_LINKOPTS) + with open(path, "w") as fh: + fh.write(src) + print(" aws.bzl patched OK") +else: + print(" WARNING: could not find expected linkopts block in aws.bzl — dumping:") + idx = src.find("linkopts") + print(repr(src[idx:idx+400]) if idx >= 0 else " (not found)") +PYEOF + +# ─── Step 6: Patch cpp/third_party/aws.BUILD (in-repo Bazel external file) ──── +# This file is the template Bazel uses to populate the external/aws/ package. +# It needs the ppc64le config_setting, library declaration, and alias entry. +info "Patching cpp/third_party/aws.BUILD (ppc64le config + alias)" + +python3 - <<'PYEOF' +path = "cpp/third_party/aws.BUILD" +with open(path) as fh: + src = fh.read() + +changed = False + +# 1) Add ppc64le config_setting after the target_aarch64 block +OLD_AARCH64_CFG = ( + 'config_setting(\n' + ' name = "target_aarch64",\n' + ' constraint_values = [\n' + ' "@platforms//cpu:aarch64",\n' + ' ],\n' + ')' +) +PPC_CFG = ( + '\n\nconfig_setting(\n' + ' name = "target_ppc64le",\n' + ' constraint_values = [\n' + ' "@platforms//cpu:ppc",\n' + ' ],\n' + ')' +) +if "target_ppc64le" not in src: + if OLD_AARCH64_CFG in src: + src = src.replace(OLD_AARCH64_CFG, OLD_AARCH64_CFG + PPC_CFG) + changed = True + else: + print(" WARNING: could not find target_aarch64 config_setting in aws.BUILD — dumping:") + idx = src.find("target_aarch64") + print(repr(src[max(0,idx-20):idx+200]) if idx >= 0 else " (not found)") + +# 2) Add aws_ppc64le library declaration after aws_x86_64 +if 'aws_library(name = "aws_ppc64le"' not in src: + src = src.replace( + 'aws_library(name = "aws_x86_64", arch = "x86_64")', + 'aws_library(name = "aws_x86_64", arch = "x86_64")\n' + 'aws_library(name = "aws_ppc64le", arch = "ppc64le")' + ) + changed = True + +# 3) Add ppc64le entry in the alias select() block +# The diff shows the entry uses a tab before ":target_ppc64le" (mixed indent) +OLD_ALIAS_TAIL = ( + ' ":target_aarch64": ":aws_aarch",\n' + ' }),\n' + ')' +) +NEW_ALIAS_TAIL = ( + ' ":target_aarch64": ":aws_aarch",\n' + '\t":target_ppc64le": ":aws_ppc64le",\n' + ' }),\n' + ')' +) +if '":target_ppc64le"' not in src: + if OLD_ALIAS_TAIL in src: + src = src.replace(OLD_ALIAS_TAIL, NEW_ALIAS_TAIL) + changed = True + else: + print(" WARNING: could not find alias select block in aws.BUILD — dumping:") + idx = src.find("alias(") + print(repr(src[idx:idx+300]) if idx >= 0 else " (not found)") + +with open(path, "w") as fh: + fh.write(src) +print(" aws.BUILD patched OK" if changed else " aws.BUILD already patched — skipping") +PYEOF + +# ─── Step 7: Patch cpp/Makefile (drop gcs and azure build targets) ──────────── +# Uses TABS for recipe indentation. +info "Patching cpp/Makefile (build only streamer + s3, drop gcs/azure)" + +python3 - <<'PYEOF' +path = "cpp/Makefile" +with open(path) as fh: + src = fh.read() + +# Exact tab-indented upstream 4-target build: block +OLD_BUILD = ( + "build:\n" + "\tbazel build streamer:libstreamer.so \\\n" + '\t\t"--config=${ARCH}" && \\\n' + "\tbazel build s3:libstreamers3.so \\\n" + "\t\t--define USE_SYSTEM_LIBS=${USE_SYSTEM_LIBS} \\\n" + '\t\t"--config=${ARCH}" && \\\n' + "\tbazel build gcs:libstreamergcs.so \\\n" + "\t\t--define USE_SYSTEM_LIBS=${USE_SYSTEM_LIBS} \\\n" + '\t\t"--config=${ARCH}" && \\\n' + "\tbazel build azure:libstreamerazure.so \\\n" + "\t\t--define USE_SYSTEM_LIBS=${USE_SYSTEM_LIBS} \\\n" + '\t\t"--config=${ARCH}"' +) +NEW_BUILD = ( + "build:\n" + "\tbazel build streamer:libstreamer.so \\\n" + '\t\t"--config=${ARCH}" && \\\n' + "\tbazel build s3:libstreamers3.so \\\n" + "\t\t--define USE_SYSTEM_LIBS=${USE_SYSTEM_LIBS} \\\n" + '\t\t"--config=${ARCH}"' +) + +# Check for gcs target — only present in the unpatched file +if "libstreamergcs.so" not in src: + print(" cpp/Makefile already patched — skipping") +elif OLD_BUILD in src: + src = src.replace(OLD_BUILD, NEW_BUILD) + with open(path, "w") as fh: + fh.write(src) + print(" cpp/Makefile patched OK") +else: + print(" WARNING: could not find expected build: block in cpp/Makefile — dumping:") + idx = src.find("build:") + print(repr(src[idx:idx+500]) if idx >= 0 else " (not found)") +PYEOF + +# ─── Step 8: Patch py/Makefile (remove gcs and azure references) ────────────── +info "Patching py/Makefile (removing gcs and azure references)" + +python3 - <<'PYEOF' +path = "py/Makefile" +with open(path) as fh: + lines = fh.readlines() + +filtered = [ + line for line in lines + if "runai_model_streamer_gcs" not in line + and "runai_model_streamer_azure" not in line +] + +if len(filtered) != len(lines): + with open(path, "w") as fh: + fh.writelines(filtered) + removed = len(lines) - len(filtered) + print(f" py/Makefile patched OK (removed {removed} line(s))") +else: + print(" py/Makefile already patched — skipping") +PYEOF + +# ─── Step 9: Build aws-sdk-cpp (optional) ───────────────────────────────────── +if [[ "$SKIP_AWS_BUILD" -eq 0 ]]; then + info "Building aws-sdk-cpp (this may take a while)" + + AWS_SDK_DIR="$WORK_DIR/aws-sdk-cpp" + if [[ ! -d "$AWS_SDK_DIR" ]]; then + git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp "$AWS_SDK_DIR" + fi + + mkdir -p "$AWS_SDK_DIR/build" + cd "$AWS_SDK_DIR/build" + + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_ONLY="s3;core;s3-crt" \ + -DENABLE_TESTING=OFF \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + .. + + make -j"$(nproc)" + make install + ldconfig + + cd "$REPO_DIR" +else + info "Skipping aws-sdk-cpp build (--skip-aws-build)" +fi + +# ─── Step 10: Set up Python venv ────────────────────────────────────────────── +info "Setting up Python venv at $REPO_DIR/runai" +if [[ ! -d "$REPO_DIR/runai" ]]; then + python3.13 -m venv "$REPO_DIR/runai" +fi +# shellcheck disable=SC1091 +source "$REPO_DIR/runai/bin/activate" +pip install --upgrade pip setuptools + +# ─── Step 11: Patch the Bazel cache external/aws/BUILD.bazel ───────────────── +# cpp/third_party/aws.BUILD (patched above) is the *source* Bazel uses to +# materialise external/aws/BUILD.bazel in the cache. If the cache copy already +# exists from a previous fetch it also needs to be patched directly so that the +# current build session picks up the changes without a full bazel clean --expunge. +info "Patching Bazel cache external/aws/BUILD.bazel" + +cd "$REPO_DIR/cpp" + +BAZEL_OUTPUT_BASE="$(bazel info output_base 2>/dev/null)" \ + || die "Could not determine Bazel output base — is Bazel installed?" + +AWS_CACHE_BUILD="$BAZEL_OUTPUT_BASE/external/aws/BUILD.bazel" + +if [[ ! -f "$AWS_CACHE_BUILD" ]]; then + info "Fetching Bazel deps to materialise external/aws/BUILD.bazel ..." + bazel fetch //... --config=ppc64le 2>/dev/null || true + # The fetch may place it under a different hash-named subdir; search for it + AWS_CACHE_BUILD="$(find "$BAZEL_OUTPUT_BASE/external" \ + -name BUILD.bazel -path "*/aws/BUILD.bazel" 2>/dev/null | head -1 || true)" +fi + +if [[ -z "$AWS_CACHE_BUILD" || ! -f "$AWS_CACHE_BUILD" ]]; then + die "Could not locate external/aws/BUILD.bazel under $BAZEL_OUTPUT_BASE" +fi + +info "Found cache file: $AWS_CACHE_BUILD" + +python3 - "$AWS_CACHE_BUILD" <<'PYEOF' +import sys + +path = sys.argv[1] +with open(path) as fh: + src = fh.read() + +if "target_ppc64le" in src: + print(" Bazel cache BUILD.bazel already patched — skipping") + raise SystemExit(0) + +changed = False + +# 1) Add ppc64le config_setting after target_aarch64 block +OLD_AARCH64_CFG = ( + 'config_setting(\n' + ' name = "target_aarch64",\n' + ' constraint_values = [\n' + ' "@platforms//cpu:aarch64",\n' + ' ],\n' + ')' +) +PPC_CFG = ( + '\n\nconfig_setting(\n' + ' name = "target_ppc64le",\n' + ' constraint_values = [\n' + ' "@platforms//cpu:ppc",\n' + ' ],\n' + ')' +) +if OLD_AARCH64_CFG in src: + src = src.replace(OLD_AARCH64_CFG, OLD_AARCH64_CFG + PPC_CFG) + changed = True + +# 2) Add aws_ppc64le library declaration after aws_x86_64 +if 'aws_library(name = "aws_ppc64le"' not in src: + src = src.replace( + 'aws_library(name = "aws_x86_64", arch = "x86_64")', + 'aws_library(name = "aws_x86_64", arch = "x86_64")\n' + 'aws_library(name = "aws_ppc64le", arch = "ppc64le")' + ) + changed = True + +# 3) Add ppc64le entry in the alias select() block +OLD_ALIAS_TAIL = ( + ' ":target_aarch64": ":aws_aarch",\n' + ' }),\n' + ')' +) +NEW_ALIAS_TAIL = ( + ' ":target_aarch64": ":aws_aarch",\n' + '\t":target_ppc64le": ":aws_ppc64le",\n' + ' }),\n' + ')' +) +if OLD_ALIAS_TAIL in src: + src = src.replace(OLD_ALIAS_TAIL, NEW_ALIAS_TAIL) + changed = True + +with open(path, "w") as fh: + fh.write(src) +print(" Bazel cache BUILD.bazel patched OK" if changed else " No changes made") +PYEOF + +cd "$REPO_DIR" + +# ─── Step 12: Optional bazel clean ──────────────────────────────────────────── +if [[ "$BAZEL_CLEAN" -eq 1 ]]; then + info "Running bazel clean --expunge" + (cd "$REPO_DIR/cpp" && bazel clean --expunge) +fi + +# ─── Step 13: Build ─────────────────────────────────────────────────────────── +info "Building runai-model-streamer for ppc64le (version $PACKAGE_VERSION)" +export USE_SYSTEM_LIBS=1 +export PACKAGE_VERSION + +make build + +# ─── Step 14: Copy wheels to staging area and report ───────────────────────── +info "Build complete. Wheels:" +find "$REPO_DIR/py" -name "*.whl" | sort | while read -r whl; do + echo " $whl" +done + +mkdir -p "$OUTPUT_DIR" +find "$REPO_DIR/py" -name "*.whl" | while read -r whl; do + cp "$whl" "$OUTPUT_DIR/" +done +info "Runai wheels copied to $OUTPUT_DIR" + From 3d68aadc86eceb23bd3fee3c3106b11b2a95c1b5 Mon Sep 17 00:00:00 2001 From: Deepali Patel Date: Tue, 4 Aug 2026 08:09:49 +0000 Subject: [PATCH 2/4] add build script for runai-model-streamer --- .../runai-model-streamer_0.16.1_ubi_10.2.sh | 721 +++++------------- 1 file changed, 192 insertions(+), 529 deletions(-) diff --git a/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh b/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh index c0008d843d..911ee210af 100644 --- a/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh +++ b/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh @@ -1,10 +1,10 @@ -#!/bin/bash +#!/bin/bash -e # ----------------------------------------------------------------------------- # # Package : runai-model-streamer # Version : 0.16.1 # Source repo : https://github.com/run-ai/runai-model-streamer -# Tested on : UBI 10 (ppc64le) +# Tested on : UBI:10.2 # Language : Python, C++ # Ci-Check : True # Script License: Apache License, Version 2 or later @@ -16,209 +16,145 @@ # package and/or distribution. In such case, please # contact "Maintainer" of this script. # -# ---------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # -# Clones runai-model-streamer, applies all ppc64le patches, and builds the two -# wheel files: +# Builds the CORE wheel only: # runai_model_streamer--py3-none-manylinux2014_ppc64le.whl -# runai_model_streamer_s3--py3-none-manylinux2014_ppc64le.whl # -# Bazel is not available as a pre-built binary for ppc64le. This script -# bootstraps Bazel 7.6.1 from the official source distribution (dist.zip) -# using only the JDK and GCC Toolset 15. The resulting binary is installed -# to /usr/local/bin/bazel. Pass --skip-bazel-build if it is already present. +# This wheel contains libstreamer.so (the base streaming engine) and the full +# Python API (SafetensorsStreamer, FileStreamer, DistributedStreamer). +# It does NOT include S3 support — run the companion script +# runai-model-streamer_0.16.1_ubi_10.2_wheel2_s3.sh for the S3 wheel. # -# Usage: -# ./runai-model-streamer_0.16.1_ubi_10.2.sh [--version 0.16.1] [--workdir $HOME] -# [--output-dir $HOME/vllm-wheels] -# [--skip-bazel-build] -# [--skip-aws-build] [--bazel-clean] +# aws-sdk-cpp is NOT required for this wheel. # -set -Eeuo pipefail +# ----------------------------------------------------------------------------- -SCRIPT_NAME="$(basename "$0")" +set -e + +PACKAGE_NAME=runai-model-streamer +PACKAGE_VERSION=${1:-0.16.1} +PACKAGE_URL=https://github.com/run-ai/runai-model-streamer +PACKAGE_DIR=runai-model-streamer +CURRENT_DIR=$(pwd) -# ─── Defaults ───────────────────────────────────────────────────────────────── -PACKAGE_VERSION="0.16.1" BAZEL_VERSION="7.6.1" -WORK_DIR="${HOME}" -OUTPUT_DIR="" # resolved to ${WORK_DIR}/vllm-wheels after arg parsing -SKIP_BAZEL_BUILD=0 -SKIP_AWS_BUILD=0 -BAZEL_CLEAN=0 - -# ─── Helpers ────────────────────────────────────────────────────────────────── -die() { echo "ERROR: $*" >&2; exit 1; } -info() { echo "==> $*"; } - -usage() { - cat </vllm-wheels) - --skip-bazel-build skip Bazel bootstrap (requires bazel already on PATH) - --skip-aws-build skip cloning/building aws-sdk-cpp (if already installed) - --bazel-clean run 'bazel clean --expunge' before the main build - -h, --help show this help and exit -EOF -} - -# ─── Argument parsing ───────────────────────────────────────────────────────── -while [[ $# -gt 0 ]]; do - case "$1" in - --version) PACKAGE_VERSION="$2"; shift 2 ;; - --bazel-version) BAZEL_VERSION="$2"; shift 2 ;; - --workdir) WORK_DIR="$2"; shift 2 ;; - --output-dir) OUTPUT_DIR="$2"; shift 2 ;; - --skip-bazel-build) SKIP_BAZEL_BUILD=1; shift ;; - --skip-aws-build) SKIP_AWS_BUILD=1; shift ;; - --bazel-clean) BAZEL_CLEAN=1; shift ;; - -h|--help) usage; exit 0 ;; - *) die "Unknown option: $1" ;; - esac -done -# Resolve OUTPUT_DIR now that WORK_DIR is final -OUTPUT_DIR="${OUTPUT_DIR:-${WORK_DIR}/vllm-wheels}" - -# ─── System packages ────────────────────────────────────────────────────────── -info "Installing system dependencies" -dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm -dnf install -y \ - git \ - gcc-toolset-15 \ - gcc-c++ \ - cmake \ - ninja-build \ +# Install dependencies +yum install -y python3.12 python3.12-devel \ + git gcc gcc-c++ gcc-toolset-15 gcc-toolset-15-gcc gcc-toolset-15-gcc-c++ \ + cmake ninja-build \ java-21-openjdk-devel \ - libcurl-devel \ - openssl-devel \ - libuuid-devel \ - unzip \ - zip \ - patch \ - python3.13 \ - python3.13-devel - -REPO_DIR="$WORK_DIR/runai-model-streamer" - -# ─── Environment setup ──────────────────────────────────────────────────────── -info "Configuring environment" -export JAVA_HOME=/usr/lib/jvm/java-21-openjdk -export BAZEL_JAVAC_OPTS="-J-Xmx2g -J-Xms200m" -export PATH="$JAVA_HOME/bin:$PATH" -export PACKAGE_VERSION + libcurl-devel openssl-devel libuuid-devel \ + unzip zip patch -# Enable GCC Toolset 15. -# Some installations provide an 'enable' script; others only have the bin dir. -GCC_TOOLSET_BIN="/opt/rh/gcc-toolset-15/root/usr/bin" +# Configure GCC Toolset 15 if [[ -f /opt/rh/gcc-toolset-15/enable ]]; then - # shellcheck disable=SC1091 source /opt/rh/gcc-toolset-15/enable -elif [[ -d "$GCC_TOOLSET_BIN" ]]; then - export PATH="$GCC_TOOLSET_BIN:$PATH" +elif [[ -d /opt/rh/gcc-toolset-15/root/usr/bin ]]; then + export PATH="/opt/rh/gcc-toolset-15/root/usr/bin:$PATH" + export LD_LIBRARY_PATH="/opt/rh/gcc-toolset-15/root/usr/lib64:$LD_LIBRARY_PATH" else - die "/opt/rh/gcc-toolset-15 not found — install gcc-toolset-15" + echo "ERROR: gcc-toolset-15 not found" + exit 1 fi -# ─── Step 0: Bootstrap Bazel from source ────────────────────────────────────── +echo "Using gcc: $(gcc --version | head -1)" + +# Configure Java +export JAVA_HOME=/usr/lib/jvm/java-21-openjdk +export BAZEL_JAVAC_OPTS="-J-Xmx2g -J-Xms200m" +export PATH="$JAVA_HOME/bin:$PATH" +export PACKAGE_VERSION + +# Install Python build tools +pip install --upgrade pip setuptools wheel + +# Install Python runtime dependencies. +# torch and humanize are imported at module level in the core package. +# numpy and safetensors are needed for the test stage. +pip install torch humanize "numpy>=1.24.4" "safetensors>=0.5.3" + +# --------------------------------------------------------------------------- +# Step 0: Bootstrap Bazel from source # No pre-built Bazel binary exists for ppc64le. We bootstrap from the official # source distribution (dist.zip), which only requires a JDK and a C++ compiler. # The compiled binary is installed to /usr/local/bin/bazel. -if [[ "$SKIP_BAZEL_BUILD" -eq 1 ]]; then - command -v bazel &>/dev/null \ - || die "--skip-bazel-build set but bazel not found on PATH" - info "Skipping Bazel bootstrap — using $(command -v bazel) ($(bazel version 2>/dev/null | head -1))" -else - BAZEL_DIST_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-dist.zip" - BAZEL_DIST_ZIP="$WORK_DIR/bazel-${BAZEL_VERSION}-dist.zip" - BAZEL_BUILD_DIR="$WORK_DIR/bazel-${BAZEL_VERSION}-src" - - if [[ -x /usr/local/bin/bazel ]]; then - INSTALLED_VER="$(/usr/local/bin/bazel version 2>/dev/null | awk '/Build label/{print $NF}')" - if [[ "$INSTALLED_VER" == "$BAZEL_VERSION" ]]; then - info "Bazel $BAZEL_VERSION already installed at /usr/local/bin/bazel — skipping bootstrap" - SKIP_BAZEL_BUILD=1 - fi +# --------------------------------------------------------------------------- +SKIP_BAZEL_BUILD=0 + +if [[ -x /usr/local/bin/bazel ]]; then + INSTALLED_VER="$(/usr/local/bin/bazel version 2>/dev/null | awk '/Build label/{print $NF}')" + if [[ "$INSTALLED_VER" == "$BAZEL_VERSION" ]]; then + echo "==> Bazel $BAZEL_VERSION already installed at /usr/local/bin/bazel — skipping bootstrap" + SKIP_BAZEL_BUILD=1 fi +fi + +if [[ "$SKIP_BAZEL_BUILD" -eq 0 ]]; then + BAZEL_DIST_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-dist.zip" + BAZEL_DIST_ZIP="$CURRENT_DIR/bazel-${BAZEL_VERSION}-dist.zip" + BAZEL_BUILD_DIR="$CURRENT_DIR/bazel-${BAZEL_VERSION}-src" + + echo "==> Downloading Bazel $BAZEL_VERSION source distribution" + [[ -f "$BAZEL_DIST_ZIP" ]] \ + || curl -fL "$BAZEL_DIST_URL" -o "$BAZEL_DIST_ZIP" - if [[ "$SKIP_BAZEL_BUILD" -eq 0 ]]; then - info "Downloading Bazel $BAZEL_VERSION source distribution" - [[ -f "$BAZEL_DIST_ZIP" ]] \ - || curl -fL "$BAZEL_DIST_URL" -o "$BAZEL_DIST_ZIP" - - info "Extracting Bazel source distribution" - if [[ ! -d "$BAZEL_BUILD_DIR" ]]; then - mkdir -p "$BAZEL_BUILD_DIR" - unzip -q "$BAZEL_DIST_ZIP" -d "$BAZEL_BUILD_DIR" - fi - - info "Bootstrapping Bazel (this may take 10–20 minutes)" - cd "$BAZEL_BUILD_DIR" - # Bazel 7.6.1 sources are not compatible with GCC 15 (missing - # transitive includes). RHEL 10 ships GCC 14 as the system compiler - # (/usr/bin/gcc from gcc-c++), which builds Bazel cleanly. We - # temporarily shadow the toolset-15 gcc/g++ with the system versions - # just for this bootstrap, then restore PATH afterwards. - # - # EXTRA_BAZEL_ARGS is forwarded to the inner 'bazel build' call: - # --tool_java_runtime_version=local_jdk prevents the bootstrap from - # downloading a hermetic JDK; it uses the system JDK instead. - # --jobs=N caps parallel actions so the bootstrap does not exhaust - # the system thread limit (EAGAIN from pthread_create). Each - # parallel JVM action needs ~10 threads; 4 jobs keeps peak thread - # count well within default container limits. - # - # ulimit -u raises the per-user max processes/threads ceiling for this - # shell; the kernel default in many container runtimes is low (1024). - ulimit -u unlimited 2>/dev/null || ulimit -u 65536 2>/dev/null || true - SAVED_PATH="$PATH" - export PATH="/usr/bin:/usr/sbin:${PATH}" - export CC=/usr/bin/gcc - export CXX=/usr/bin/g++ - export EXTRA_BAZEL_ARGS="--tool_java_runtime_version=local_jdk --jobs=4" - bash compile.sh - export PATH="$SAVED_PATH" - unset CC CXX - - install -m 0755 output/bazel /usr/local/bin/bazel - info "Bazel installed: $(bazel version 2>/dev/null | head -1)" - cd "$WORK_DIR" + echo "==> Extracting Bazel source distribution" + if [[ ! -d "$BAZEL_BUILD_DIR" ]]; then + mkdir -p "$BAZEL_BUILD_DIR" + unzip -q "$BAZEL_DIST_ZIP" -d "$BAZEL_BUILD_DIR" fi + + echo "==> Bootstrapping Bazel (this may take 10-20 minutes)" + cd "$BAZEL_BUILD_DIR" + # Bazel 7.6.1 sources are not compatible with GCC 15 (missing + # transitive includes). The system gcc/g++ installed above (gcc + gcc-c++) + # builds Bazel cleanly. We temporarily shadow the toolset-15 gcc/g++ with + # the system versions just for this bootstrap, then restore PATH afterwards. + ulimit -u unlimited 2>/dev/null || ulimit -u 65536 2>/dev/null || true + SAVED_PATH="$PATH" + export PATH="/usr/bin:/usr/sbin:${PATH}" + export CC=/usr/bin/gcc + export CXX=/usr/bin/g++ + export EXTRA_BAZEL_ARGS="--tool_java_runtime_version=local_jdk --jobs=4" + bash compile.sh + export PATH="$SAVED_PATH" + unset CC CXX + + install -m 0755 output/bazel /usr/local/bin/bazel + echo "==> Bazel installed: $(bazel version 2>/dev/null | head -1)" + cd "$CURRENT_DIR" fi -# ─── Step 1: Clone the repository and checkout the requested version ────────── -info "Cloning runai-model-streamer into $REPO_DIR" -if [[ -d "$REPO_DIR" ]]; then - info "Directory already exists — skipping clone" -else - git clone https://github.com/run-ai/runai-model-streamer "$REPO_DIR" +# --------------------------------------------------------------------------- +# Step 1: Clone the repository and checkout the requested version +# --------------------------------------------------------------------------- +echo "==> Cloning runai-model-streamer" +if [[ ! -d "$CURRENT_DIR/$PACKAGE_DIR" ]]; then + git clone $PACKAGE_URL $CURRENT_DIR/$PACKAGE_DIR fi -cd "$REPO_DIR" +cd "$CURRENT_DIR/$PACKAGE_DIR" -# Checkout the tag that matches PACKAGE_VERSION. -# The repo uses tags like "v0.15.7"; fall back to bare "0.15.7" if not found. -info "Checking out version $PACKAGE_VERSION" +echo "==> Checking out version $PACKAGE_VERSION" if git rev-parse "v${PACKAGE_VERSION}" &>/dev/null; then git checkout "v${PACKAGE_VERSION}" elif git rev-parse "${PACKAGE_VERSION}" &>/dev/null; then git checkout "${PACKAGE_VERSION}" else - die "No git tag found for version '$PACKAGE_VERSION' (tried v${PACKAGE_VERSION} and ${PACKAGE_VERSION})" + echo "ERROR: No git tag found for version '$PACKAGE_VERSION' (tried v${PACKAGE_VERSION} and ${PACKAGE_VERSION})" + exit 1 fi -info "HEAD commit: $(git log --oneline -1)" +echo "==> HEAD commit: $(git log --oneline -1)" -# ─── Step 2: Patch top-level Makefile ───────────────────────────────────────── +# --------------------------------------------------------------------------- +# Step 2: Patch top-level Makefile # The upstream Makefile uses TABS for recipe indentation. # "build:" has a trailing space: "build: " -info "Patching Makefile (ppc64le arch + build target)" +# --------------------------------------------------------------------------- +echo "==> Patching Makefile (ppc64le arch + build target)" python3 - <<'PYEOF' path = "Makefile" @@ -227,7 +163,6 @@ with open(path) as fh: changed = False -# 1) Insert PPC64LE_ARCH variable after AARCH64_ARCH line if "PPC64LE_ARCH" not in src: src = src.replace( "AARCH64_ARCH := aarch64", @@ -235,7 +170,6 @@ if "PPC64LE_ARCH" not in src: ) changed = True -# 2) Insert build_ppc64le target after build_aarch64 block (tab-indented) OLD_AARCH64 = ( "build_aarch64:\n" "\tmake -C cpp build ARCH=${AARCH64_ARCH} && \\\n" @@ -259,7 +193,6 @@ if "build_ppc64le:" not in src: idx = src.find("build_aarch64") print(repr(src[idx:idx+200]) if idx >= 0 else " (not found)") -# 3) Replace the build: recipe — note the trailing space after "build:" OLD_BUILD = ( "build: \n" "\tmake -C py clean && \\\n" @@ -285,8 +218,10 @@ with open(path, "w") as fh: print(" Makefile patched OK" if changed else " Makefile already fully patched — skipping") PYEOF -# ─── Step 3: Patch cpp/.bazelrc ─────────────────────────────────────────────── -info "Patching cpp/.bazelrc (ppc64le platform suffix)" +# --------------------------------------------------------------------------- +# Step 3: Patch cpp/.bazelrc (ppc64le platform suffix) +# --------------------------------------------------------------------------- +echo "==> Patching cpp/.bazelrc (ppc64le platform suffix)" python3 - <<'PYEOF' path = "cpp/.bazelrc" @@ -302,9 +237,11 @@ else: print(" cpp/.bazelrc already patched — skipping") PYEOF -# ─── Step 4: Patch cpp/cc/freeres/freeres.cc ────────────────────────────────── +# --------------------------------------------------------------------------- +# Step 4: Patch cpp/cc/freeres/freeres.cc # Removes the hidden visibility attribute that causes link errors on ppc64le. -info "Patching cpp/cc/freeres/freeres.cc (__freeres visibility)" +# --------------------------------------------------------------------------- +echo "==> Patching cpp/cc/freeres/freeres.cc (__freeres visibility)" python3 - <<'PYEOF' path = "cpp/cc/freeres/freeres.cc" @@ -322,213 +259,16 @@ else: print(" freeres.cc already patched — skipping") PYEOF -# ─── Step 5: Patch cpp/third_party/aws.bzl ──────────────────────────────────── -# Replaces the original static-only linkopts with a dynamic/static select() -# block that also adds the /usr/local/lib64 search path for the system-installed -# aws-sdk-cpp. Uses exact literal replacement against the known upstream content. -info "Patching cpp/third_party/aws.bzl (linkopts)" - -python3 - <<'PYEOF' -path = "cpp/third_party/aws.bzl" -with open(path) as fh: - src = fh.read() - -if '"-L/usr/local/lib64"' in src: - print(" aws.bzl already patched — skipping") - raise SystemExit(0) - -# Exact upstream linkopts block (no -L lines, simple static list + small select) -OLD_LINKOPTS = ( - " linkopts = [\n" - ' "-lpthread",\n' - ' "-l:libaws-cpp-sdk-s3-crt.a",\n' - ' "-l:libaws-cpp-sdk-core.a",\n' - ' "-l:libaws-crt-cpp.a",\n' - ' "-l:libaws-c-mqtt.a",\n' - ' "-l:libaws-c-event-stream.a",\n' - ' "-l:libaws-c-s3.a",\n' - ' "-l:libaws-c-auth.a",\n' - ' "-l:libaws-c-http.a",\n' - ' "-l:libaws-c-io.a",\n' - ' "-l:libs2n.a",\n' - ' "-l:libaws-c-compression.a",\n' - ' "-l:libaws-c-cal.a",\n' - ' "-l:libaws-c-sdkutils.a",\n' - ' "-l:libaws-checksums.a",\n' - ' "-l:libaws-c-common.a",\n' - ' "-ldl -lm -lrt",\n' - ' "-L/opt/%s-curl/lib" % arch,\n' - ' "-L/opt/%s-ssl/lib" % arch,\n' - ' "-L/opt/%s-zlib/lib" % arch,\n' - ' "-L/opt/%s-aws/lib" % arch,\n' - " ] + select({\n" - ' "//:dynamic_link": ["-lz", "-lssl", "-lcrypto", "-lcurl"],\n' - ' "//conditions:default": [\n' - ' "-l:libz.a",\n' - ' "-l:libcurl.a",\n' - ' "-l:libssl.a",\n' - ' "-l:libcrypto.a",\n' - " ],\n" - " })," -) -NEW_LINKOPTS = ( - " linkopts = [\n" - ' "-lpthread",\n' - ' "-L/usr/local/lib64",\n' - ' "-L/opt/%s-curl/lib" % arch,\n' - ' "-L/opt/%s-ssl/lib" % arch,\n' - ' "-L/opt/%s-zlib/lib" % arch,\n' - ' "-L/opt/%s-aws/lib" % arch,\n' - ' "-Wl,-rpath,/usr/local/lib64",\n' - " ] + select({\n" - ' "//:dynamic_link": [\n' - ' # Dynamic linking for all libraries\n' - ' "-laws-cpp-sdk-s3-crt",\n' - ' "-laws-cpp-sdk-core",\n' - ' "-laws-crt-cpp",\n' - ' "-laws-c-mqtt",\n' - ' "-laws-c-event-stream",\n' - ' "-laws-c-s3",\n' - ' "-laws-c-auth",\n' - ' "-laws-c-http",\n' - ' "-laws-c-io",\n' - ' "-ls2n",\n' - ' "-laws-c-compression",\n' - ' "-laws-c-cal",\n' - ' "-laws-c-sdkutils",\n' - ' "-laws-checksums",\n' - ' "-laws-c-common",\n' - ' "-lz",\n' - ' "-lssl",\n' - ' "-lcrypto",\n' - ' "-lcurl",\n' - ' "-ldl",\n' - ' "-lm",\n' - ' "-lrt",\n' - ' ],\n' - ' "//conditions:default": [\n' - ' # Static linking (original)\n' - ' "-l:libaws-cpp-sdk-s3-crt.a",\n' - ' "-l:libaws-cpp-sdk-core.a",\n' - ' "-l:libaws-crt-cpp.a",\n' - ' "-l:libaws-c-mqtt.a",\n' - ' "-l:libaws-c-event-stream.a",\n' - ' "-l:libaws-c-s3.a",\n' - ' "-l:libaws-c-auth.a",\n' - ' "-l:libaws-c-http.a",\n' - ' "-l:libaws-c-io.a",\n' - ' "-l:libs2n.a",\n' - ' "-l:libaws-c-compression.a",\n' - ' "-l:libaws-c-cal.a",\n' - ' "-l:libaws-c-sdkutils.a",\n' - ' "-l:libaws-checksums.a",\n' - ' "-l:libaws-c-common.a",\n' - ' "-l:libz.a",\n' - ' "-l:libcurl.a",\n' - ' "-l:libssl.a",\n' - ' "-l:libcrypto.a",\n' - ' "-ldl",\n' - ' "-lm",\n' - ' "-lrt",\n' - ' ],\n' - " })," -) - -if OLD_LINKOPTS in src: - src = src.replace(OLD_LINKOPTS, NEW_LINKOPTS) - with open(path, "w") as fh: - fh.write(src) - print(" aws.bzl patched OK") -else: - print(" WARNING: could not find expected linkopts block in aws.bzl — dumping:") - idx = src.find("linkopts") - print(repr(src[idx:idx+400]) if idx >= 0 else " (not found)") -PYEOF - -# ─── Step 6: Patch cpp/third_party/aws.BUILD (in-repo Bazel external file) ──── -# This file is the template Bazel uses to populate the external/aws/ package. -# It needs the ppc64le config_setting, library declaration, and alias entry. -info "Patching cpp/third_party/aws.BUILD (ppc64le config + alias)" - -python3 - <<'PYEOF' -path = "cpp/third_party/aws.BUILD" -with open(path) as fh: - src = fh.read() - -changed = False - -# 1) Add ppc64le config_setting after the target_aarch64 block -OLD_AARCH64_CFG = ( - 'config_setting(\n' - ' name = "target_aarch64",\n' - ' constraint_values = [\n' - ' "@platforms//cpu:aarch64",\n' - ' ],\n' - ')' -) -PPC_CFG = ( - '\n\nconfig_setting(\n' - ' name = "target_ppc64le",\n' - ' constraint_values = [\n' - ' "@platforms//cpu:ppc",\n' - ' ],\n' - ')' -) -if "target_ppc64le" not in src: - if OLD_AARCH64_CFG in src: - src = src.replace(OLD_AARCH64_CFG, OLD_AARCH64_CFG + PPC_CFG) - changed = True - else: - print(" WARNING: could not find target_aarch64 config_setting in aws.BUILD — dumping:") - idx = src.find("target_aarch64") - print(repr(src[max(0,idx-20):idx+200]) if idx >= 0 else " (not found)") - -# 2) Add aws_ppc64le library declaration after aws_x86_64 -if 'aws_library(name = "aws_ppc64le"' not in src: - src = src.replace( - 'aws_library(name = "aws_x86_64", arch = "x86_64")', - 'aws_library(name = "aws_x86_64", arch = "x86_64")\n' - 'aws_library(name = "aws_ppc64le", arch = "ppc64le")' - ) - changed = True - -# 3) Add ppc64le entry in the alias select() block -# The diff shows the entry uses a tab before ":target_ppc64le" (mixed indent) -OLD_ALIAS_TAIL = ( - ' ":target_aarch64": ":aws_aarch",\n' - ' }),\n' - ')' -) -NEW_ALIAS_TAIL = ( - ' ":target_aarch64": ":aws_aarch",\n' - '\t":target_ppc64le": ":aws_ppc64le",\n' - ' }),\n' - ')' -) -if '":target_ppc64le"' not in src: - if OLD_ALIAS_TAIL in src: - src = src.replace(OLD_ALIAS_TAIL, NEW_ALIAS_TAIL) - changed = True - else: - print(" WARNING: could not find alias select block in aws.BUILD — dumping:") - idx = src.find("alias(") - print(repr(src[idx:idx+300]) if idx >= 0 else " (not found)") - -with open(path, "w") as fh: - fh.write(src) -print(" aws.BUILD patched OK" if changed else " aws.BUILD already patched — skipping") -PYEOF - -# ─── Step 7: Patch cpp/Makefile (drop gcs and azure build targets) ──────────── -# Uses TABS for recipe indentation. -info "Patching cpp/Makefile (build only streamer + s3, drop gcs/azure)" +# --------------------------------------------------------------------------- +# Step 5: Patch cpp/Makefile — build streamer only (drop s3, gcs, azure) +# --------------------------------------------------------------------------- +echo "==> Patching cpp/Makefile (streamer target only)" python3 - <<'PYEOF' path = "cpp/Makefile" with open(path) as fh: src = fh.read() -# Exact tab-indented upstream 4-target build: block OLD_BUILD = ( "build:\n" "\tbazel build streamer:libstreamer.so \\\n" @@ -543,16 +283,13 @@ OLD_BUILD = ( "\t\t--define USE_SYSTEM_LIBS=${USE_SYSTEM_LIBS} \\\n" '\t\t"--config=${ARCH}"' ) +# Core wheel needs libstreamer.so only NEW_BUILD = ( "build:\n" "\tbazel build streamer:libstreamer.so \\\n" - '\t\t"--config=${ARCH}" && \\\n' - "\tbazel build s3:libstreamers3.so \\\n" - "\t\t--define USE_SYSTEM_LIBS=${USE_SYSTEM_LIBS} \\\n" '\t\t"--config=${ARCH}"' ) -# Check for gcs target — only present in the unpatched file if "libstreamergcs.so" not in src: print(" cpp/Makefile already patched — skipping") elif OLD_BUILD in src: @@ -566,8 +303,10 @@ else: print(repr(src[idx:idx+500]) if idx >= 0 else " (not found)") PYEOF -# ─── Step 8: Patch py/Makefile (remove gcs and azure references) ────────────── -info "Patching py/Makefile (removing gcs and azure references)" +# --------------------------------------------------------------------------- +# Step 6: Patch py/Makefile — build only the base wheel (drop gcs, azure, s3) +# --------------------------------------------------------------------------- +echo "==> Patching py/Makefile (base wheel only)" python3 - <<'PYEOF' path = "py/Makefile" @@ -578,6 +317,7 @@ filtered = [ line for line in lines if "runai_model_streamer_gcs" not in line and "runai_model_streamer_azure" not in line + and "runai_model_streamer_s3" not in line ] if len(filtered) != len(lines): @@ -589,159 +329,82 @@ else: print(" py/Makefile already patched — skipping") PYEOF -# ─── Step 9: Build aws-sdk-cpp (optional) ───────────────────────────────────── -if [[ "$SKIP_AWS_BUILD" -eq 0 ]]; then - info "Building aws-sdk-cpp (this may take a while)" - - AWS_SDK_DIR="$WORK_DIR/aws-sdk-cpp" - if [[ ! -d "$AWS_SDK_DIR" ]]; then - git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp "$AWS_SDK_DIR" - fi - - mkdir -p "$AWS_SDK_DIR/build" - cd "$AWS_SDK_DIR/build" - - cmake \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_ONLY="s3;core;s3-crt" \ - -DENABLE_TESTING=OFF \ - -DCMAKE_INSTALL_PREFIX=/usr/local \ - .. - - make -j"$(nproc)" - make install - ldconfig - - cd "$REPO_DIR" -else - info "Skipping aws-sdk-cpp build (--skip-aws-build)" -fi +# --------------------------------------------------------------------------- +# Step 7: Build +# --------------------------------------------------------------------------- +echo "==> Building runai-model-streamer core wheel for ppc64le (version $PACKAGE_VERSION)" +export USE_SYSTEM_LIBS=1 -# ─── Step 10: Set up Python venv ────────────────────────────────────────────── -info "Setting up Python venv at $REPO_DIR/runai" -if [[ ! -d "$REPO_DIR/runai" ]]; then - python3.13 -m venv "$REPO_DIR/runai" -fi -# shellcheck disable=SC1091 -source "$REPO_DIR/runai/bin/activate" -pip install --upgrade pip setuptools - -# ─── Step 11: Patch the Bazel cache external/aws/BUILD.bazel ───────────────── -# cpp/third_party/aws.BUILD (patched above) is the *source* Bazel uses to -# materialise external/aws/BUILD.bazel in the cache. If the cache copy already -# exists from a previous fetch it also needs to be patched directly so that the -# current build session picks up the changes without a full bazel clean --expunge. -info "Patching Bazel cache external/aws/BUILD.bazel" - -cd "$REPO_DIR/cpp" - -BAZEL_OUTPUT_BASE="$(bazel info output_base 2>/dev/null)" \ - || die "Could not determine Bazel output base — is Bazel installed?" - -AWS_CACHE_BUILD="$BAZEL_OUTPUT_BASE/external/aws/BUILD.bazel" - -if [[ ! -f "$AWS_CACHE_BUILD" ]]; then - info "Fetching Bazel deps to materialise external/aws/BUILD.bazel ..." - bazel fetch //... --config=ppc64le 2>/dev/null || true - # The fetch may place it under a different hash-named subdir; search for it - AWS_CACHE_BUILD="$(find "$BAZEL_OUTPUT_BASE/external" \ - -name BUILD.bazel -path "*/aws/BUILD.bazel" 2>/dev/null | head -1 || true)" +if ! make build ; then + echo "------------------$PACKAGE_NAME:Install_fails-------------------------------------" + echo "$PACKAGE_URL $PACKAGE_NAME" + echo "$PACKAGE_NAME | $PACKAGE_URL | $PACKAGE_VERSION | GitHub | Fail | Install_Fails" + exit 1 fi -if [[ -z "$AWS_CACHE_BUILD" || ! -f "$AWS_CACHE_BUILD" ]]; then - die "Could not locate external/aws/BUILD.bazel under $BAZEL_OUTPUT_BASE" -fi +# Copy wheel to CURRENT_DIR and install it +find "$CURRENT_DIR/$PACKAGE_DIR/py" -name "runai_model_streamer-*.whl" | while read -r whl; do + cp "$whl" "$CURRENT_DIR/" +done -info "Found cache file: $AWS_CACHE_BUILD" +pip install "$CURRENT_DIR"/runai_model_streamer-"${PACKAGE_VERSION}"-*.whl -python3 - "$AWS_CACHE_BUILD" <<'PYEOF' +# Run tests +if ! python3.12 - <<'PYEOF' import sys - -path = sys.argv[1] -with open(path) as fh: - src = fh.read() - -if "target_ppc64le" in src: - print(" Bazel cache BUILD.bazel already patched — skipping") - raise SystemExit(0) - -changed = False - -# 1) Add ppc64le config_setting after target_aarch64 block -OLD_AARCH64_CFG = ( - 'config_setting(\n' - ' name = "target_aarch64",\n' - ' constraint_values = [\n' - ' "@platforms//cpu:aarch64",\n' - ' ],\n' - ')' -) -PPC_CFG = ( - '\n\nconfig_setting(\n' - ' name = "target_ppc64le",\n' - ' constraint_values = [\n' - ' "@platforms//cpu:ppc",\n' - ' ],\n' - ')' -) -if OLD_AARCH64_CFG in src: - src = src.replace(OLD_AARCH64_CFG, OLD_AARCH64_CFG + PPC_CFG) - changed = True - -# 2) Add aws_ppc64le library declaration after aws_x86_64 -if 'aws_library(name = "aws_ppc64le"' not in src: - src = src.replace( - 'aws_library(name = "aws_x86_64", arch = "x86_64")', - 'aws_library(name = "aws_x86_64", arch = "x86_64")\n' - 'aws_library(name = "aws_ppc64le", arch = "ppc64le")' - ) - changed = True - -# 3) Add ppc64le entry in the alias select() block -OLD_ALIAS_TAIL = ( - ' ":target_aarch64": ":aws_aarch",\n' - ' }),\n' - ')' +print(f"Python: {sys.version}") + +# 1. Core package import — loads libstreamer.so via ctypes on import +print("\n[1] Importing runai_model_streamer...") +from runai_model_streamer import ( + SafetensorsStreamer, + FileStreamer, + DistributedStreamer, + FileChunks, + list_safetensors, + pull_files, ) -NEW_ALIAS_TAIL = ( - ' ":target_aarch64": ":aws_aarch",\n' - '\t":target_ppc64le": ":aws_ppc64le",\n' - ' }),\n' - ')' -) -if OLD_ALIAS_TAIL in src: - src = src.replace(OLD_ALIAS_TAIL, NEW_ALIAS_TAIL) - changed = True - -with open(path, "w") as fh: - fh.write(src) -print(" Bazel cache BUILD.bazel patched OK" if changed else " No changes made") +print(f" SafetensorsStreamer : OK") +print(f" FileStreamer : OK") +print(f" DistributedStreamer : OK") + +# 2. Runtime dep: torch +print("\n[2] Checking torch...") +import torch +print(f" torch version : {torch.__version__}") + +# 3. Runtime dep: humanize +print("\n[3] Checking humanize...") +import humanize +print(f" humanize version : {humanize.__version__}") + +# 4. Runtime dep: numpy +print("\n[4] Checking numpy...") +import numpy as np +print(f" numpy version : {np.__version__}") + +# 5. Runtime dep: safetensors +print("\n[5] Checking safetensors...") +import safetensors +print(f" safetensors version : {safetensors.__version__}") + +# 6. Verify libstreamer.so is loadable +print("\n[6] Verifying libstreamer.so loads via ctypes...") +from runai_model_streamer.libstreamer import dll +print(f" libstreamer.so : loaded OK") + +print("\n══════════════════════════════════════════════════════") +print(" All checks passed — runai-model-streamer core OK") +print("══════════════════════════════════════════════════════") PYEOF - -cd "$REPO_DIR" - -# ─── Step 12: Optional bazel clean ──────────────────────────────────────────── -if [[ "$BAZEL_CLEAN" -eq 1 ]]; then - info "Running bazel clean --expunge" - (cd "$REPO_DIR/cpp" && bazel clean --expunge) +then + echo "------------------$PACKAGE_NAME:Install_success_but_test_fails---------------------" + echo "$PACKAGE_URL $PACKAGE_NAME" + echo "$PACKAGE_NAME | $PACKAGE_URL | $PACKAGE_VERSION | GitHub | Fail | Install_success_but_test_Fails" + exit 2 +else + echo "------------------$PACKAGE_NAME:Install_&_test_both_success-------------------------" + echo "$PACKAGE_URL $PACKAGE_NAME" + echo "$PACKAGE_NAME | $PACKAGE_URL | $PACKAGE_VERSION | GitHub | Pass | Both_Install_and_Test_Success" + exit 0 fi - -# ─── Step 13: Build ─────────────────────────────────────────────────────────── -info "Building runai-model-streamer for ppc64le (version $PACKAGE_VERSION)" -export USE_SYSTEM_LIBS=1 -export PACKAGE_VERSION - -make build - -# ─── Step 14: Copy wheels to staging area and report ───────────────────────── -info "Build complete. Wheels:" -find "$REPO_DIR/py" -name "*.whl" | sort | while read -r whl; do - echo " $whl" -done - -mkdir -p "$OUTPUT_DIR" -find "$REPO_DIR/py" -name "*.whl" | while read -r whl; do - cp "$whl" "$OUTPUT_DIR/" -done -info "Runai wheels copied to $OUTPUT_DIR" - From c8534cbc889cb8bca9a4e71cbc7fac6785e4a776 Mon Sep 17 00:00:00 2001 From: Deepali Patel Date: Tue, 4 Aug 2026 08:34:10 +0000 Subject: [PATCH 3/4] install torch from devpi --- .../runai-model-streamer_0.16.1_ubi_10.2.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh b/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh index 911ee210af..31818176ae 100644 --- a/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh +++ b/r/runai-model-streamer/runai-model-streamer_0.16.1_ubi_10.2.sh @@ -73,7 +73,12 @@ pip install --upgrade pip setuptools wheel # Install Python runtime dependencies. # torch and humanize are imported at module level in the core package. # numpy and safetensors are needed for the test stage. -pip install torch humanize "numpy>=1.24.4" "safetensors>=0.5.3" +# torch has no ppc64le wheel on PyPI — install from the IBM wheels index. +IBM_WHEELS="https://wheels.developerfirst.ibm.com/ppc64le/linux/+simple/" +pip install --trusted-host wheels.developerfirst.ibm.com \ + --extra-index-url "${IBM_WHEELS}" --prefer-binary \ + torch +pip install humanize "numpy>=1.24.4" "safetensors>=0.5.3" # --------------------------------------------------------------------------- # Step 0: Bootstrap Bazel from source From eaabe6677d042aa690d2d6550fe9cc6f0eff48bb Mon Sep 17 00:00:00 2001 From: Deepali Patel Date: Tue, 4 Aug 2026 11:13:54 +0000 Subject: [PATCH 4/4] update build info --- r/runai-model-streamer/build_info.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/r/runai-model-streamer/build_info.json b/r/runai-model-streamer/build_info.json index 4b987c83c5..3e97c24272 100644 --- a/r/runai-model-streamer/build_info.json +++ b/r/runai-model-streamer/build_info.json @@ -4,20 +4,13 @@ "github_url":"https://github.com/run-ai/runai-model-streamer", "version": "0.16.1", "default_branch": "master", - "category": "default", "package_dir": "r/runai-model-streamer", - "docker_cmd":"NA", "build_script": "runai-model-streamer_0.16.1_ubi_10.2.sh", "docker_build": "false", "validate_build_script": "true", "use_non_root_user": "false", "wheel_build": "true", - "wheel_name": "runai-model-streamer", - - "required_versions": { - "Releases": "[0.16.1]", - "Tags": "[0.16.1]" - }, + "required_versions": {"Releases": "[*]","Tags": "[0.16.1]"}, "*": { "build_script":"runai-model-streamer_0.16.1_ubi_10.2.sh" }