Skip to content

[Feature] Swift unit tests over CMake setup #324

@incertum

Description

@incertum

Follow for #320 (comment) @davidkoski
We may want to consider waiting until we have adopted the newer Swift Testing framework? WDYT?

Today it could work like this:

CMakeLists.txt

option(MLX_SWIFT_BUILD_UNIT_TESTS "Build unit tests for mlx-swift, Linux support only" OFF)

...

# Swift mlx-swift Unit Tests
if(MLX_SWIFT_BUILD_UNIT_TESTS)
  if(APPLE)
    message(FATAL_ERROR "Building mlx-swift unit tests with CMake on macOS is not supported. Please use Swift Package Manager ('swift test') instead.")
  elseif(UNIX AND NOT APPLE)
    enable_testing()
    target_compile_options(MLX PRIVATE -enable-testing)
    target_compile_options(MLXRandom PRIVATE -enable-testing)
    target_compile_options(MLXNN PRIVATE -enable-testing)
    target_compile_options(MLXOptimizers PRIVATE -enable-testing)
    target_compile_options(MLXFFT PRIVATE -enable-testing)
    target_compile_options(MLXLinalg PRIVATE -enable-testing)
    target_compile_options(MLXFast PRIVATE -enable-testing)

    file(GLOB MLXTests_SOURCES
        CONFIGURE_DEPENDS
        ${CMAKE_CURRENT_LIST_DIR}/Tests/MLXTests/*.swift
    )

    if(MLXTests_SOURCES)
      add_executable(MLXTestsRunner
          ${MLXTests_SOURCES}
          ${CMAKE_CURRENT_LIST_DIR}/Tests/LinuxMain.swift
      )

      target_link_libraries(MLXTestsRunner PRIVATE
          MLX
          MLXRandom
          MLXNN
          MLXOptimizers
          MLXFFT
          MLXLinalg
          MLXFast
      )

      target_compile_options(MLXTestsRunner PRIVATE -enable-testing)
      target_link_options(MLXTestsRunner PRIVATE "-Xlinker" "--export-dynamic")
      add_test(NAME MLXTestsAll COMMAND MLXTestsRunner)
    endif()
  endif()
endif()

Need a new main file where we would have to maintain a listing of all tests. Wouldn't be a big fan of this ...

Tests/LinuxMain.swift

import XCTest
import MLX

extension ArrayAtTests {
    static var allTests = [
        ("testArrayAt", testArrayAt),
    ]
}

@main
struct TestRunner {
    static func main() {
        Stream.withNewDefaultStream(device: .cpu) {
            XCTMain([
                testCase(ArrayAtTests.allTests),
            ])
        }
    }
}

Run

rm -rf build
mkdir -p build
pushd build
cmake -DMLX_BUILD_METAL=OFF -DMLX_SWIFT_BUILD_UNIT_TESTS=ON .. -G Ninja
ninja
./example1
./tutorial
ctest -V
popd

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions