Skip to content

Minimal Windows CI Build requirements#27

Merged
coatless merged 32 commits into
mainfrom
i21-windows-support
Apr 24, 2026
Merged

Minimal Windows CI Build requirements#27
coatless merged 32 commits into
mainfrom
i21-windows-support

Conversation

@coatless

Copy link
Copy Markdown
Contributor

In this PR, we add in OpenCL headers for windows as well as the prebuilt CLBlast binaries.

By default, the GitHub action runner for Windows does not have a GPU; however, the CPU instruction set should hopefully take. We'll know soon enough. Worst case scenario this is the basis for a community call for help.

To get this to work, we've added:

  • configure.win
  • src/Makevars.win

Then, updated the GitHub actions worker to install OpenCL + CLBlast directly. We may switch this over to chocolate.

coatless and others added 19 commits December 28, 2025 00:26
…ast (though, chocolatey looks better ever second...)
Refactor OpenCL installation steps for Windows and remove verification step.
Updated the R-CMD-check workflow to include Intel OpenCL installation steps for Windows and removed macOS and Ubuntu configurations.
Updated OpenCL environment variables and added debugging step.
Update path format for vcpkg installation on Windows.
Added environment variable registrations for CLBlast.
@coatless

coatless commented Jan 5, 2026

Copy link
Copy Markdown
Contributor Author
RcppBandicoot compiling cleanly on Windows using the OpenCL backend with CLBlast and Intel OpenCL CPU Emulation

Welp, that was fun... I may throw this into a setup-opencl action.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Windows CI build support to RcppBandicoot by implementing a Windows-specific configuration system that detects and configures OpenCL and CLBlast dependencies via environment variables.

  • Introduces configure.win shell script for Windows build configuration
  • Adds templated Makevars.win.in that gets processed by configure.win
  • Updates GitHub Actions workflow to install OpenCL SDK and Intel CPU runtime on Windows

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
configure.win New Windows configuration script that detects OpenCL/CLBlast from environment variables and generates Makevars.win and R/flags.R
src/Makevars.win.in Template file for Windows-specific compiler and linker flags, processed by configure.win
src/Makevars.win Removed static version in favor of generated file from template
src/.gitignore Added Makevars and Makevars.win to ignore list since they are now generated files
.github/workflows/R-CMD-check.yaml Added Windows build steps: vcpkg installation of OpenCL/CLBlast, Intel OpenCL runtime installation, and registry configuration
.gitattributes Ensures shell scripts and configure files use LF line endings for cross-platform compatibility
.Rbuildignore Excludes install.log and .gitattributes from R package builds

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +105 to +106
REG ADD "HKLM\SOFTWARE\Khronos\OpenCL\Vendors" /v $dllPath /t REG_DWORD /d 0 /f
REG ADD "HKLM\SOFTWARE\Wow6432Node\Khronos\OpenCL\Vendors" /v $dllPath /t REG_DWORD /d 0 /f

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential security risk: Registry modifications using REG ADD require elevated privileges and should verify success. These commands modify HKLM (HKEY_LOCAL_MACHINE) which typically requires administrator rights. If the commands fail silently, OpenCL runtime won't be properly registered. Add error checking after each REG ADD command to ensure they succeeded, or wrap them in a try-catch block with appropriate error handling.

Copilot uses AI. Check for mistakes.
Comment thread configure.win Outdated
Comment thread configure.win Outdated
Comment thread configure.win
OPENCL_TARGET_VERSION=300

## Kernel source directory (matches configure.ac logic)
BANDICOOT_KERNELS_DIR=$("${R_HOME}/bin/Rscript" -e 'cat(paste(head(.libPaths(),1), "RcppBandicoot", "include", "bandicoot_bits", "ks", "", sep="/"))')

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple issues with BANDICOOT_KERNELS_DIR path handling: (1) The path uses forward slashes from R (sep="/") but is being used on Windows where backslashes are native; (2) No validation that the Rscript command succeeded or returned a valid path; (3) The path may contain spaces or special characters that will break sed substitution on line 109. Consider: validating the path exists, using normalizePath() in R for proper Windows path handling, and escaping special sed characters before substitution.

Suggested change
BANDICOOT_KERNELS_DIR=$("${R_HOME}/bin/Rscript" -e 'cat(paste(head(.libPaths(),1), "RcppBandicoot", "include", "bandicoot_bits", "ks", "", sep="/"))')
BANDICOOT_KERNELS_DIR=$("${R_HOME}/bin/Rscript" -e 'p <- file.path(head(.libPaths(), 1L), "RcppBandicoot", "include", "bandicoot_bits", "ks"); p <- normalizePath(p, winslash="\\", mustWork=FALSE); if (dir.exists(p)) cat(p)')
if [ $? -ne 0 ] || [ -z "${BANDICOOT_KERNELS_DIR}" ] || [ ! -d "${BANDICOOT_KERNELS_DIR}" ]; then
echo "ERROR: Could not determine BANDICOOT_KERNELS_DIR"
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/R-CMD-check.yaml Outdated
Comment on lines +21 to +22
#- {os: macos-latest, r: 'release'}
#- {os: ubuntu-latest, r: 'release'}

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macOS and Ubuntu build configurations are commented out, leaving only Windows enabled. While the PR description mentions this is for testing Windows builds, this should not be committed to the main branch as it disables CI testing for other platforms. Either re-enable these platforms once Windows testing is complete, or add a clear TODO comment explaining when they will be re-enabled.

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +98
- name: Install Intel CPU Runtime for OpenCL (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# Download
curl -o opencl-installer.exe "${{ env.INTEL_OPENCL_URL }}"

# Extract MSI from the self-extracting exe
$proc = Start-Process "./opencl-installer.exe" "-s -x -f extracted" -NoNewWindow -PassThru
$proc.WaitForExit()

# Install via msiexec
$msi = Get-ChildItem ./extracted/*.msi | Select-Object -First 1
$proc = Start-Process "msiexec" "/i `"$msi`" /qn /l*! install.log" -NoNewWindow -PassThru
$proc.WaitForExit()

if ($proc.ExitCode -ne 0) {
Get-Content install.log
exit $proc.ExitCode
}

Remove-Item -Recurse -Force extracted, opencl-installer.exe

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache step is configured but never checked for a cache hit. The Intel OpenCL Runtime installation (lines 77-98) runs unconditionally, even if the cache was restored. This wastes build time re-installing when the cache is available. Add a condition like "if: runner.os == 'Windows' && steps.cache-opencl-win.outputs.cache-hit != 'true'" to the installation step.

Copilot uses AI. Check for mistakes.
Comment thread .Rbuildignore Outdated
Comment thread configure.win
Comment on lines +81 to +93
if [ "${HAVE_OPENCL}" = "0" ]; then
echo ""
echo "WARNING: No GPU backend detected!"
echo ""
echo "RcppBandicoot requires OpenCL headers to compile on Windows."
echo "Set the following environment variables before building:"
echo ""
echo " OPENCL_CPPFLAGS - Path to OpenCL headers (e.g., -IC:/OpenCL/include)"
echo " OPENCL_LIBS - OpenCL library flags (e.g., -LC:/OpenCL/lib -lOpenCL)"
echo " CLBLAST_CPPFLAGS - Path to CLBlast headers (optional)"
echo " CLBLAST_LIBS - CLBlast library flags (optional)"
echo ""
fi

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script continues to generate R/flags.R even when OpenCL is not detected (HAVE_OPENCL=0). While this may be intentional to allow builds without GPU support, the warning message on lines 82-93 suggests OpenCL is required ("RcppBandicoot requires OpenCL headers to compile on Windows"). This is contradictory. Either the script should exit with an error when HAVE_OPENCL=0, or the warning message should be softened to indicate GPU features will be unavailable but the build can continue.

Copilot uses AI. Check for mistakes.
Comment thread configure.win
Comment on lines +105 to +110
sed -e "s|@BANDICOOT_CXXFLAGS@|${BANDICOOT_CXXFLAGS}|g" \
-e "s|@BANDICOOT_LIBS@|${BANDICOOT_LIBS}|g" \
-e "s|@OPENMP_CXXFLAGS@|${OPENMP_CXXFLAGS}|g" \
-e "s|@OPENCL_TARGET_VERSION@|${OPENCL_TARGET_VERSION}|g" \
-e "s|@BANDICOOT_KERNELS_DIR@|${BANDICOOT_KERNELS_DIR}|g" \
src/Makevars.win.in > src/Makevars.win

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sed substitution does not escape special sed characters that may appear in the variable values. If BANDICOOT_KERNELS_DIR or other paths contain characters like '&', '', or '/', the sed command will fail or produce incorrect output. The '/' is especially problematic since Windows paths converted from backslashes often use it. Consider escaping these characters before substitution or using a different templating approach.

Copilot uses AI. Check for mistakes.
Comment thread src/Makevars.win.in Outdated
coatless and others added 7 commits January 6, 2026 01:08
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Makes the Intel OpenCL runtime install skip on cache hit, pins the cache
key to the installer URL version, drops the debug step, and requires
both OPENCL_CPPFLAGS and OPENCL_LIBS before enabling COOT_USE_OPENCL.
A URL bump now auto-invalidates the cache instead of silently reusing
a stale install because we forgot to edit the key.
The upstream-update workflow renamed kernels/ into a pre-existing ks/
during the 4.0.0 bump, so main has been shipping 3.1.0 kernel sources
under ks/{cuda,opencl}/ alongside 4.0.0 headers, with the real 4.0.0
kernels nested at ks/kernels/{cuda,opencl}/ (tripping CRAN's 100-byte
path limit). Cleans out the stale dirs, promotes the 4.0.0 kernels
to their intended location, and wipes bandicoot_bits/ before each
re-copy so this cannot recur. Also redirects the Windows MSI install
log to RUNNER_TEMP and adds it to .Rbuildignore so it no longer
appears as a top-level non-standard file.
Adds -Wno-reorder and -Wno-address to PKG_CXXFLAGS on Windows to
suppress cosmetic -Wreorder noise in opencl/runtime_bones.hpp and the
-Waddress flood GCC 14 emits against bandicoot's compile-time string
metaprogramming in kernel_gen/array_util.hpp. Both are upstream issues
with no correctness impact.
… suppressions

Applies four local patches to the embedded bandicoot 4.0.0 headers to
eliminate -Wreorder, -Wmaybe-uninitialized, -Waddress, and
-Wunused-local-typedefs warnings at the source, then removes the
-Wno-reorder/-Wno-address flags from Makevars.win.in that CRAN flagged
as non-portable. Candidate upstream fixes:

  opencl/runtime_meat.hpp     reorder val64/val32 mem-initializers to match
                              declaration order (copy + move ctors)
  opencl/runtime_bones.hpp    default-initialize adapt_uword members so the
                              branch not taken by the primary ctor is no
                              longer formally uninitialized
  kernel_gen/array_util.hpp   replace decltype(T::len, void()) SFINAE check
                              with decltype((void)T::len) to avoid GCC 14's
                              -Waddress false-positives
  mtglue_mixed_meat.hpp       drop unused in_eT1/in_eT2 typedefs in
                              mtglue_mixed_times::apply
actions/checkout drops git's 100755 mode on NTFS, so R CMD build warns
"did not have execute permissions: corrected" on every run. A chmod +x
via MSYS bash restores the bit in a form R's tar picks up.
@coatless coatless merged commit 8565503 into main Apr 24, 2026
@coatless coatless deleted the i21-windows-support branch April 24, 2026 06:07
@coatless coatless mentioned this pull request Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants