ادغام مداوم AMD ROCm

این سند، پیاده‌سازی یکپارچه‌سازی مداوم (CI) AMD ROCm را شرح می‌دهد. این سند، گردش کار GitHub Actions، runner pool، کانتینرهای Docker، پیکربندی‌های Bazel، فیلترهای برچسب، قفل‌گذاری GPU و رابطه upstream-fork با ROCm/xla را پوشش می‌دهد.

این تنظیمات شامل دو مسیر مجزا است:

  1. گردش کار ROCm CI ( .github/workflows/rocm_ci.yml ): تست‌های فیزیکی XLA و JAX را روی یک اجراکننده پردازنده گرافیکی AMD Instinct که به صورت خودکار میزبانی می‌شود، اجرا می‌کند.
  2. ROCm CI فقط-کامپایل ( .github/workflows/ci.yml ‎): XLA را در برابر یک زنجیره ابزار ROCm غیرقابل نفوذ روی یک اجراکننده عمومی لینوکس x86 بدون پردازنده گرافیکی (GPU) می‌سازد.

این مسیرها هم تأیید زمان اجرا روی سخت‌افزار و هم قابلیت اطمینان کامپایل در هر کامیت را تضمین می‌کنند.

تریگر و همزمانی

rocm_ci.yml روی موارد زیر اجرا می‌شود:

  • pull_request در برابر main (کار jax علاوه بر این به github.base_ref == 'main' نیز محدود شده است).
  • workflow_dispatch (دستی).

مسیر ROCm فقط-کامپایل درون ci.yml در همان رویدادهای pull_request که بقیه ماتریس CI و در زمان ارسال اجرا می‌شوند، اجرا می‌شود.

هر دو گردش کار یک گروه همزمانی مشترک دارند که توسط گردش کار + مرجع سر کلیدگذاری شده است، بنابراین یک فشار جدید به یک PR هرگونه اجرای در حال انجام روی آن PR را لغو می‌کند اما اجراها را روی main لغو نمی‌کند:

concurrency:
  group: ${ { github.workflow } }-${ { github.head_ref || github.ref } }
  cancel-in-progress: ${ { github.ref != 'main' } }

مجوزها به contents: read . هیچ محدوده نوشتن یا آپلود مصنوعات فعال نیست.

پیکربندی دونده و کانتینر

استخر دونده

کارهای ROCm از یک اجراکننده‌ی GitHub Actions خود-میزبان با برچسب linux-x86-64-1gpu-amd استفاده می‌کنند. این یک میزبان لینوکس x86_64 با یک پردازنده‌ی گرافیکی AMD Instinct متصل است که در حال حاضر gfx950 را هدف قرار می‌دهد. این برچسب به ناوگان اجراکننده‌ی RBE متعلق به AMD، جایی که ساخت و آزمایش‌ها اجرا می‌شوند، پیوند دارد. وضعیت این خوشه را می‌توان در این داشبورد نظارت کرد.

تصویر داکر

این وظایف در یک کانتینر داکر اجرا می‌شوند. ایمیج داکر توسط AMD ارائه شده و از ایمیج‌های رسمی ساخت Tensorflow گرفته شده است.

نکات کلیدی:

  • --device=/dev/kfd و --device=/dev/dri درایور فیوژن هسته پردازنده گرافیکی AMD و گره‌های رندر DRI را در اختیار کانتینر قرار می‌دهند. بدون این موارد، کانتینر نمی‌تواند پردازنده گرافیکی (GPU) را ببیند.
  • --group-add video کاربر کانتینر را در گروه video قرار می‌دهد، که قراردادی در اوبونتو برای کاربرانی است که ممکن است به گره‌های دستگاه GPU دسترسی داشته باشند.
  • --ipc=host و --shm-size=64G مورد نیاز هستند زیرا مجموعه‌های HIP/ROCm (RCCL) و چندین مسیر اجراکننده جریان از حافظه مشترک برای ارتباط بین فرآیندی در یک گره واحد استفاده می‌کنند.
  • --cap-add=SYS_PTRACE و --security-opt=seccomp=unconfined به فایل‌های آزمایشیِ ابزارِ sanitizer اجازه می‌دهند تا اشکال‌زداها را ضمیمه کرده و فیلترهای seccomp را که فراخوانی‌های زمان اجرای sanitizer را مسدود می‌کنند، دور بزنند.
  • --tmpfs /root/.cache/bazel:rw,exec,size=80g ‎ حافظه پنهان دیسک Bazel را در RAM قرار می‌دهد. exec اجباری است زیرا Bazel فایل‌های باینری bazel-out را مستقیماً از حافظه پنهان اجرا می‌کند.
  • دو فایل ci-cert.* که در from /data روی میزبان نصب شده‌اند، گواهی TLS کلاینت و کلید خصوصی مورد استفاده برای احراز هویت در خوشه ساخت از راه دور EngFlow هستند.

توپولوژی کار

rocm_ci.yml سه کار تعریف می‌کند:

شغل هدف بستگی دارد
rocm-config خلاصه تصویر داکر پین‌شده را منتشر کنید.
jax JAX را در برابر تغییرات XLA، روی یک پردازنده گرافیکی AMD واحد، بسازید و آزمایش کنید. rocm-config
xla خود XLA را روی یک پردازنده گرافیکی AMD و یک مجموعه XLA فقط برای CPU بسازید و آزمایش کنید. rocm-config

jax و xla به محض اتمام rocm-config به صورت موازی اجرا می‌شوند.

کار xla در github.base_ref == 'main' محدود نشده است؛ کار jax شده است. این بدان معناست که مجموعه JAX فقط برای PRهایی که هدفشان main است اجرا می‌شود، در حالی که مجموعه XLA برای هر PR به علاوه workflow_dispatch اجرا می‌شود.

timeout-minutes در سطح job تنظیم می‌شود، با یک timeout-minutes: 60 (XLA single-GPU، JAX) یا ۸۰ (XLA CPU suite) در هر مرحله تست.

شغل XLA CI

توالی مراحل

  1. به سربرگ روابط عمومی openxla/xla را بررسی کنید.
  2. اسکریپت درایور تحت مدیریت AMD ( execute_ci_build_upstream.sh ) را از شاخه ROCm/xla دانلود کنید.
  3. اطلاعات CPU ( lscpu ) و GPU ( rocminfo ) را برای اشکال‌زدایی چاپ کنید.
  4. مراحل تست (تک پردازنده گرافیکی و تک پردازنده مرکزی) را با استفاده از اسکریپت دانلود شده اجرا کنید.

معنی --config=ci_single_gpu و --config=ci_rocm_cpu چیست؟

این موارد در build_tools/rocm/rocm_xla.bazelrc تعریف شده‌اند. مجموعه تک پردازنده گرافیکی از کمکی GPU موازی استفاده می‌کند، سه بار flakes را دوباره امتحان می‌کند و تست‌ها را به صورت فرآیند-ایزوله اجرا می‌کند. مجموعه پردازنده مرکزی از موازی‌سازی محلی ۲۰۰-پهنی و پوشش‌دهنده ضدعفونی‌کننده استفاده می‌کند:

build:ci_single_gpu --run_under=//build_tools/rocm:parallel_gpu_execute
build:ci_single_gpu --flaky_test_attempts=3

build:ci_rocm_cpu --run_under=//build_tools/rocm:sanitizer_wrapper
build:ci_rocm_cpu --local_test_jobs=200
build:ci_rocm_cpu --strategy=TestRunner=local

پیکربندی سوم، ci_multi_gpu ، در bazelrc وجود دارد اما در حال حاضر از rocm_ci.yml فعال نمی‌شود - این پیکربندی توسط کمک‌کننده مستقل run_xla_multi_gpu.sh در میزبان‌هایی با ≥4 پردازنده گرافیکی استفاده می‌شود.

فیلتر کردن برچسب

execute_ci_build_upstream.sh (در شاخه ROCm/xla ) با استفاده از کمکی که در build_tools/rocm/rocm_tag_filters.sh قرار دارد، یک لیست فیلتر برچسب تشکیل می‌دهد. پوشش درون‌درختی قدیمی build_tools/rocm/run_xla_ci_build.sh نیز همین الگو را نشان می‌دهد:

TAG_FILTERS=$($SCRIPT_DIR/rocm_tag_filters.sh)
for arg in "$@"; do
    if [[ "$arg" == "--config=ci_multi_gpu" ]]; then
        TAG_FILTERS="${TAG_FILTERS},requires-gpu-rocm,requires-gpu-amd,multi_gpu"
    fi
    if [[ "$arg" == "--config=ci_single_gpu" ]]; then
        TAG_FILTERS="${TAG_FILTERS},requires-gpu-rocm,requires-gpu-amd,-multi_gpu"
    fi
    if [[ "$arg" == "--config=ci_rocm_cpu" ]]; then
        TAG_FILTERS="${TAG_FILTERS},gpu,-requires-gpu-rocm,-requires-gpu-amd"
    fi
done

لیست پایه از rocm_tag_filters.sh «کارهایی است که ROCm CI هرگز نباید انجام دهد»:

-no_gpu
-requires-gpu-intel
-requires-gpu-nvidia
-requires-gpu-cuda
-cuda-only
-oneapi-only
-requires-gpu-sm60
-requires-gpu-sm60-only
-requires-gpu-sm70
-requires-gpu-sm70-only
-requires-gpu-sm80
-requires-gpu-sm80-only
-requires-gpu-sm86
-requires-gpu-sm86-only
-requires-gpu-sm89
-requires-gpu-sm89-only
-requires-gpu-sm90
-requires-gpu-sm90-only
-skip_rocprofiler_sdk
-no_oss
-oss_excluded
-oss_serial

سپس موارد اضافه شده به ازای هر پیکربندی، مجموعه را محدود می‌کنند:

پیکربندی اضافه می‌کند
ci_single_gpu requires-gpu-rocm ، requires-gpu-amd ، به gpu- -multi_gpu نیاز دارد
ci_multi_gpu requires-gpu-rocm ، requires-gpu-amd ، multi_gpu
ci_rocm_cpu gpu ، -requires-gpu-rocm ، -requires-gpu-amd

آزمایش‌های حذف‌شده بر اساس نام

روش‌های جمعی، انتشار شاردینگ و PJRT توزیع‌شده به چندین پردازنده گرافیکی AMD نیاز دارند و از اجرای تک پردازنده گرافیکی فیلتر می‌شوند. این روش‌ها باید روی یک میزبان چند پردازنده گرافیکی اختصاصی اجرا شوند.

شغل JAX CI

کار JAX در همان کانتینر اما با یک اسکریپت درایور متفاوت که توسط خود JAX ارائه شده است، اجرا می‌شود:

./ci/run_bazel_test_rocm_rbe.sh \
  --override_repository=xla="${GITHUB_WORKSPACE}" \
  --override_module=xla="${GITHUB_WORKSPACE}" \
  --config=single_gpu \
  --//jax:build_jaxlib=wheel \
  --//jax:build_jax=true \
  --local_test_jobs=1 \
  --action_env=JAX_ENABLE_X64=0 \
  --repo_env=HERMETIC_PYTHON_VERSION=3.14 \
  --repo_env=TF_ROCM_RBE_DOCKER_IMAGE="${DOCKER_IMAGE}"

جزئیات پرچم:

  • --override_repository=xla=... و --override_module=xla=... وابستگی xla مربوط به JAX را در هنگام پرداخت درون‌شاخه‌ای PR تغییر مسیر می‌دهند. بدون این موارد، کار JAX بر اساس کامیت XLA پین‌شده که در WORKSPACE/MODULE.bazel مربوط به JAX ثبت شده است، کامپایل می‌شود که این امر، هدف از اجرای JAX از یک PR مربوط به XLA را از بین می‌برد.
  • --//jax:build_jaxlib=wheel و --//jax:build_jax=true jaxlib را به عنوان یک مصنوع wheel می‌سازیم و خود jax را از منبع بازسازی می‌کنیم - اینگونه است که JAX در حال حاضر افزونه C++ را برای تست‌ها بوت‌استرپ می‌کند.
  • HERMETIC_PYTHON_VERSION=3.14 زنجیره ابزار پایتون را به صورت هرمتیک انتخاب می‌کند (ساخت صرف نظر از پایتون میزبان قابل تکرار است).
  • --local_test_jobs=1 رقابت GPU را پایین نگه می‌دارد؛ با وجود تنها یک پردازنده گرافیکی AMD روی اجراکننده، هیچ مزیتی برای اجرای موازی تست‌های JAX وجود ندارد.
  • JAX_ENABLE_X64=0 با وضعیت تست پیش‌فرض تیم JAX برای CI سریع مطابقت دارد.
  • همان TF_ROCM_RBE_DOCKER_IMAGE به نسل‌های بعدی منتقل می‌شود تا هر کارگر راه دوری که ساخت از EngFlow اجاره می‌کند، همان تصویر ROCm را اجرا کند.

اجرای ساخت از راه دور (EngFlow)

ROCm CI از یک کلاستر ساخت از راه دور EngFlow ( grpcs://wardite.cluster.engflow.com ) برای ذخیره‌سازی از راه دور و اجرای از راه دور استفاده می‌کند. پیکربندی در build_tools/rocm/rocm_xla.bazelrc قرار دارد.

احراز هویت در این کلاستر از طریق گواهی‌های نصب‌شده ( /data/ci-cert.crt ، /data/ci-cert.key ) انجام می‌شود.

پیکربندی‌های کلیدی:

  • REMOTE_GPU_TESTING=1 : بهینه‌سازی‌های اجرای از راه دور (مثلاً دسترسی محدود به سیستم فایل) را فعال می‌کند.
  • @local_config_rocm//rocm:linux_x64 : پلتفرم را مشخص می‌کند، با فرض نصب ROCm در سطح سیستم روی workerها برای حل مخزن @local_config_rocm .

همچنین یک پیکربندی rocm_rbe_dynamic وجود دارد که به صورت محلی ساخته می‌شود اما تحت زمانبند پویای Bazel آزمایش می‌شود (هر اقدام آزمایشی را همزمان به صورت محلی و از راه دور اجرا می‌کند، و هر کدام که زودتر تمام شود را می‌گیرد):

build:rocm_rbe_dynamic --config=rocm_rbe
build:rocm_rbe_dynamic --spawn_strategy=local
test:rocm_rbe_dynamic --experimental_spawn_scheduler
test:rocm_rbe_dynamic --strategy=TestRunner=dynamic
test:rocm_rbe_dynamic --dynamic_mode=default
test:rocm_rbe_dynamic --dynamic_local_strategy=worker,standalone,local
test:rocm_rbe_dynamic --dynamic_remote_strategy=remote
test:rocm_rbe_dynamic --experimental_local_execution_delay=1000
test:rocm_rbe_dynamic --local_resources=cpu=HOST_CPUS*0.5

مرحله‌ی XLA تک-GPU در rocm_ci.yml اساساً از این رویکرد با ارسال مستقیم --internal_spawn_scheduler --strategy=TestRunner=dynamic در خط فرمان، بالای --config=rocm_rbe استفاده می‌کند.

سومین پیکربندی "چتر" ، rocm_ci ، از طریق زیر بارگذاری می‌شود:

# rocm_xla_ci.bazelrc
try-import /usertools/rocm.bazelrc
try-import %workspace%/build_tools/rocm/rocm_xla.bazelrc

/usertools/rocm.bazelrc توسط ایمیج داکر ساخته شده توسط AMD ارائه می‌شود (مسیرهای نصب ROCm میزبان را رمزگذاری می‌کند)؛ bazelrc درون‌شاخه‌ای روی آن لایه‌بندی شده است. بنابراین --config=rocm_ci به معنی "استفاده از زنجیره ابزار ROCm درون‌تصویری به همراه پیکربندی‌های XLA درون‌شاخه‌ای" است.

قفل کردن پردازنده گرافیکی

وقتی یک تست GPU روی میزبان AMD اجرا می‌شود، Bazel آن را از طریق --run_under=//build_tools/rocm:parallel_gpu_execute فراخوانی می‌کند. اسکریپت ( build_tools/rocm/parallel_gpu_execute.sh ) سه کار انجام می‌دهد:

  1. با فراخوانی rocminfo و شمارش خطوط Name: *gfx* تعداد واقعی پردازنده‌های گرافیکی (GPU) را که اجراکننده در اختیار دارد، محاسبه کنید.

    ROCMINFO=$(find -L "${TEST_SRCDIR:-.}" -name "rocminfo" -path "*/bin/rocminfo" | head -n 1)
    TF_GPU_COUNT=$($ROCMINFO | grep "Name: *gfx*" | wc -l)
    

    rocminfo از طریق data = ["//tensorflow/third_party/rocm/google:rocminfo"] هدف Bazel در build_tools/rocm/BUILD به فایل‌های اجرایی اکشن آورده می‌شود، بنابراین در داخل sandbox اجرای از راه دور قابل شناسایی است.

  2. اگر TF_GPU_COUNT == 0 (مثلاً در مجموعه پیش‌فرض RBE که هیچ GPU ندارد)، اسکریپت فقط exec "$@" - تست همچنان اجرا می‌شود، اما بدون هیچ گونه جداسازی برای هر GPU. انتظار می‌رود تست‌هایی که واقعاً به GPU نیاز دارند، خود-شکست بخورند. این شاخه وجود دارد تا تست‌های دارای برچسب GPU که می‌توانند واقعاً روی CPU اجرا شوند، همچنان روی کارگران ارزان اجرا شوند.

  3. در غیر این صورت، یک اسلات مبتنی بر flock ، به ازای هر جفت (gpu, slot_within_gpu) یکی، بدست آورید و CUDA_VISIBLE_DEVICES و HIP_VISIBLE_DEVICES را برای مدت زمان آزمایش به آن شاخص GPU صادر کنید:

    for j in `seq 0 $((TF_TESTS_PER_GPU-1))`; do
      for i in `seq 0 $((TF_GPU_COUNT-1))`; do
        exec {lock_fd}>/var/lock/gpulock${i}_${j} || exit 1
        if flock -n "$lock_fd"; then
          (
            export CUDA_VISIBLE_DEVICES=$i
            export HIP_VISIBLE_DEVICES=$i
            "$TEST_BINARY" "$@"
          )
              fi
      done
    done
    

اسلات‌ها به ترتیب در سراسر GPUها پر می‌شوند (مثلاً ابتدا اسلات ۰ در همه GPUها، سپس اسلات ۱) تا قبل از اشغال بیش از حد حافظه، تداخل به حداقل برسد.

همچنین یک کپی تقریباً یکسان در build_tools/ci/parallel_gpu_execute.sh وجود دارد که نسخه‌ی مبتنی بر CUDA است که توسط مشاغل NVIDIA استفاده می‌شود. تفاوت اصلی آنها در این است که نسخه ROCm در زمان اجرا در واقع rocminfo بررسی می‌کند، در حالی که نسخه CUDA به طور پیش‌فرض به TF_GPU_COUNT=4 اعتماد دارد.

یک کمک‌کننده‌ی دوم، //build_tools/rocm:sanitizer_wrapper ، توسط ci_rocm_cpu و ci_multi_gpu استفاده می‌شود. این یک اسکریپت پوسته‌ی کوچک تولید شده ( echo '#!/bin/bash' > $@; echo 'exec "$$@"' >> $@ ) است که تنها وظیفه‌اش اعلام لیست‌های نادیده گرفته شده‌ی پاک‌کننده به عنوان فایل‌های اجرایی است، به طوری که تغییرات در آن لیست‌های نادیده گرفته شده، اقدامات آزمایشی تحت تأثیر را مجبور به اجرای مجدد می‌کند.

کمک‌کننده‌های مستقل

سه اسکریپت در build_tools/rocm/ طوری طراحی شده‌اند که به صورت دستی روی یک ماشین محلی AMD اجرا شوند و از همان قراردادهای CI پیروی می‌کنند:

  • run_xla.sh — تست رفت و برگشتی تک GPU XLA. تعداد GPU را از طریق rocm-smi تشخیص می‌دهد، N_TEST_JOBS = TF_GPU_COUNT * TF_TESTS_PER_GPU محاسبه می‌کند، شناسه gfx* را از rocminfo برای تنظیم TF_ROCM_AMDGPU_TARGETS می‌گیرد، و bazel test --config=rocm_ci --config=xla_sgpu … را با دستورالعمل فیلتر برچسب مشابه CI فراخوانی می‌کند (هرچند در جزئیات پیاده‌سازی کمی متفاوت هستند). --run_under=//build_tools/ci:parallel_gpu_execute (پوشش‌دهنده به سبک CUDA) استفاده می‌کند.
  • run_xla_multi_gpu.sh — تست چند GPU XLA. به TF_GPU_COUNT ≥ 4 نیاز دارد، در غیر این صورت به طور بی‌صدا خارج می‌شود. از --config=xla_mgpu استفاده می‌کند، NCCL_MAX_NCHANNELS=1 را تنظیم می‌کند و به طور قابل توجهی از --run_under=//build_tools/ci:parallel_gpu_execute عبور نمی‌کند — تست‌های جمعی باید همه GPUها را به طور همزمان ببینند، بنابراین پین کردن GPU برای هر تست آنها را خراب می‌کند.
  • run_xla_ci_build.sh — نسخه قدیمی درون‌شاخه‌ای از آنچه CI اکنون از ROCm/xla دریافت می‌کند. به عنوان مستندی برای نحوه نگاشت آرگومان‌های --config=… به فیلترهای برچسب مفید است.

این سه مورد برای توسعه‌دهندگان AMD وجود دارد که رفتار CI را به صورت محلی بازتولید می‌کنند.

ROCm CI فقط کامپایل شونده

مستقل از اجراکننده‌ی GPU، .github/workflows/ci.yml یک کار XLA Linux x86 GPU ROCm را روی یک اجراکننده‌ی عمومی Linux x86 بدون GPU و بدون نصب سیستم ROCm اجرا می‌کند. این امر قابلیت اطمینان کامپایل را روی تمام PRها مستقل از در دسترس بودن اجراکننده‌ی GPU تضمین می‌کند.

حوضچه و مخزن دونده برای این کار عبارتند از:

{
  pool: "linux-x86-n2-16",
  container: "us-docker.pkg.dev/ml-oss-artifacts-published/ml-public-container/ml-build:latest",
  name: "XLA Linux x86 GPU ROCm",
  repo: "openxla/xla",
}

یک ورودی ماتریس واحد؛ بدون --device=/dev/kfd ؛ بدون حجم گواهی AMD. این کار به build_tools/ci/build.py ارسال می‌شود، که درایور پیکربندی به عنوان داده است که با هر ورودی ماتریس CI دیگر به اشتراک گذاشته شده است:

- run: |
    "$GITHUB_WORKSPACE"/openxla/xla/build_tools/ci/build.py \
      --build="${ { matrix.job_info.name } }_github_actions"

بیلد XLA_LINUX_X86_GPU_ROCM_GITHUB_ACTIONS در build_tools/ci/build.py به صورت زیر تعریف شده است:

Build(
    type_=BuildType.XLA_LINUX_X86_GPU_ROCM_GITHUB_ACTIONS,
    repo="openxla/xla",
    configs=("warnings", "rbe_linux_cpu", "rocm_clang_hermetic"),
    target_patterns=_XLA_DEFAULT_TARGET_PATTERNS,
    build_tag_filters=rocm_tag_filter,
    test_tag_filters=rocm_tag_filter,
    options={**_DEFAULT_BAZEL_OPTIONS, "//xla/tsl:ci_build": True},
    subcommand="build",
)

جزئیات پیکربندی:

  • subcommand="build" — هیچ آزمایشی اجرا نمی‌شود.
  • configs=("warnings", "rbe_linux_cpu", "rocm_clang_hermetic") — این نسخه از مجموعه CPU RBE (بدون نیاز به GPU worker) و پیکربندی rocm_clang_hermetic استفاده می‌کند که به جای وابستگی به وجود /opt/rocm ، یک زنجیره ابزار ROCm + Clang را به صورت هرمتیک دریافت می‌کند.
  • rocm_tag_filter مجموعه فیلترهای زمان اجرا که توسط rocm_ci.yml استفاده می‌شود را به علاوه یک "gpu" صریح منعکس می‌کند، زیرا build.py اسکریپت rocm_tag_filters.sh را در محدوده خود ندارد.

build.py فقط یک کارخانه پیکربندی به عنوان داده است: در هر ساخت، سه دستور Bazel منتشر می‌کند - dry-run ( --nobuild ) retry، real build، و bazel analyze-profile profile.json.gz :

def commands(self) -> List[List[str]]:
    cmds = []
    cmds.extend(self.extra_setup_commands)
    if not (macos_build or windows_build):
      cmds.append(retry(self.bazel_command(subcommand="build",
                                           extra_options=("--nobuild",))))
    cmds.append(self.bazel_command(subcommand=self.subcommand))
    cmds.append(["bazel", "analyze-profile", "profile.json.gz"])
    return cmds

الگوی «اجرای خشک-سپس-ساخت» امکان تلاش مجدد برای رفع خطاهای گذرای دریافت بسته را بدون بازسازی فراهم می‌کند.

این مرحله تضمین می‌کند که رگرسیون‌های کامپایل حتی اگر اجراکننده‌های GPU در دسترس نباشند، شناسایی می‌شوند.

پشتیبانی از ضدعفونی‌کننده

build_tools/rocm/rocm_xla.bazelrc همچنین پیکربندی‌های ASan و TSan را تعریف می‌کند:

build:tsan --strip=never
build:tsan --copt -fsanitize=thread
build:tsan --copt -g
build:tsan --copt -fno-omit-frame-pointer
build:tsan --linkopt -fsanitize=thread
build:tsan --linkopt -g
build:tsan --//build_tools/rocm:sanitizer=tsan
build:tsan --test_env=TSAN_OPTIONS=suppressions=build_tools/rocm/tsan_ignore_list.txt:
build:tsan --run_under=//build_tools/rocm:sanitizer_wrapper

build:asan --test_env=ASAN_OPTIONS=suppressions=build_tools/rocm/asan_ignore_list.txt:use_sigaltstack=0
build:asan --test_env=LSAN_OPTIONS=suppressions=build_tools/rocm/lsan_ignore_list.txt:use_sigaltstack=0
build:asan --//build_tools/rocm:sanitizer=asan
build:asan --run_under=//build_tools/rocm:sanitizer_wrapper

پرچم رشته‌ای //build_tools/rocm:sanitizer ‎ توسط select({"asan": [...], "tsan": [...]}) ‎ در گروه فایل sanitizer_wrapper‎ مصرف می‌شود تا فایل سرکوب مناسب را به فایل‌های اجرایی اکشن آزمایشی وارد کند.

این پیکربندی‌ها امروزه توسط rocm_ci.yml فعال نمی‌شوند؛ آن‌ها برای فراخوانی‌های موقت و برای خطوط لوله پایین‌دستی در دسترس هستند.

جریان اجرا

برای یک فرود معمولی PR در openxla/xla :

PR commit
   
   ├─► .github/workflows/ci.yml ───────────────► matrix of CPU/GPU/ROCm builds
          
          └─► XLA Linux x86 GPU ROCm
                └─► build_tools/ci/build.py
                      └─► bazel build (nobuild  real)
                            configs: warnings + rbe_linux_cpu +
                                     rocm_clang_hermetic
                            tag filter: rocm_tag_filter (compile-only)
   
   └─► .github/workflows/rocm_ci.yml ──────────► AMD GPU runner
           
           ├─► rocm-config: pin Docker image digest
           
           ├─► jax (1 GPU)
                └─► jax/ci/run_bazel_test_rocm_rbe.sh
                      └─► bazel test --config=single_gpu 
                            override_module=xla=<this PR>
                            EngFlow RBE
           
           └─► xla (1 GPU)
                 ├─► wget execute_ci_build_upstream.sh from ROCm/xla
                 ├─► bazel test --config=rocm_ci --config=rocm_rbe
                                 --config=ci_single_gpu
                        (dynamic scheduling, parallel_gpu_execute lock,
                         flock per CUDA_VISIBLE_DEVICES, 3 retries)
                 └─► bazel test --config=rocm_ci --config=rocm_rbe
                                --config=ci_rocm_cpu
                         (200-way local, sanitizer_wrapper, no GPU
                          required but exercises GPU-tagged tests on CPU)

اگر چیزی شکست بخورد:

  • یک لینک EngFlow ( <a href="https://wardite.cluster.engflow.com/invocation/">https://wardite.cluster.engflow.com/invocation/</a><UUID> ) توسط Bazel چاپ می‌شود؛ این مکان، محل استانداردی برای مشاهده لاگ‌های اکشن، بازدیدهای کش و خروجی استاندارد هر تست است.
  • داده‌های پروفایل به /tf/pkg/profile.json.gz می‌روند (این مسیر در اسکریپت‌های AMD به صورت کدگذاری شده است؛ کانتینر --tmpfs به همراه دایرکتوری /tf/pkg جایی است که Bazel داده‌های زمان‌بندی را برای bazel analyze-profile می‌نویسد).
  • خروجی‌های lscpu و rocminfo در بالای هر گزارش کار قرار دارند که اغلب برای بررسی اینکه «آیا پردازنده گرافیکی واقعاً برای کانتینر قابل مشاهده است» کافی است.

نگهداری و به‌روزرسانی‌ها

ویرایش‌های رایج و محل انجام آنها:

هدف فایل
نسخهٔ بامپ ROCm .github/workflows/rocm_ci.yml ، مرحله rocm-config — به‌روزرسانی خلاصه sha256
اضافه کردن/حذف کردن فیلتر تگ پایه build_tools/rocm/rocm_tag_filters.sh
مرحله ROCm فقط کامپایل را دوباره تنظیم کنید build_tools/ci/build.py ، بلوک XLA_LINUX_X86_GPU_ROCM_GITHUB_ACTIONS + تاپل rocm_tag_filter
اضافه کردن/حذف تست‌ها از اسکن تک پردازنده گرافیکی build_tools/rocm/rocm_xla.bazelrc ، test:xla_sgpu
یک تست را به چند پردازنده گرافیکی ارتقا دهید build_tools/rocm/rocm_xla.bazelrc ، test:xla_mgpu و اطمینان حاصل کنید که برچسب multi_gpu را دارد.
تغییر نقطه پایانی یا مسیر احراز هویت EngFlow build_tools/rocm/rocm_xla.bazelrc ، خطوط build:rocm_rbe + volumes: در rocm_ci.yml
ایزولاسیون هر تست را محکم‌تر کنید build_tools/rocm/parallel_gpu_execute.sh
تنظیم پرچم‌های ساخت سمت JAX مرحله jax در rocm_ci.yml ، با فراخوانی JAX's ci/run_bazel_test_rocm_rbe.sh
اسکریپت درایور بالادست را تنظیم کنید این در ROCm/xla در شاخه rocm-dev-infra ( build_tools/rocm/execute_ci_build_upstream.sh ) قرار دارد - در این مخزن نیست

تغییر در build.py باید با بازسازی build_tools/ci/golden_commands.txt همراه شود (متن خوانده شده نحوه انجام آن را توضیح می‌دهد: PYTHONDONTWRITEBYTECODE=1 python3 build.py --dump_commands > golden_commands.txt ). فایل‌های طلایی مستندات هستند، نه اجرا - CI با آنها تفاوتی ندارد - اما بررسی‌کنندگان آنها را می‌خوانند تا خطوط فرمان پیاده‌سازی شده را ببینند.

منابع

  • گردش‌های کاری: .github/workflows/rocm_ci.yml ، .github/workflows/ci.yml
  • اسکریپت‌های مخصوص ROCm و bazelrc: build_tools/rocm/
  • درایور CI مشترک: build_tools/ci/build.py
  • کمک‌رسان تگ-فیلتر: build_tools/rocm/rocm_tag_filters.sh
  • کمک‌کننده‌های قفل پردازنده گرافیکی: build_tools/rocm/parallel_gpu_execute.sh ، build_tools/ci/parallel_gpu_execute.sh
  • لیست‌های نادیده گرفته شده توسط پاک‌کننده: build_tools/rocm/{asan,lsan,tsan}_ignore_list.txt
  • اسکریپت درایور Upstream-fork (خارجی): ROCm/xla روی شاخه rocm-dev-infra ، فایل build_tools/rocm/execute_ci_build_upstream.sh
  • کلاستر EngFlow (RBE + BES): grpcs://wardite.cluster.engflow.com