diff --git a/.github/actions/setup-randblas-deps-windows/setup.ps1 b/.github/actions/setup-randblas-deps-windows/setup.ps1 index 2a9d1033..63454e33 100644 --- a/.github/actions/setup-randblas-deps-windows/setup.ps1 +++ b/.github/actions/setup-randblas-deps-windows/setup.ps1 @@ -110,6 +110,12 @@ if (-not $VcpkgExecutable) { if ($vcpkgCommand) { $vcpkgCandidates += $vcpkgCommand.Source } + if ($env:VSINSTALLDIR) { + # Visual Studio 2022 17.6+ bundles vcpkg with the C++ workload; a + # developer prompt exports VSINSTALLDIR but does not always put + # vcpkg.exe on PATH. + $vcpkgCandidates += Join-Path $env:VSINSTALLDIR "VC\vcpkg\vcpkg.exe" + } $VcpkgExecutable = $vcpkgCandidates | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1 @@ -130,11 +136,44 @@ $mklLibraries = @( ) if (-not (Test-Path -LiteralPath $mklLibraries[0])) { - Invoke-Checked -Program $VcpkgExecutable -Arguments @( - "install", - "intel-mkl:x64-windows", - "--x-install-root=$vcpkgInstall" - ) + # Manifest mode is the only mode every vcpkg distribution supports: the + # copy bundled with Visual Studio has no classic-mode instance, so + # `vcpkg install intel-mkl:x64-windows` fails there outright. Generate a + # minimal manifest and point every scratch tree at DependencyRoot -- the + # bundled vcpkg lives under Program Files, where its default scratch + # locations are not writable. The bundled vcpkg additionally requires + # builtin-baseline; the pin below is vcpkg release 2026.07.29 + # (intel-mkl 2025.2.0), which also makes the oneMKL version independent + # of the vcpkg copy's age. + $vcpkgScratch = Join-Path $DependencyRoot "vcpkg-scratch" + $manifestDir = Join-Path $vcpkgScratch "manifest" + New-Item -ItemType Directory -Force -Path $manifestDir | Out-Null + Set-Content -Path (Join-Path $manifestDir "vcpkg.json") -Encoding ascii -Value @( + '{', + ' "name": "randblas-windows-deps",', + ' "version-string": "1",', + ' "builtin-baseline": "9e593bb18ea69cc5095e012465dcd675a822ed0d",', + ' "dependencies": [ "intel-mkl" ]', + '}') + Push-Location $manifestDir + try { + Invoke-Checked -Program $VcpkgExecutable -Arguments @( + "install", + "--triplet", "x64-windows", + "--x-install-root=$vcpkgInstall", + "--downloads-root=$(Join-Path $vcpkgScratch 'downloads')", + "--x-buildtrees-root=$(Join-Path $vcpkgScratch 'buildtrees')", + "--x-packages-root=$(Join-Path $vcpkgScratch 'packages')" + ) + } + finally { + Pop-Location + } + # buildtrees/packages hold gigabytes of extracted installer scratch; the + # installed prefix is self-contained. Keep downloads so a re-run (or a + # CI downloads cache) skips the oneMKL fetch. + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue ` + (Join-Path $vcpkgScratch "buildtrees"), (Join-Path $vcpkgScratch "packages") } foreach ($path in @($mklInclude, $mklBin) + $mklLibraries) { if (-not (Test-Path -LiteralPath $path)) { diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 639f707c..0b30271b 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -280,3 +280,56 @@ jobs: -Task $task ` -WorkRoot "$env:GITHUB_WORKSPACE/../RandBLAS-windows-ci-$workName" ` -SanitizeAddress:$sanitizeAddress + + # User-fidelity lane: a plain Visual Studio install has no standalone + # vcpkg -- only the manifest-only copy bundled with the C++ workload. A + # classic-mode `vcpkg install` fails there ("this vcpkg distribution does + # not have a classic mode instance") while staying green on CI runners, + # which ship a classic-capable C:\vcpkg. This job hides the runner's + # standalone vcpkg and provisions oneMKL through the bundled copy. The + # vcpkg-installed tree is deliberately NOT cached so every run exercises + # the manifest-mode fetch; only the installer download is cached. + windows-vs-bundled-vcpkg: + name: windows-msvc-mkl-ilp64-vs-bundled-vcpkg + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + + - name: initialize MSVC + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: cache oneMKL installer downloads + uses: actions/cache@v4 + with: + path: ${{ github.workspace }}\..\windows-deps-vsvcpkg\vcpkg-scratch\downloads + key: windows-vsvcpkg-mkl-downloads-1-${{ hashFiles('.github/actions/setup-randblas-deps-windows/setup.ps1') }} + + - name: cache GoogleTest installation + uses: actions/cache@v4 + with: + path: ${{ github.workspace }}\..\windows-deps-vsvcpkg\googletest-install + key: windows-vsvcpkg-googletest-1.17.0-1 + + - name: cache BLAS++ installation + uses: actions/cache@v4 + with: + path: ${{ github.workspace }}\..\windows-deps-vsvcpkg\blaspp-install + key: windows-vsvcpkg-blaspp-windows-portability-ilp64-sequential-3-${{ hashFiles('.github/actions/setup-randblas-deps-windows/setup.ps1') }} + + - name: run native Windows core validation + shell: pwsh + run: | + Remove-Item Env:VCPKG_INSTALLATION_ROOT -ErrorAction SilentlyContinue + Remove-Item Env:VCPKG_ROOT -ErrorAction SilentlyContinue + $bundledVcpkg = Join-Path $env:VSINSTALLDIR "VC\vcpkg\vcpkg.exe" + if (-not (Test-Path $bundledVcpkg)) { + throw "Runner image has no VS-bundled vcpkg at $bundledVcpkg; this lane needs another way to reproduce a manifest-only vcpkg." + } + & "$env:GITHUB_WORKSPACE/.github/scripts/windows/run-ci.ps1" ` + -Task CoreSerial ` + -WorkRoot "$env:GITHUB_WORKSPACE/../RandBLAS-windows-ci-vsvcpkg" ` + -DependencyRoot "$env:GITHUB_WORKSPACE/../windows-deps-vsvcpkg" ` + -SetupDependencies ` + -VcpkgExecutable $bundledVcpkg diff --git a/INSTALL.md b/INSTALL.md index 55cd69e5..44636ed0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -176,7 +176,8 @@ Install the following tools first: * Visual Studio 2022 or Build Tools with **Desktop development with C++**; * Git; * CMake 3.24 or later; -* vcpkg. +* vcpkg (the copy bundled with Visual Studio's C++ workload works; so does a + standalone clone). Create the workspace directories: @@ -187,17 +188,47 @@ mkdir C:\randblas-work\build mkdir C:\randblas-work\install ``` -The following command assumes vcpkg is installed at `C:\vcpkg`. Adjust that -path if necessary. Install the oneMKL port into a dedicated dependency prefix: +Install the oneMKL port into a dedicated dependency prefix. The commands below +use vcpkg's manifest mode, which every vcpkg distribution supports -- the copy +bundled with Visual Studio has no classic-mode instance, so a plain +`vcpkg install intel-mkl:x64-windows` fails there. First write a minimal +manifest (the bundled vcpkg requires the `builtin-baseline` field; the pin +below is vcpkg release 2026.07.29, whose intel-mkl port is 2025.2.0): ```bat -C:\vcpkg\vcpkg.exe install intel-mkl:x64-windows ^ - --x-install-root=C:\randblas-work\vcpkg-installed +mkdir C:\randblas-work\vcpkg-manifest +( +echo { +echo "name": "randblas-windows-deps", +echo "version-string": "1", +echo "builtin-baseline": "9e593bb18ea69cc5095e012465dcd675a822ed0d", +echo "dependencies": [ "intel-mkl" ] +echo } +) > C:\randblas-work\vcpkg-manifest\vcpkg.json +``` + +Then install from the manifest directory. The command below assumes the +Visual Studio bundled vcpkg, which a Native Tools prompt exposes under +`%VSINSTALLDIR%VC\vcpkg`; substitute `C:\vcpkg\vcpkg.exe` (or wherever your +copy lives) if you use a standalone clone. The scratch-directory flags keep +vcpkg's working trees out of the read-only Visual Studio install location: + +```bat +cd C:\randblas-work\vcpkg-manifest +"%VSINSTALLDIR%VC\vcpkg\vcpkg.exe" install ^ + --triplet x64-windows ^ + --x-install-root=C:\randblas-work\vcpkg-installed ^ + --downloads-root=C:\randblas-work\vcpkg-scratch\downloads ^ + --x-buildtrees-root=C:\randblas-work\vcpkg-scratch\buildtrees ^ + --x-packages-root=C:\randblas-work\vcpkg-scratch\packages set "MKLROOT=C:\randblas-work\vcpkg-installed\x64-windows" set "PATH=%MKLROOT%\bin;%PATH%" ``` +After the install succeeds, `C:\randblas-work\vcpkg-scratch` can be deleted; +the installed prefix is self-contained. + Build a shared, sequential, ILP64 BLAS++: ```bat