From 970dbe8e25ca15e8284b511f52c8d87ebb68158a Mon Sep 17 00:00:00 2001 From: Cheng Date: Tue, 29 Jul 2025 08:43:22 +0900 Subject: [PATCH] Use ccache in CI (#2414) * Detect ccache * Use ccache in CI * Separate cache for different images * Test both 12.2 and 12.9 for PRs --- .circleci/config.yml | 27 +++++++++++++++++++++++++-- CMakeLists.txt | 10 ++++++++++ setup.py | 3 +++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f33e80f0cd..0fea8804cd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,22 +212,42 @@ jobs: resource_class: gpu.nvidia.small.gen2 steps: - checkout + - restore_cache: + keys: + - cuda-<< parameters.image_date >>-{{ arch }}- - run: - name: Install Python package + name: Install dependencies command: | sudo apt-get update sudo apt-get install libcudnn9-dev-cuda-12 sudo apt-get install libblas-dev liblapack-dev liblapacke-dev + curl -sL https://github.com/ccache/ccache/releases/download/v4.11.3/ccache-4.11.3-linux-x86_64.tar.xz | tar xJf - + sudo mv ccache-4.11.3-linux-x86_64/ccache /usr/bin/ccache + rm -rf ccache-4.11.3-linux-x86_64 + - run: + name: Install Python package + command: | python3 -m venv env source env/bin/activate CMAKE_ARGS="-DMLX_BUILD_CUDA=ON -DCMAKE_CUDA_COMPILER=`which nvcc`" \ - pip install -e ".[dev]" + pip install -e ".[dev]" -v - run: name: Run Python tests command: | source env/bin/activate LOW_MEMORY=1 DEVICE=cpu python -m unittest discover python/tests -v LOW_MEMORY=1 DEVICE=gpu python -m tests discover python/tests -v + - run: + name: CCache report + command: | + ccache --show-stats + ccache --zero-stats + ccache --max-size 400MB + ccache --cleanup + - save_cache: + key: cuda-<< parameters.image_date >>-{{ arch }}-{{ epoch }} + paths: + - /home/circleci/.cache/ccache build_release: parameters: @@ -555,6 +575,9 @@ workflows: requires: [ hold ] - cuda_build_and_test: requires: [ hold ] + matrix: + parameters: + image_date: ["2023.11.1", "2025.05.1"] nightly_build: when: and: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e67e4bf25..1ed41aea5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ option(MLX_BUILD_GGUF "Include support for GGUF format" ON) option(MLX_BUILD_SAFETENSORS "Include support for safetensors format" ON) option(MLX_BUILD_BLAS_FROM_SOURCE "Build OpenBLAS from source code" OFF) option(MLX_METAL_JIT "Use JIT compilation for Metal kernels" OFF) +option(MLX_USE_CCACHE "Use CCache for compilation cache when available" ON) option(BUILD_SHARED_LIBS "Build mlx as a shared library" OFF) # --------------------- Processor tests ------------------------- @@ -68,6 +69,15 @@ else() set(MLX_BUILD_METAL OFF) endif() +if(MLX_USE_CCACHE) + find_program(CCACHE_PROGRAM ccache) + if(CCACHE_PROGRAM) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CUDA_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + endif() +endif() + # ----------------------------- Lib ----------------------------- include(FetchContent) diff --git a/setup.py b/setup.py index 4485d274d3..d15f36b2b7 100644 --- a/setup.py +++ b/setup.py @@ -120,6 +120,9 @@ class CMakeBuild(build_ext): if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ: build_args += [f"-j{os.cpu_count()}"] + # Avoid cache miss when building from temporary dirs. + os.environ["CCACHE_BASEDIR"] = os.path.abspath(self.build_temp) + subprocess.run( ["cmake", ext.sourcedir, *cmake_args], cwd=build_temp, check=True )