Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 56 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,60 @@ jobs:
fail-fast: false
matrix:
include:
- name: macOS (Clang)
- name: macOS (Clang, Metal)
os: macos-latest
cmake_args: ""
key: macos
cmake_args: "-DCMAKE_PREFIX_PATH=/opt/homebrew -DSAM3_BUILD_TESTS=ON"
build_args: ""

- name: Linux (GCC)
os: ubuntu-latest
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF"
- name: Ubuntu 24.04 (GCC)
os: ubuntu-24.04
key: ubuntu
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DSAM3_BUILD_TESTS=ON"
build_args: ""

- name: Ubuntu 24.04 (GCC + CUDA)
os: ubuntu-24.04
key: ubuntu-cuda
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DSAM3_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=75 -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache -DSAM3_BUILD_TESTS=ON"
build_args: ""
cuda: true

- name: Windows (MSVC)
os: windows-latest
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows"
key: windows
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DSAM3_BUILD_TESTS=ON -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows"
build_args: "--config Release"

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive

- name: Setup CUDA toolkit
if: matrix.cuda
uses: Jimver/cuda-toolkit@v0.2.35
with:
cuda: '12.8.0'

- name: Install Ninja (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y ninja-build
run: sudo apt-get update && sudo apt-get install -y ninja-build libsdl2-dev libgl1-mesa-dev

- name: Install Ninja (macOS)
if: runner.os == 'macOS'
run: brew install ninja
run: brew install ninja sdl2

- name: Install SDL2 (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: vcpkg install sdl2:x64-windows

- name: ccache
uses: hendrikmuhs/ccache-action@v1
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ci-${{ matrix.os }}
key: ci-${{ matrix.key }}

- name: Configure
run: >
Expand All @@ -69,27 +85,39 @@ jobs:
- name: Build
run: cmake --build build ${{ matrix.build_args }} --parallel

- name: Verify build artifacts
- name: Install and verify package tree
shell: bash
run: |
if [ -f build/libsam3.a ]; then
echo "Found build/libsam3.a"
elif [ -f build/Release/sam3.lib ]; then
echo "Found build/Release/sam3.lib"
elif [ -f build/sam3.lib ]; then
echo "Found build/sam3.lib"
PREFIX="$RUNNER_TEMP/sam3-install"
cmake --install build ${{ matrix.build_args }} --prefix "$PREFIX"

if [ -f "$PREFIX/lib/libsam3.a" ] || [ -f "$PREFIX/lib/sam3.lib" ]; then
echo "libsam3 installed OK"
else
echo "ERROR: sam3 library not found in install tree"
exit 1
fi

if [ -f "$PREFIX/include/sam3.h" ]; then
echo "sam3.h installed OK"
else
echo "ERROR: sam3.h not found in install tree"
exit 1
fi

if [ -f "$PREFIX/bin/sam3_image" ] || [ -f "$PREFIX/bin/sam3_image.exe" ]; then
echo "GUI examples installed OK"
else
echo "ERROR: sam3 library not found"
echo "ERROR: sam3_image not found in install tree (SDL2 missing?)"
exit 1
fi

if [ "$RUNNER_OS" = "Windows" ]; then
for exe in sam3_image.exe sam3_video.exe; do
if [ -f "build/examples/Release/$exe" ]; then
echo "Found build/examples/Release/$exe"
else
echo "ERROR: $exe not built (GUI examples were silently skipped — likely SDL2 not found)"
exit 1
fi
done
if [ -f "$PREFIX/bin/test_load" ] || [ -f "$PREFIX/bin/test_load.exe" ]; then
echo "tests installed OK"
else
echo "ERROR: test_load not found in install tree"
exit 1
fi

echo "Installed binaries:"
ls -1 "$PREFIX/bin" | sort
119 changes: 41 additions & 78 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,54 @@ jobs:
include:
- name: macOS arm64 (Metal)
os: macos-latest
artifact: sam3-darwin-arm64
cmake_args: "-DBUILD_SHARED_LIBS=OFF"
build_args: ""
pkg: sam3-darwin-arm64
ext: tar.gz
cmake_args: "-DBUILD_SHARED_LIBS=OFF -DSAM3_BUILD_EXAMPLES=OFF -DSAM3_BUILD_TESTS=OFF"

- name: macOS x86_64
os: macos-latest
artifact: sam3-darwin-x86_64
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_OSX_ARCHITECTURES=x86_64 -DGGML_NATIVE=OFF"
build_args: ""
pkg: sam3-darwin-x86_64
ext: tar.gz
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_OSX_ARCHITECTURES=x86_64 -DGGML_NATIVE=OFF -DSAM3_BUILD_EXAMPLES=OFF -DSAM3_BUILD_TESTS=OFF"

- name: Linux x86_64
os: ubuntu-latest
artifact: sam3-linux-x86_64
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF"
build_args: ""
- name: Ubuntu 24.04 x86_64
os: ubuntu-24.04
pkg: sam3-linux-x86_64-ubuntu24.04
ext: tar.gz
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -DSAM3_BUILD_EXAMPLES=OFF -DSAM3_BUILD_TESTS=OFF"

- name: Linux arm64
- name: Ubuntu 24.04 arm64
os: ubuntu-24.04-arm
artifact: sam3-linux-arm64
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF"
build_args: ""
pkg: sam3-linux-arm64-ubuntu24.04
ext: tar.gz
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -DSAM3_BUILD_EXAMPLES=OFF -DSAM3_BUILD_TESTS=OFF"

- name: Ubuntu 24.04 x86_64 (CUDA)
os: ubuntu-24.04
pkg: sam3-linux-x86_64-ubuntu24.04-cuda
ext: tar.gz
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -DSAM3_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=\"75-virtual;80-virtual;86-real;89-real;90-virtual\" -DSAM3_BUILD_EXAMPLES=OFF -DSAM3_BUILD_TESTS=OFF"
cuda: true

- name: Windows x86_64
os: windows-latest
artifact: sam3-win-x86_64
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -A x64"
build_args: "--config Release"
pkg: sam3-win-x86_64
ext: zip
cmake_args: "-DGGML_METAL=OFF -DSAM3_METAL=OFF -DBUILD_SHARED_LIBS=OFF -A x64 -DSAM3_BUILD_EXAMPLES=OFF -DSAM3_BUILD_TESTS=OFF"
build_args: "--config Release"

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive

- name: Setup CUDA toolkit
if: matrix.cuda
uses: Jimver/cuda-toolkit@v0.2.35
with:
cuda: '12.8.0'

- name: Install Ninja (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y ninja-build
Expand All @@ -63,78 +72,31 @@ jobs:
run: brew install ninja

- name: ccache
uses: hendrikmuhs/ccache-action@v1
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: release-${{ matrix.artifact }}
key: release-${{ matrix.pkg }}

- name: Configure
run: >
cmake -B build
${{ runner.os != 'Windows' && '-G Ninja' || '' }}
${{ matrix.cmake_args }}
-DCPACK_PACKAGE_FILE_NAME=${{ matrix.pkg }}
${{ runner.os != 'Windows' && '-DCMAKE_BUILD_TYPE=Release' || '' }}
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

- name: Build
run: cmake --build build ${{ matrix.build_args }} --parallel

- name: Package (Unix)
if: runner.os != 'Windows'
run: |
mkdir -p staging/${{ matrix.artifact }}/{lib,include,bin}

cp build/libsam3.a staging/${{ matrix.artifact }}/lib/
find build/ggml -name "*.a" -exec cp {} staging/${{ matrix.artifact }}/lib/ \;

cp sam3.h staging/${{ matrix.artifact }}/include/
cp -r ggml/include/* staging/${{ matrix.artifact }}/include/

for bin in sam3_quantize sam3_benchmark sam3_profile_edgetam; do
if [ -f "build/examples/${bin}" ]; then
cp "build/examples/${bin}" staging/${{ matrix.artifact }}/bin/
fi
done

cd staging
tar czf ../${{ matrix.artifact }}.tar.gz ${{ matrix.artifact }}

- name: Package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path staging/${{ matrix.artifact }}/lib
New-Item -ItemType Directory -Force -Path staging/${{ matrix.artifact }}/include
New-Item -ItemType Directory -Force -Path staging/${{ matrix.artifact }}/bin

# Library (MSVC multi-config puts outputs in Release/)
$libPaths = @("build/Release/sam3.lib", "build/sam3.lib")
foreach ($p in $libPaths) {
if (Test-Path $p) { Copy-Item $p staging/${{ matrix.artifact }}/lib/; break }
}

# ggml static libs
Get-ChildItem -Path build/ggml -Recurse -Filter "*.lib" | Copy-Item -Destination staging/${{ matrix.artifact }}/lib/

# Headers
Copy-Item sam3.h staging/${{ matrix.artifact }}/include/
Get-ChildItem -Path ggml/include -Filter "*.h" | Copy-Item -Destination staging/${{ matrix.artifact }}/include/

# Example binaries
foreach ($bin in @("sam3_quantize", "sam3_benchmark", "sam3_profile_edgetam")) {
$paths = @("build/examples/Release/${bin}.exe", "build/examples/${bin}.exe")
foreach ($p in $paths) {
if (Test-Path $p) { Copy-Item $p staging/${{ matrix.artifact }}/bin/; break }
}
}

Compress-Archive -Path staging/${{ matrix.artifact }} -DestinationPath ${{ matrix.artifact }}.zip
- name: Package (CPack)
run: cmake --build build ${{ matrix.build_args }} --target package

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: ${{ matrix.artifact }}
path: ${{ matrix.artifact }}.${{ matrix.ext }}
name: ${{ matrix.pkg }}
path: build/${{ matrix.pkg }}.${{ matrix.ext }}

release:
name: Create Release
Expand All @@ -145,12 +107,12 @@ jobs:

steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: artifacts

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ github.ref_name }}
name: sam3.cpp ${{ github.ref_name }}
Expand All @@ -160,6 +122,7 @@ jobs:
files: |
artifacts/sam3-darwin-arm64/*.tar.gz
artifacts/sam3-darwin-x86_64/*.tar.gz
artifacts/sam3-linux-x86_64/*.tar.gz
artifacts/sam3-linux-arm64/*.tar.gz
artifacts/sam3-linux-x86_64-ubuntu24.04/*.tar.gz
artifacts/sam3-linux-arm64-ubuntu24.04/*.tar.gz
artifacts/sam3-linux-x86_64-ubuntu24.04-cuda/*.tar.gz
artifacts/sam3-win-x86_64/*.zip
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "ggml"]
path = ggml
url = https://github.com/PABannier/ggml.git
url = https://github.com/greenjava/ggml.git
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Project

sam3.cpp — a C++14 port of Meta's SAM 3 (Segment Anything Model 3) using ggml for inference on CPU and Metal.
sam3.cpp — a C++14 port of Meta's SAM 3 (Segment Anything Model 3) using ggml for inference on CPU, Metal, and CUDA.

## Architecture

Expand Down
51 changes: 51 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ if(APPLE AND SAM3_METAL)
set(GGML_METAL_EMBED_LIBRARY ON CACHE BOOL "" FORCE)
endif()

# Check if CUDA should be enabled
option(SAM3_CUDA "Enable CUDA backend" OFF)
# ggml options — enable CUDA
if(SAM3_CUDA)
set(GGML_CUDA ON CACHE BOOL "" FORCE)
endif()

add_subdirectory(ggml)

# sam3 static library
Expand All @@ -38,3 +45,47 @@ option(SAM3_BUILD_TESTS "Build test executables" OFF)
if(SAM3_BUILD_TESTS)
add_subdirectory(tests)
endif()

# --- Install ---
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(SAM3_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Location of sam3 header files")
set(SAM3_LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Location of sam3 library files")
set(SAM3_BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Location of sam3 binary files")

install(TARGETS sam3 ARCHIVE DESTINATION ${SAM3_LIB_INSTALL_DIR})
install(FILES sam3.h DESTINATION ${SAM3_INCLUDE_INSTALL_DIR})
install(FILES stb/stb_image.h stb/stb_image_write.h DESTINATION ${SAM3_INCLUDE_INSTALL_DIR}/stb)

configure_package_config_file(
cmake/sam3-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/sam3-config.cmake
INSTALL_DESTINATION ${SAM3_LIB_INSTALL_DIR}/cmake/sam3
PATH_VARS SAM3_INCLUDE_INSTALL_DIR SAM3_LIB_INSTALL_DIR SAM3_BIN_INSTALL_DIR)

write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/sam3-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)

install(FILES
${CMAKE_CURRENT_BINARY_DIR}/sam3-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/sam3-version.cmake
DESTINATION ${SAM3_LIB_INSTALL_DIR}/cmake/sam3)

# Package archive (make package / cpack)
set(CPACK_PACKAGE_NAME "sam3")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_VENDOR "sam3.cpp")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "C++ inference for Meta SAM 3 on ggml")
if(WIN32)
set(CPACK_GENERATOR "ZIP")
else()
set(CPACK_GENERATOR "TGZ")
endif()
if(NOT CPACK_PACKAGE_FILE_NAME)
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}")
endif()
include(CPack)

Loading