Skip to content
Draft
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
233 changes: 233 additions & 0 deletions .github/workflows/test-vm-setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# SPDX-FileCopyrightText: (c) 2025 Tenstorrent AI ULC
# SPDX-License-Identifier: Apache-2.0
#
# Manual workflow to test the Lima VM setup for ttsim testing.
# This verifies that the bundled ttsim binaries and VM scripts work correctly.
#
# Note: This workflow uses macos-26 which has limited resources:
# - 3 CPUs (M1)
# - 7 GB RAM
# - 14 GB disk
# The VM is configured with reduced resources to fit these constraints.

name: Test VM Setup

on:
workflow_dispatch:
inputs:
chip_type:
description: "Chip type to simulate"
type: choice
options:
- wh
- bh
default: wh
skip_tt_mlir_build:
description: "Skip tt-mlir build (faster, but tests won't run)"
type: boolean
default: false

jobs:
test-vm-setup:
runs-on: macos-26
timeout-minutes: 180 # 3 hours for full build

env:
TT_ROOT: ${{ github.workspace }}/tt
VM_NAME: ttlang-ttsim-ci
# Reduced resources for CI runner (macos-26 has 3 CPUs, 7GB RAM, 14GB disk)
VM_CPUS: 2
VM_MEMORY: 4GiB
VM_DISK: 10GiB
CHIP_TYPE: ${{ inputs.chip_type }}

steps:
- name: Show runner info
run: |
echo "Runner OS: $RUNNER_OS"
echo "Runner Arch: $RUNNER_ARCH"
sysctl -n hw.ncpu
sysctl -n hw.memsize | awk '{print $0/1024/1024/1024 " GB"}'
df -h

- name: Checkout tt-lang
uses: actions/checkout@v4
with:
path: tt/tt-lang

- name: Read tt-mlir version
id: ttmlir-version
run: |
TTMLIR_COMMIT=$(cat tt/tt-lang/third-party/tt-mlir.commit | tr -d '[:space:]')
echo "commit=$TTMLIR_COMMIT" >> $GITHUB_OUTPUT

- name: Checkout tt-mlir
uses: actions/checkout@v4
with:
repository: tenstorrent/tt-mlir
ref: ${{ steps.ttmlir-version.outputs.commit }}
path: tt/tt-mlir
submodules: recursive
fetch-depth: 0

- name: Install Lima
run: |
brew install lima
limactl --version

- name: Verify bundled ttsim binaries
run: |
echo "Checking bundled ttsim binaries..."
ls -la tt/tt-lang/tools/vm/bin/
ls -la tt/tt-lang/tools/vm/bin/wh/
ls -la tt/tt-lang/tools/vm/bin/bh/

# Verify the binary for selected chip type exists
if [[ ! -f "tt/tt-lang/tools/vm/bin/${{ inputs.chip_type }}/libttsim.so" ]]; then
echo "ERROR: libttsim.so not found for chip type: ${{ inputs.chip_type }}"
exit 1
fi
echo "✓ Bundled libttsim.so found for ${{ inputs.chip_type }}"

- name: Validate VM configuration
run: |
cd tt/tt-lang
source tools/vm/config.sh

echo "=== Configuration Validation ==="
config_summary

echo ""
echo "=== Path Validation ==="
if validate_paths; then
echo "✓ All paths valid"
else
echo "✗ Path validation failed"
exit 1
fi

- name: Generate Lima configuration
run: |
cd tt/tt-lang/tools/vm

# Source config to get variables
source config.sh

# Generate lima.yaml from template
sed -e "s|@TT_ROOT@|${TT_ROOT}|g" \
-e "s|@VM_MOUNT_POINT@|$(get_vm_mount_point)|g" \
-e "s|@VM_CPUS@|${VM_CPUS}|g" \
-e "s|@VM_MEMORY@|${VM_MEMORY}|g" \
-e "s|@VM_DISK@|${VM_DISK}|g" \
-e "s|@UBUNTU_VERSION@|${UBUNTU_VERSION}|g" \
-e "s|@CHIP_TYPE@|${CHIP_TYPE}|g" \
lima.yaml.template > lima.yaml

echo "=== Generated Lima Configuration ==="
cat lima.yaml

- name: Create Lima VM
run: |
cd tt/tt-lang/tools/vm

echo "Creating Lima VM: $VM_NAME"
limactl create --name="$VM_NAME" lima.yaml

echo "Starting Lima VM..."
limactl start "$VM_NAME"

echo "Waiting for VM to be ready..."
sleep 10

echo "VM Status:"
limactl list

- name: Verify VM access
run: |
echo "Testing SSH access to VM..."
limactl shell "$VM_NAME" -- uname -a
limactl shell "$VM_NAME" -- cat /etc/os-release
limactl shell "$VM_NAME" -- df -h

- name: Verify mount point
run: |
echo "Checking if TT_ROOT is mounted in VM..."
limactl shell "$VM_NAME" -- ls -la /home/runner.linux/tt/ || {
echo "Mount point not found, checking available mounts..."
limactl shell "$VM_NAME" -- mount | grep -i tt || true
limactl shell "$VM_NAME" -- ls -la /home/ || true
}

- name: Verify bundled binary accessible in VM
run: |
limactl shell "$VM_NAME" -- bash -c "
ls -la /home/runner.linux/tt/tt-lang/tools/vm/bin/${{ inputs.chip_type }}/
file /home/runner.linux/tt/tt-lang/tools/vm/bin/${{ inputs.chip_type }}/libttsim.so
"

- name: Test provisioning script (dry run)
if: ${{ inputs.skip_tt_mlir_build }}
run: |
echo "Skipping full provisioning (skip_tt_mlir_build=true)"
echo "Would run: provision-vm.sh"

# Just verify the script is accessible and has correct syntax
limactl shell "$VM_NAME" -- bash -n /home/runner.linux/tt/tt-lang/tools/vm/provision-vm.sh
echo "✓ Provisioning script syntax OK"

- name: Run full provisioning
if: ${{ !inputs.skip_tt_mlir_build }}
run: |
echo "Running full VM provisioning..."
echo "This will build ttmlir-toolchain, tt-mlir, and tt-lang"
echo "Expected time: 1-2 hours"

limactl shell "$VM_NAME" -- bash -c "
export TT_ROOT_VM='/home/runner.linux/tt'
export LINUX_VM_DIR='\${TT_ROOT_VM}/linux-vm'
export TTMLIR_TOOLCHAIN_DIR='\${LINUX_VM_DIR}/ttmlir-toolchain'
export CHIP_TYPE='${{ inputs.chip_type }}'
export SIM_DIR='\$HOME/sim'
export CMAKE_BUILD_TYPE='Release'
export USE_CCACHE='ON'

bash '\${TT_ROOT_VM}/tt-lang/tools/vm/provision-vm.sh'
"

- name: Verify simulator setup
if: ${{ !inputs.skip_tt_mlir_build }}
run: |
echo "Verifying simulator directory..."
limactl shell "$VM_NAME" -- bash -c "
ls -la ~/sim/
echo ''
echo 'Checking libttsim.so:'
file ~/sim/libttsim.so
echo ''
echo 'Checking soc_descriptor.yaml:'
head -20 ~/sim/soc_descriptor.yaml
"

- name: Run smoke test
if: ${{ !inputs.skip_tt_mlir_build }}
run: |
echo "Running smoke test inside VM..."
limactl shell "$VM_NAME" -- bash -c "
source ~/activate-ttsim.sh
cd /home/runner.linux/tt/tt-lang
python test/python/smoketest.py
"

- name: Cleanup VM
if: always()
run: |
echo "Cleaning up VM..."
limactl stop "$VM_NAME" || true
limactl delete --force "$VM_NAME" || true
echo "VM cleaned up"

- name: Show disk usage
if: always()
run: |
echo "Final disk usage:"
df -h
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ generated/pykernels/*
**/temp/

test/temp

# VM testing infrastructure
tools/vm/config.local.sh
tools/vm/lima.yaml
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ option(TTLANG_ENABLE_RUNTIME "Enable runtime support" OFF)
option(CODE_COVERAGE "Enable coverage reporting" OFF)
option(TTLANG_ENABLE_PERF_TRACE "Enable performance trace" OFF)
option(TTLANG_ENABLE_DOCS "Enable Sphinx documentation build" OFF)
option(TTLANG_BUILD_TTMLIR_TOOLCHAIN "Build LLVM/MLIR toolchain from tt-mlir source (requires TTMLIR_TOOLCHAIN_DIR env var)" OFF)

if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
Expand Down
22 changes: 22 additions & 0 deletions cmake/modules/ExternTTMLIR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ function(ttlang_create_ttmlir_aliases)
endif()

set(_alias_count 0)

foreach(target IN LISTS TTMLIR_EXPORTED_TARGETS)
if(TARGET TTMLIR::${target} AND NOT TARGET ${target})
add_library(${target} ALIAS TTMLIR::${target})
math(EXPR _alias_count "${_alias_count} + 1")
endif()
endforeach()

message(STATUS "Created ${_alias_count} aliases for installed tt-mlir targets")
endfunction()

Expand Down Expand Up @@ -168,6 +170,17 @@ else()

message(STATUS "tt-mlir not found. Building private copy version: ${TTMLIR_GIT_TAG}")

if(TTLANG_BUILD_TTMLIR_TOOLCHAIN)
if(NOT DEFINED ENV{TTMLIR_TOOLCHAIN_DIR})
message(FATAL_ERROR "TTLANG_BUILD_TTMLIR_TOOLCHAIN is enabled but TTMLIR_TOOLCHAIN_DIR environment variable is not set. "
"Set it to the toolchain install directory, e.g.: export TTMLIR_TOOLCHAIN_DIR=$HOME/t/ttmlir-toolchain")
endif()

set(_BUILD_TOOLCHAIN_DIR "$ENV{TTMLIR_TOOLCHAIN_DIR}")
message(STATUS "TTLANG_BUILD_TTMLIR_TOOLCHAIN enabled, installing to: ${_BUILD_TOOLCHAIN_DIR}")
set(TTMLIR_TOOLCHAIN_DIR "${_BUILD_TOOLCHAIN_DIR}" CACHE PATH "tt-mlir toolchain installation directory" FORCE)
endif()

set(_TOOLCHAIN_Python3_ROOT_DIR "${TTMLIR_TOOLCHAIN_DIR}/venv")
set(_TOOLCHAIN_Python3_EXECUTABLE "${TTMLIR_TOOLCHAIN_DIR}/venv/bin/python3")
set(_TTMLIR_TARGETS_TO_BUILD "-t all")
Expand Down Expand Up @@ -238,6 +251,15 @@ else()
BINARY_DIR "${_TTMLIR_BUILD_DIR}"
)

if(TTLANG_BUILD_TTMLIR_TOOLCHAIN)
message(STATUS "Building LLVM/MLIR toolchain in ${CMAKE_BINARY_DIR}/_deps/tt-mlir-toolchain-build (this may take a while)...")
execute_process(
COMMAND "${CMAKE_SOURCE_DIR}/tools/build-toolchain.sh" "${_TTMLIR_SOURCE_DIR}" "${CMAKE_BINARY_DIR}/_deps/tt-mlir-toolchain-build"
COMMAND_ECHO STDOUT
COMMAND_ERROR_IS_FATAL ANY
)
endif()

set(_TTMLIR_CMAKE_ARGS
-G Ninja
-B ${_TTMLIR_BUILD_DIR}
Expand Down
18 changes: 15 additions & 3 deletions docs/BUILD_SYSTEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,24 @@ If `TTMLIR_BUILD_DIR` is not specified:
If tt-mlir is not found in scenarios 1 or 2:
1. Reads the commit SHA from `third-party/tt-mlir.commit`
2. Uses `FetchContent_Populate` to clone tt-mlir at the above SHA
3. Configures tt-mlir with platform-specific options:
3. Optionally builds the LLVM/MLIR toolchain if `TTLANG_BUILD_TTMLIR_TOOLCHAIN=ON`
4. Configures tt-mlir with platform-specific options:
- **Linux**: Runtime and runtime tests enabled
- **macOS**: Runtime and runtime tests disabled
- Common: StableHLO OFF, OPMODEL OFF, Python bindings ON, Debug strings ON
- Performance trace: Controlled by `TTLANG_ENABLE_PERF_TRACE` (default: OFF)
4. Builds and installs tt-mlir to `${TTMLIR_INSTALL_PREFIX}` (default: `${CMAKE_BINARY_DIR}/tt-mlir-install`)
5. Uses the newly built tt-mlir for the tt-lang build
5. Builds and installs tt-mlir to `${TTMLIR_INSTALL_PREFIX}` (default: `${CMAKE_BINARY_DIR}/tt-mlir-install`)
6. Uses the newly built tt-mlir for the tt-lang build

**Building the toolchain from source:**

If you don't have a pre-built LLVM/MLIR toolchain, you can build it automatically:
```bash
export TTMLIR_TOOLCHAIN_DIR=/path/to/toolchain
cmake -GNinja -Bbuild . -DTTLANG_BUILD_TTMLIR_TOOLCHAIN=ON
```

This builds the LLVM/MLIR toolchain from tt-mlir's `env/CMakeLists.txt` into `TTMLIR_TOOLCHAIN_DIR` before building tt-mlir itself. The toolchain build takes significant time (1-2 hours) but only needs to be done once.

**Python Environment:**
- **Scenarios 1 & 2**: Use Python from `${TTMLIR_TOOLCHAIN_DIR}/venv` with `Python3_FIND_VIRTUALENV=ONLY`
Expand Down Expand Up @@ -205,6 +216,7 @@ cmake --build build
- `TTLANG_ENABLE_BINDINGS_PYTHON` (default: OFF) - Enable Python bindings
- `TTLANG_ENABLE_RUNTIME` (default: OFF) - Enable runtime support
- `TTLANG_ENABLE_PERF_TRACE` (default: OFF) - Enable performance trace (Scenario 3 only, passed to tt-mlir build)
- `TTLANG_BUILD_TTMLIR_TOOLCHAIN` (default: OFF) - Build LLVM/MLIR toolchain from tt-mlir source (Scenario 3 only, requires `TTMLIR_TOOLCHAIN_DIR` env var)
- `CODE_COVERAGE` (default: OFF) - Enable code coverage reporting

**Examples:**
Expand Down
Loading