diff --git a/.github/actions/cvcpkg-deps/action.yml b/.github/actions/cvcpkg-deps/action.yml new file mode 100644 index 0000000..fbf4ece --- /dev/null +++ b/.github/actions/cvcpkg-deps/action.yml @@ -0,0 +1,92 @@ +name: 'Provision dependencies via cvcpkg' +description: | + Installs F2Dock's entire third-party dependency closure from the cvcpkg + catalog into a prefix, and exports that prefix to the calling job. + + This is the ONLY dependency source F2Dock uses. There is deliberately no + apt / Homebrew / vcpkg path and no libcvc-deps release-tarball download: + + * libcvc arrives as a published bundle, so F2Dock never compiles it. + That matters because compiling libcvc is what pulls CGAL and the host + toolchain into F2Dock's build. Homebrew and vcpkg have both moved to + CGAL 6.2, which collides with a `#define error(x)` in libcvc's + reg3data.h, and windows-latest's VS18 v180 crashes CL.exe outright on + cvc.vcxproj. Neither can reach a build that consumes a bundle. + * cmake and ninja come from the catalog too (--include-host-tools), so + the runner image's toolchain versions are never in play. + + The closure is not listed here: it is whatever cvcpkg/recipes/f2dock + declares, resolved transitively. Adding a dependency to the recipe is + enough to make CI install it. + +inputs: + build_type: + description: 'Debug or Release. Selects the matching bundle config.' + required: true + link: + description: 'shared or static.' + required: false + default: 'shared' + prefix: + description: 'Install prefix. Defaults to /deps.' + required: false + default: '' + python-version: + description: 'Python used to run cvcpkg itself.' + required: false + default: '3.11' + +outputs: + prefix: + description: 'Absolute path to the provisioned cvcpkg prefix.' + value: ${{ steps.install.outputs.path }} + +runs: + using: 'composite' + steps: + # Delegate to libcvc-deps' own cvcpkg-install action rather than + # pip-installing cvcpkg: it is NOT on PyPI, so `pip install cvcpkg` fails + # with "No matching distribution found". That action is the supported + # entry point -- it provisions cvcpkg itself and runs + # `cvcpkg install-deps` against the recipe. + # + # include_host_tools brings cmake, ninja and anything else the recipe pins + # from the catalog, so the runner image's toolchain is never in play. + - name: Install dependency closure via cvcpkg + id: install + uses: transfix/libcvc-deps/.github/actions/cvcpkg-install@master + with: + recipe: cvcpkg/recipes/f2dock + build_type: ${{ inputs.build_type }} + link: ${{ inputs.link }} + prefix: ${{ inputs.prefix }} + include_host_tools: 'true' + # The catalog does not yet carry every component for every tuple this + # matrix builds (googletest is published for linux-release and both + # windows configs, but not linux-debug or macOS). Build the gap from + # the pinned recipe source rather than failing a lane for a reason + # F2Dock's own diff cannot cause or fix. + fallback_to_source: 'true' + python_version: ${{ inputs.python-version }} + + - name: Export prefix to the job + shell: bash + env: + PREFIX: ${{ steps.install.outputs.path }} + run: | + set -euo pipefail + if [ -z "$PREFIX" ]; then + echo "::error::cvcpkg-install produced no prefix -- dependency provisioning failed." + exit 1 + fi + echo "CMAKE_PREFIX_PATH=$PREFIX" >> "$GITHUB_ENV" + echo "$PREFIX/bin" >> "$GITHUB_PATH" + case "$RUNNER_OS" in + Linux) + echo "LD_LIBRARY_PATH=$PREFIX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + ;; + macOS) + echo "DYLD_LIBRARY_PATH=$PREFIX/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" >> "$GITHUB_ENV" + ;; + esac + echo "cvcpkg prefix: $PREFIX" diff --git a/.github/actions/fetch-libcvc-deps/action.yml b/.github/actions/fetch-libcvc-deps/action.yml deleted file mode 100644 index 6c311c3..0000000 --- a/.github/actions/fetch-libcvc-deps/action.yml +++ /dev/null @@ -1,168 +0,0 @@ -name: 'Fetch libcvc-deps' -description: | - Attempts to download a pinned libcvc-deps release archive matching - the current platform / build config and extract it to a known - prefix path. The extracted root contains a self-contained CMake - prefix (Boost, HDF5, FFTW, GSL, log4cplus, CGAL, ImageMagick, - Qt 6, VTK 9.5) so workflow steps can skip the slow - VTK-from-source build whenever a matching dep bundle is available. - - Behaviour: - * Computes the URL from inputs (defaults match libcvc-deps's - release.yml stem naming). - * curl -fL the archive into a temp file; falls back to nothing - on any HTTP error (404, network blip, etc.) instead of - failing the build. This keeps the calling workflow robust to - the libcvc-deps release not yet existing for a given version. - * On success, extracts to /libcvc-deps-<...> and emits - that path as the `path` output. - * Caller is expected to gate the from-source VTK build step on - `steps..outputs.path != ''` and to add `path` to - CMAKE_PREFIX_PATH when set. - -inputs: - version: - description: 'libcvc-deps release version (without leading v).' - required: false - default: '1.1.0' - os: - description: 'linux | macos | windows. Defaults to runner.os.' - required: false - default: '' - arch: - description: 'CPU arch (x86_64, arm64). Defaults to runner host arch.' - required: false - default: '' - build_type: - description: 'Debug or Release. Used to pick the matching archive flavor.' - required: true - link: - description: 'shared or static. Picks the -static suffix if static.' - required: false - default: 'shared' - prefix: - description: 'Directory under which to extract the archive.' - required: false - default: '' - -outputs: - path: - description: 'Absolute path to the extracted libcvc-deps root, or empty string if no matching archive was available.' - value: ${{ steps.extract.outputs.path }} - -runs: - using: 'composite' - steps: - - name: 'libcvc-deps: try fetch + extract' - id: extract - shell: bash - env: - LCD_VERSION: ${{ inputs.version }} - LCD_OS: ${{ inputs.os }} - LCD_ARCH: ${{ inputs.arch }} - LCD_BUILD_TYPE: ${{ inputs.build_type }} - LCD_LINK: ${{ inputs.link }} - LCD_PREFIX: ${{ inputs.prefix }} - RUNNER_OS: ${{ runner.os }} - run: | - set -euo pipefail - - # Resolve defaults from the runner context when caller did - # not pin os/arch/prefix. - os="${LCD_OS}" - if [ -z "$os" ]; then - case "$RUNNER_OS" in - Linux) os=linux ;; - macOS) os=macos ;; - Windows) os=windows ;; - *) os=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]') ;; - esac - fi - - arch="${LCD_ARCH}" - if [ -z "$arch" ]; then - if [ "$os" = "windows" ]; then - arch="x86_64" - else - arch=$(uname -m) - fi - fi - - btlc=$(echo "${LCD_BUILD_TYPE}" | tr '[:upper:]' '[:lower:]') - - linksfx="" - if [ "${LCD_LINK}" = "static" ]; then - linksfx="-static" - fi - - # Linux ships .tar.gz; macOS and Windows ship .zip. - if [ "$os" = "linux" ]; then - ext="tar.gz" - else - ext="zip" - fi - - stem="libcvc-deps-${LCD_VERSION}-${os}-${arch}-${btlc}${linksfx}" - url="https://github.com/transfix/libcvc-deps/releases/download/v${LCD_VERSION}/${stem}.${ext}" - - prefix="${LCD_PREFIX}" - if [ -z "$prefix" ]; then - if [ "$os" = "windows" ]; then - prefix="D:/libcvc-deps" - else - prefix="$HOME/libcvc-deps" - fi - fi - mkdir -p "$prefix" - - echo "libcvc-deps: trying $url" - tmp="$(mktemp -d)" - archive="$tmp/${stem}.${ext}" - if ! curl -fL -o "$archive" "$url"; then - echo "libcvc-deps: archive not available (HTTP error); falling back." - echo "path=" >> "$GITHUB_OUTPUT" - exit 0 - fi - - # Sanity-check the archive is non-empty before extracting. - if [ ! -s "$archive" ]; then - echo "libcvc-deps: archive is empty; ignoring." - echo "path=" >> "$GITHUB_OUTPUT" - exit 0 - fi - - case "$ext" in - tar.gz) - tar -xzf "$archive" -C "$prefix" - ;; - zip) - # unzip is preinstalled on all GH runners (incl. Git Bash on Windows). - unzip -q "$archive" -d "$prefix" - ;; - esac - - # Some archives extract as a single root dir matching $stem - # (Linux + macOS via tar/ditto-keepParent); the Windows zip - # is flat from libcvc-deps's `Compress-Archive -Path $dist/*`. - # Normalise both layouts so the output path always points at - # a directory that contains include/, lib/, etc. - if [ -d "$prefix/$stem" ]; then - root="$prefix/$stem" - elif [ -d "$prefix/lib" ] || [ -d "$prefix/include" ]; then - # Flat archive; the prefix itself is the root. - root="$prefix" - else - # Fall back to the largest subdirectory at the prefix. - root="$(find "$prefix" -mindepth 1 -maxdepth 1 -type d | head -n1)" - fi - - if [ -z "$root" ] || [ ! -d "$root" ]; then - echo "libcvc-deps: extraction did not yield a usable root; falling back." - echo "path=" >> "$GITHUB_OUTPUT" - exit 0 - fi - - echo "libcvc-deps: ready at $root" - ls "$root" | head -20 || true - echo "path=$root" >> "$GITHUB_OUTPUT" -# v1.0.2 fetch action default diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 139b9ad..0dce551 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,14 @@ jobs: build_type: Release coverage: false integration: false + # The optional GPL modules (sparsefft3, libicp) are OFF by + # default, so nothing else in this matrix compiles them. One job + # keeps that path from rotting. See THIRD-PARTY.md. + - os: ubuntu-latest + build_type: Release + coverage: false + integration: false + gpl_components: true # macOS - os: macos-latest build_type: Debug @@ -76,9 +84,9 @@ jobs: integration: false runs-on: ${{ matrix.os }} - name: ${{ matrix.os }} / ${{ matrix.build_type }} + name: ${{ matrix.os }} / ${{ matrix.build_type }}${{ matrix.gpl_components && ' / GPL components' || '' }} concurrency: - group: ci-${{ github.ref }}-build-${{ matrix.os }}-${{ matrix.build_type }} + group: ci-${{ github.ref }}-build-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.gpl_components && 'gpl' || 'lgpl' }} cancel-in-progress: true steps: @@ -87,129 +95,23 @@ jobs: with: fetch-depth: 0 - # ── Linux dependencies ── - - name: Install dependencies (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential \ - cmake \ - ninja-build \ - libfftw3-dev \ - libboost-all-dev \ - libhdf5-dev \ - libgsl-dev \ - libcgal-dev - # Coverage tools - if [ "${{ matrix.coverage }}" = "true" ]; then - sudo apt-get install -y --no-install-recommends lcov - fi - - # ── macOS dependencies ── - - name: Install dependencies (macOS) - if: runner.os == 'macOS' - run: | - brew install \ - cmake \ - ninja \ - fftw \ - boost \ - hdf5 \ - gsl \ - cgal - echo "BOOST_ROOT=$(brew --prefix boost)" >> $GITHUB_ENV - echo "CMAKE_PREFIX_PATH=$(brew --prefix boost)" >> $GITHUB_ENV - - # ── libcvc-deps bundle (Linux only) ── - # Pulls a prebuilt dep bundle (FFTW + NFFT3 among others) from - # the libcvc-deps release page. F2Dock's CMakeLists detects NFFT - # via pkg_check_modules; pointing PKG_CONFIG_PATH and - # CMAKE_PREFIX_PATH at the bundle activates F2DOCK_HAVE_NFFT and - # links libnfft3 into f3dock_science_stack. On miss the action - # returns an empty path and the build falls back to the system - # FFTW (no NFFT, same as before). - # - # macOS is intentionally excluded here: the macos-arm64 bundle - # ships its own Boost which shadows brew's and triggers Boost - # multi_array concept-check failures inside libcvc's sources. - # Re-enable once that compatibility is resolved upstream. - - name: Fetch libcvc-deps - if: runner.os == 'Linux' - id: libcvc-deps - uses: ./.github/actions/fetch-libcvc-deps + # ── Dependencies: cvcpkg, and nothing else ── + # No apt, no brew, no vcpkg, no libcvc-deps release tarball. See the + # action's own description for why that is a requirement rather than a + # preference. + - name: Provision dependencies (cvcpkg) + id: deps + uses: ./.github/actions/cvcpkg-deps with: - build_type: Release + build_type: ${{ matrix.build_type }} link: shared - # ── Windows dependencies (vcpkg) ── - # cgal pulls gmp, which fetches gmp-6.3.0.tar.xz from a GNU mirror - # that times out roughly 1-in-3 cold runs. We mitigate with: - # 1) Route vcpkg working dirs to D: so we have ~80 GB free. - # 2) Cache the installed/ + packages/ + archives/ tree so warm - # runs skip the download entirely. - # 3) Wrap vcpkg install in a 5-attempt retry loop with backoff - # so transient network errors don't fail the job. - - name: 'Free disk space and route vcpkg to D: (Windows)' - if: runner.os == 'Windows' - shell: pwsh - run: | - New-Item -ItemType Directory -Force -Path D:\vcpkg-buildtrees | Out-Null - New-Item -ItemType Directory -Force -Path D:\vcpkg-packages | Out-Null - New-Item -ItemType Directory -Force -Path D:\vcpkg-downloads | Out-Null - "VCPKG_DOWNLOADS=D:\vcpkg-downloads" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 - "VCPKG_BUILDTREES=D:\vcpkg-buildtrees" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 - "VCPKG_PACKAGES=D:\vcpkg-packages" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 - - - name: Restore vcpkg cache (Windows) - if: runner.os == 'Windows' - id: vcpkg-cache - uses: actions/cache/restore@v4 - with: - path: | - ${{ env.VCPKG_INSTALLATION_ROOT }}\installed - ${{ env.VCPKG_INSTALLATION_ROOT }}\packages - ~\AppData\Local\vcpkg\archives - key: vcpkg-f2dock-${{ matrix.build_type }}-v1 - restore-keys: | - vcpkg-f2dock-${{ matrix.build_type }}- - - - name: Install dependencies (Windows) - if: runner.os == 'Windows' - shell: pwsh - run: | - $packages = @( - 'fftw3','pthreads', - 'boost-thread','boost-date-time','boost-regex','boost-filesystem', - 'boost-system','boost-chrono','boost-program-options','boost-signals2', - 'boost-format','boost-property-tree','boost-algorithm','boost-asio', - 'boost-any','boost-array','boost-dynamic-bitset','boost-exception', - 'boost-foreach','boost-function','boost-lambda','boost-lexical-cast', - 'boost-multi-array','boost-optional','boost-smart-ptr','boost-tuple', - 'boost-utility','hdf5[cpp]','gsl','cgal' - ) - for ($i = 1; $i -le 5; $i++) { - Write-Host "vcpkg install attempt $i / 5" - vcpkg install @packages --triplet x64-windows ` - --clean-after-build ` - --x-buildtrees-root=D:\vcpkg-buildtrees ` - --x-packages-root=D:\vcpkg-packages - if ($LASTEXITCODE -eq 0) { break } - if ($i -eq 5) { exit $LASTEXITCODE } - $sleep = [Math]::Min(60 * $i, 180) - Write-Host "Retrying after transient failure (sleeping $sleep s)..." - Start-Sleep -Seconds $sleep - } - - - name: Save vcpkg cache (Windows) - if: runner.os == 'Windows' && steps.vcpkg-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: | - ${{ env.VCPKG_INSTALLATION_ROOT }}\installed - ${{ env.VCPKG_INSTALLATION_ROOT }}\packages - ~\AppData\Local\vcpkg\archives - key: vcpkg-f2dock-${{ matrix.build_type }}-v1 + # lcov is a coverage-report tool, not a build dependency, and has no + # cvcpkg bundle. It runs only on the one Linux Debug lane that uploads + # coverage and never participates in compiling or linking F2Dock. + - name: Install lcov (coverage lane only) + if: matrix.coverage + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends lcov # ── Configure (Unix) ── - name: Configure (Unix) @@ -219,30 +121,23 @@ jobs: if [ "${{ matrix.integration }}" = "true" ]; then integration_tests=ON fi - # If libcvc-deps was fetched successfully, expose its - # include/lib/pkgconfig trees so pkg_check_modules(NFFT) and - # any future find_package() calls pick it up. Existing - # CMAKE_PREFIX_PATH (e.g. brew Boost root) is preserved. - deps_path="${{ steps.libcvc-deps.outputs.path }}" - if [ -n "$deps_path" ]; then - export CMAKE_PREFIX_PATH="$deps_path${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}" - export PKG_CONFIG_PATH="$deps_path/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" - # Persist for subsequent build/test steps so the dynamic - # loader can resolve libnfft3.so / libfftw3.so etc. - echo "CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH" >> "$GITHUB_ENV" - echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" >> "$GITHUB_ENV" - if [ "$RUNNER_OS" = "macOS" ]; then - echo "DYLD_LIBRARY_PATH=$deps_path/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" >> "$GITHUB_ENV" - else - echo "LD_LIBRARY_PATH=$deps_path/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" - fi + gpl_components=OFF + if [ "${{ matrix.gpl_components }}" = "true" ]; then + gpl_components=ON fi + # pkg_check_modules(NFFT) reads PKG_CONFIG_PATH; CMAKE_PREFIX_PATH + # and the loader paths are already exported by the cvcpkg-deps + # action. + deps_path="${{ steps.deps.outputs.prefix }}" + export PKG_CONFIG_PATH="$deps_path/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" + echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" >> "$GITHUB_ENV" cmake_args=( -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install -DF2DOCK_BUILD_INTEGRATION_TESTS=${integration_tests} + -DF2DOCK_ENABLE_GPL_COMPONENTS=${gpl_components} ) if [ "${{ matrix.coverage }}" = "true" ]; then # F2Dock's CMakeLists.txt overwrites CMAKE_CXX_FLAGS via set(), @@ -262,10 +157,17 @@ jobs: if [ "${{ matrix.integration }}" = "true" ]; then integration_tests=ON fi + gpl_components=OFF + if [ "${{ matrix.gpl_components }}" = "true" ]; then + gpl_components=ON + fi + # No toolchain file: the cvcpkg prefix is on CMAKE_PREFIX_PATH and + # every windows bundle in it is MSVC-built, which the default + # Visual Studio generator matches. cmake -B build \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ - -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \ -DF2DOCK_BUILD_INTEGRATION_TESTS=${integration_tests} \ + -DF2DOCK_ENABLE_GPL_COMPONENTS=${gpl_components} \ -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install" # ── Build ── @@ -351,7 +253,7 @@ jobs: - name: Upload build artifact uses: actions/upload-artifact@v4 with: - name: build-${{ matrix.os }}-${{ matrix.build_type }} + name: build-${{ matrix.os }}-${{ matrix.build_type }}${{ matrix.gpl_components && '-gpl' || '' }} path: | build/bin/ build/lib/ @@ -376,12 +278,17 @@ jobs: echo "sha=$SHA" >> "$GITHUB_OUTPUT" echo "arch=$ARCH" >> "$GITHUB_OUTPUT" - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential cmake ninja-build libfftw3-dev dpkg-dev \ - libboost-all-dev libhdf5-dev libgsl-dev libcgal-dev + # Dependencies come from cvcpkg only — see .github/actions/cvcpkg-deps. + - name: Provision dependencies (cvcpkg) + uses: ./.github/actions/cvcpkg-deps + with: + build_type: Release + link: shared + + # dpkg-dev is a packaging tool for the .deb step, not a build + # dependency, and has no cvcpkg bundle. + - name: Install dpkg-dev (packaging only) + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends dpkg-dev - name: Configure run: | @@ -459,11 +366,12 @@ jobs: echo "sha=$SHA" >> "$GITHUB_OUTPUT" echo "arch=$ARCH" >> "$GITHUB_OUTPUT" - - name: Install dependencies - run: | - brew install cmake ninja fftw boost hdf5 gsl cgal - echo "BOOST_ROOT=$(brew --prefix boost)" >> $GITHUB_ENV - echo "CMAKE_PREFIX_PATH=$(brew --prefix boost):$(brew --prefix hdf5)" >> $GITHUB_ENV + # Dependencies come from cvcpkg only — see .github/actions/cvcpkg-deps. + - name: Provision dependencies (cvcpkg) + uses: ./.github/actions/cvcpkg-deps + with: + build_type: Release + link: shared - name: Configure run: | @@ -531,70 +439,23 @@ jobs: echo "sha=$SHA" >> "$GITHUB_OUTPUT" echo "arch=x64" >> "$GITHUB_OUTPUT" - - name: 'Free disk space and route vcpkg to D:' - shell: pwsh - run: | - New-Item -ItemType Directory -Force -Path D:\vcpkg-buildtrees | Out-Null - New-Item -ItemType Directory -Force -Path D:\vcpkg-packages | Out-Null - New-Item -ItemType Directory -Force -Path D:\vcpkg-downloads | Out-Null - "VCPKG_DOWNLOADS=D:\vcpkg-downloads" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 - "VCPKG_BUILDTREES=D:\vcpkg-buildtrees" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 - "VCPKG_PACKAGES=D:\vcpkg-packages" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 - - - name: Restore vcpkg cache - id: vcpkg-cache - uses: actions/cache/restore@v4 - with: - path: | - ${{ env.VCPKG_INSTALLATION_ROOT }}\installed - ${{ env.VCPKG_INSTALLATION_ROOT }}\packages - ~\AppData\Local\vcpkg\archives - key: vcpkg-f2dock-package-release-v1 - restore-keys: | - vcpkg-f2dock-package-release- - - - name: Install dependencies - shell: pwsh - run: | - $packages = @( - 'fftw3','pthreads', - 'boost-thread','boost-date-time','boost-regex','boost-filesystem', - 'boost-system','boost-chrono','boost-program-options','boost-signals2', - 'boost-format','boost-property-tree','boost-algorithm','boost-asio', - 'boost-any','boost-array','boost-dynamic-bitset','boost-exception', - 'boost-foreach','boost-function','boost-lambda','boost-lexical-cast', - 'boost-multi-array','boost-optional','boost-smart-ptr','boost-tuple', - 'boost-utility','hdf5[cpp]','gsl','cgal' - ) - for ($i = 1; $i -le 5; $i++) { - Write-Host "vcpkg install attempt $i / 5" - vcpkg install @packages --triplet x64-windows ` - --clean-after-build ` - --x-buildtrees-root=D:\vcpkg-buildtrees ` - --x-packages-root=D:\vcpkg-packages - if ($LASTEXITCODE -eq 0) { break } - if ($i -eq 5) { exit $LASTEXITCODE } - $sleep = [Math]::Min(60 * $i, 180) - Write-Host "Retrying after transient failure (sleeping $sleep s)..." - Start-Sleep -Seconds $sleep - } - - - name: Save vcpkg cache - if: steps.vcpkg-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 + # Dependencies come from cvcpkg only — see .github/actions/cvcpkg-deps. + # This replaces the whole vcpkg apparatus that used to live here: the + # D: drive re-routing for disk space, the cache save/restore, and the + # 5-attempt retry loop around `vcpkg install` that existed because the + # gmp tarball's GNU mirror timed out on roughly one cold run in three. + - name: Provision dependencies (cvcpkg) + id: deps + uses: ./.github/actions/cvcpkg-deps with: - path: | - ${{ env.VCPKG_INSTALLATION_ROOT }}\installed - ${{ env.VCPKG_INSTALLATION_ROOT }}\packages - ~\AppData\Local\vcpkg\archives - key: vcpkg-f2dock-package-release-v1 + build_type: Release + link: shared - name: Configure shell: bash run: | cmake -B build \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \ -DCMAKE_INSTALL_PREFIX=install \ -DF2DOCK_BUILD_TESTS=OFF @@ -606,8 +467,10 @@ jobs: run: | STEM="F2Dock-${{ steps.meta.outputs.version }}-${{ steps.meta.outputs.sha }}-windows-${{ steps.meta.outputs.arch }}" cmake --install build --config Release --prefix staging/F2Dock - cp "$VCPKG_INSTALLATION_ROOT"/installed/x64-windows/bin/*.dll staging/F2Dock/bin/ 2>/dev/null || true - cp README.md staging/F2Dock/ + # Runtime DLLs now come from the cvcpkg prefix (libcvc, FFTW, Boost, + # ... ) rather than a vcpkg installed tree. + cp "${{ steps.deps.outputs.prefix }}"/bin/*.dll staging/F2Dock/bin/ 2>/dev/null || true + cp README.md LICENSE staging/F2Dock/ cd staging 7z a -tzip ../"$STEM.zip" F2Dock/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f54e6b4..4e5d76b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,11 +23,17 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "arch=$ARCH" >> "$GITHUB_OUTPUT" - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential cmake ninja-build libfftw3-dev dpkg-dev + # Dependencies come from cvcpkg only — see .github/actions/cvcpkg-deps. + - name: Provision dependencies (cvcpkg) + id: deps + uses: ./.github/actions/cvcpkg-deps + with: + build_type: Release + link: shared + + # dpkg-dev is a packaging tool for the .deb step, not a build dependency. + - name: Install dpkg-dev (packaging only) + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends dpkg-dev - name: Configure run: | @@ -98,8 +104,13 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "arch=$ARCH" >> "$GITHUB_OUTPUT" - - name: Install dependencies - run: brew install cmake ninja fftw + # Dependencies come from cvcpkg only — see .github/actions/cvcpkg-deps. + - name: Provision dependencies (cvcpkg) + id: deps + uses: ./.github/actions/cvcpkg-deps + with: + build_type: Release + link: shared - name: Configure run: | @@ -161,16 +172,19 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "arch=x64" >> "$GITHUB_OUTPUT" - - name: Install dependencies - shell: bash - run: vcpkg install fftw3:x64-windows pthreads:x64-windows + # Dependencies come from cvcpkg only — see .github/actions/cvcpkg-deps. + - name: Provision dependencies (cvcpkg) + id: deps + uses: ./.github/actions/cvcpkg-deps + with: + build_type: Release + link: shared - name: Configure shell: bash run: | cmake -B build \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \ -DCMAKE_INSTALL_PREFIX=install \ -DF2DOCK_BUILD_TESTS=OFF @@ -182,11 +196,11 @@ jobs: run: | cmake --install build --config Release --prefix staging/F2Dock - # Bundle vcpkg runtime DLLs alongside the executables - cp "$VCPKG_INSTALLATION_ROOT"/installed/x64-windows/bin/*.dll \ + # Bundle the cvcpkg prefix's runtime DLLs alongside the executables + cp "${{ steps.deps.outputs.prefix }}"/bin/*.dll \ staging/F2Dock/bin/ 2>/dev/null || true - cp README.md staging/F2Dock/ + cp README.md LICENSE staging/F2Dock/ cd staging 7z a -tzip ../F2Dock-${{ steps.meta.outputs.version }}-windows-${{ steps.meta.outputs.arch }}.zip F2Dock/ diff --git a/CMakeLists.txt b/CMakeLists.txt index a4bb8ff..db6e525 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,86 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) # include macro for setting up FFTW -include( SetupFFTW ) +# ── FFT provider ───────────────────────────────────────────────────── +# F2Dock is LGPL-2.1-only. FFTW is GPL-2.0-or-later, so linking it makes the +# binary a combined work under the GPL -- that is why the default is NOT FFTW, +# and why this is a licence control rather than a tuning knob. +# +# pocketfft BSD-3-Clause. Default. Verified against FFTW to float64 +# round-off (<= 7.3e-12, N=64..256). ~1.4-1.7x slower on +# throughput at equal core count. +# mkl Intel oneMKL. Proprietary but redistributable, which LGPL +# permits linking; comparable to FFTW. +# cufft NVIDIA cuFFT. Same licensing shape as MKL; needs a GPU. +# fftw GPL-2.0-or-later. OPT-IN, warns loudly, and the binary reports +# itself as GPL at startup. +set(F2DOCK_FFT_PROVIDER "pocketfft" CACHE STRING + "FFT backend: pocketfft (default, BSD-3) | mkl | cufft | fftw (GPL)") +set_property(CACHE F2DOCK_FFT_PROVIDER PROPERTY STRINGS pocketfft mkl cufft fftw) + +string(TOLOWER "${F2DOCK_FFT_PROVIDER}" _f2dock_fft_provider) +set(_f2dock_fft_known pocketfft mkl cufft fftw) +if(NOT _f2dock_fft_provider IN_LIST _f2dock_fft_known) + message(FATAL_ERROR + "F2DOCK_FFT_PROVIDER='${F2DOCK_FFT_PROVIDER}' is not one of: " + "${_f2dock_fft_known}") +endif() + +if(_f2dock_fft_provider STREQUAL "fftw") + # SetupFFTW is only invoked on this path: an LGPL build should not even + # search for a GPL library, let alone link it. + include(SetupFFTW) + SetupFFTW() + message(WARNING + "\n" + " ============================================================\n" + " F2DOCK_FFT_PROVIDER=fftw selects FFTW3, which is\n" + " GPL-2.0-or-later. The F2Dock binary produced by this build\n" + " is a COMBINED WORK COVERED BY THE GNU GPL, not by F2Dock's\n" + " own LGPL-2.1. Do not redistribute it under F2Dock's licence.\n" + "\n" + " Reconfigure with -DF2DOCK_FFT_PROVIDER=pocketfft (BSD-3),\n" + " mkl or cufft to keep the build LGPL.\n" + " ============================================================\n") +endif() + + +# ── Optional GPL components ────────────────────────────────────────── +# F2Dock itself is LGPL-2.1-only (see LICENSE). Two vendored modules are +# not: +# +# inc/fft-utils/sparsefft3*.h, src/fft-utils/sparsefft3*.cpp +# GPL-2.0-or-later (MIT 2000, modified at CVC Lab) -- the sparse +# 3-D FFT used by the `useSparseFFT` parameter. +# inc/libicp/*.h, src/f3dock-icp/{icp,icpPointToPoint,icpPointToPlane, +# matrix}.cpp +# GPL-2.0-or-later (Andreas Geiger, KIT) -- the ICP solver behind +# the `icpRefine` parameter. src/f3dock-icp/kdtree.cpp is AFL-1.1 +# and references a LICENSE file that is not in the tree. +# +# Linking either into F2Dock makes the resulting binary a combined work +# covered by the GPL, which is not what this project distributes. They are +# therefore OFF by default. With the option OFF the sources are not +# compiled and not linked, `useSparseFFT` is forced off in favour of the +# dense FFTW path, and `icpRefine` is a no-op. +# +# Turning this ON produces a GPL-2.0-or-later binary. Do not ship the +# result under F2Dock's own licence. See THIRD-PARTY.md. +option(F2DOCK_ENABLE_GPL_COMPONENTS + "Build the GPL-licensed sparse FFT and libicp modules. The resulting binary is covered by the GPL, not the LGPL." + OFF) -SetupFFTW() +if(F2DOCK_ENABLE_GPL_COMPONENTS) + message(WARNING + "F2DOCK_ENABLE_GPL_COMPONENTS=ON: sparsefft3 and libicp are GPL-2.0-or-later. " + "The F2Dock binary produced by this build is a combined work covered by the " + "GNU GPL v2 or later, not by F2Dock's own LGPL-2.1. See THIRD-PARTY.md.") +else() + message(STATUS + "F2Dock: GPL components disabled (default). Sparse FFT and ICP refinement " + "are unavailable; the dense FFTW transform is used. " + "Re-run with -DF2DOCK_ENABLE_GPL_COMPONENTS=ON to build them.") +endif() option(F2DOCK_ENABLE_F3DOCK_EXPERIMENTAL "Build experimental features ported from F3Dock" ON) option(F2DOCK_ENABLE_F3DOCK_SCIENCE_STACK "Discover optional scientific dependencies for F3Dock ports" ON) @@ -68,133 +145,54 @@ if(F2DOCK_ENABLE_F3DOCK_EXPERIMENTAL) endif() endif() -include(FetchContent) # ── libcvc dependency ──────────────────────────────────────────────── -# Resolution order, falling through on failure: -# 1. find_package(cvc CONFIG) against a pre-installed libcvc on -# CMAKE_PREFIX_PATH (fastest, no download or build). -# 2. Download the prebuilt release tarball matching this platform / -# build type and find_package against the extracted tree. -# 3. FetchContent_Declare(GIT_REPOSITORY ...) and build from source. +# libcvc comes from cvcpkg. Nothing else: no FetchContent source build, no +# release-tarball download, no system package manager. # -# F2Dock links cvc::xmlrpc (XML-RPC support used by F2DockServer). When -# the prebuilt archive does not ship cvc::xmlrpc, or when no prebuilt -# archive has been published for the requested tag at all, strategies -# 1 and 2 are rejected and we fall through to the source build (which -# in turn pulls libcvc-deps for the heavy science stack, including -# NFFT). The source path is the supported way to consume a libcvc -# release that does not yet have platform binaries attached. -set(LIBCVC_TAG "v3.2.1" CACHE STRING "libcvc release tag to consume") -# Package version that libcvc reports via cvcConfigVersion.cmake. The v3.2.1 -# release artifacts still carry the 3.2.0 project version baked at build -# time (the bump shipped in #64 was tagged but not re-versioned in the -# CMake project() call). Keep the find_package() version match aligned -# with what's actually inside the prebuilt archive so the prebuilt path -# does not silently fall through to a from-source build. -set(LIBCVC_VERSION "3.2.0" CACHE STRING "libcvc package version to look up") -set(LIBCVC_ARCHIVE_VERSION "${LIBCVC_VERSION}" - CACHE STRING "Version string embedded in the prebuilt archive filename") -set(LIBCVC_GIT_SHA "08c15b5e244564469a34cddb6cdea00c87add906" - CACHE STRING "libcvc commit SHA used when falling through to source build") -option(LIBCVC_FORCE_SOURCE "Skip prebuilt libcvc and always build from source" OFF) -set(LIBCVC_NEEDS_XMLRPC TRUE) - -# Lean on libcvc for XML-RPC support used by F2DockServer. -set(CVC_BUILD_TESTS OFF CACHE BOOL "" FORCE) -set(CVC_ENABLE_CUDA OFF CACHE BOOL "" FORCE) -set(CVC_ENABLE_COVERAGE OFF CACHE BOOL "" FORCE) -set(CVC_BUILD_VOLROVER3 OFF CACHE BOOL "" FORCE) -set(CVC_USING_XMLRPC ON CACHE BOOL "" FORCE) -# F2Dock does not load MRC volumes. Disable libcvc's IMOD MRC path so the -# source build does not require libiimod (only shipped via libcvc-deps as -# of libcvc 3.2.1). -set(CVC_USING_IMOD_MRC OFF CACHE BOOL "" FORCE) - -function(_libcvc_check_usable out_var) - set(${out_var} FALSE PARENT_SCOPE) - if(NOT cvc_FOUND) - return() - endif() - if(LIBCVC_NEEDS_XMLRPC AND NOT TARGET cvc::xmlrpc) - message(STATUS "libcvc package found (${cvc_VERSION}) but cvc::xmlrpc is missing") - return() - endif() - set(${out_var} TRUE PARENT_SCOPE) -endfunction() - -set(_libcvc_usable FALSE) +# Provision the prefix from F2Dock's own recipe, which declares the closure: +# +# cvcpkg install-deps cvcpkg/recipes/f2dock --prefix deps \ +# --config release --link shared +# cmake -B build -DCMAKE_PREFIX_PATH="$PWD/deps" +# +# That installs libcvc plus everything cvcConfig.cmake find_dependency()s +# (Boost, assimp) and everything F2Dock links directly (FFTW3, pthreads4w on +# Windows) -- ~40 components, all hermetic cvcpkg bundles. +# +# Why the source build is gone rather than kept as a fallback: compiling +# libcvc here is what pulled CGAL and the host toolchain into F2Dock's build, +# and it broke on both non-Linux platforms at once. CGAL 6.2 (which Homebrew +# and vcpkg both ship now) collides with a `#define error(x)` in libcvc's +# reg3data.h, and windows-latest's VS18 v180 crashes CL.exe outright compiling +# cvc.vcxproj. A published bundle compiles none of that. A fallback that only +# runs when the fast path fails is a fallback that only runs on the broken +# platforms, so there is no version of it worth keeping. +set(LIBCVC_VERSION "3.3.0" CACHE STRING "Minimum libcvc version to require") -# 1. Pre-installed package -if(NOT LIBCVC_FORCE_SOURCE) - find_package(cvc ${LIBCVC_VERSION} CONFIG QUIET) - _libcvc_check_usable(_libcvc_usable) - if(_libcvc_usable) - message(STATUS "Using pre-installed libcvc ${cvc_VERSION}") - endif() -endif() +find_package(cvc ${LIBCVC_VERSION} CONFIG QUIET) -# 2. Prebuilt release tarball -if(NOT _libcvc_usable AND NOT LIBCVC_FORCE_SOURCE) - if(WIN32) - set(_libcvc_plat "windows-x86_64") - set(_libcvc_ext "zip") - elseif(APPLE) - set(_libcvc_plat "macos-arm64") - set(_libcvc_ext "zip") - elseif(UNIX) - set(_libcvc_plat "linux-x86_64") - set(_libcvc_ext "tar.gz") - endif() - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(_libcvc_cfg "debug") - else() - set(_libcvc_cfg "release") - endif() - if(DEFINED _libcvc_plat) - set(_libcvc_archive "libcvc-${LIBCVC_ARCHIVE_VERSION}-${_libcvc_plat}-${_libcvc_cfg}.${_libcvc_ext}") - set(_libcvc_url "https://github.com/transfix/libcvc/releases/download/${LIBCVC_TAG}/${_libcvc_archive}") - set(_libcvc_stage "${CMAKE_BINARY_DIR}/libcvc-prebuilt") - set(_libcvc_cfgfile "${_libcvc_stage}/lib/cmake/cvc/cvcConfig.cmake") - if(NOT EXISTS "${_libcvc_cfgfile}") - message(STATUS "Downloading prebuilt libcvc: ${_libcvc_url}") - file(MAKE_DIRECTORY "${_libcvc_stage}") - file(DOWNLOAD "${_libcvc_url}" "${_libcvc_stage}/${_libcvc_archive}" - STATUS _libcvc_dl TLS_VERIFY ON) - list(GET _libcvc_dl 0 _libcvc_dl_code) - if(_libcvc_dl_code EQUAL 0) - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf "${_libcvc_archive}" - WORKING_DIRECTORY "${_libcvc_stage}" - RESULT_VARIABLE _libcvc_extract) - if(NOT _libcvc_extract EQUAL 0) - message(STATUS "Failed to extract ${_libcvc_archive} (exit ${_libcvc_extract})") - endif() - else() - message(STATUS "Prebuilt libcvc download failed: ${_libcvc_dl}") - endif() - endif() - if(EXISTS "${_libcvc_cfgfile}") - list(PREPEND CMAKE_PREFIX_PATH "${_libcvc_stage}") - find_package(cvc ${LIBCVC_VERSION} CONFIG QUIET) - _libcvc_check_usable(_libcvc_usable) - if(_libcvc_usable) - message(STATUS "Using prebuilt libcvc ${cvc_VERSION} from ${_libcvc_url}") - endif() - endif() - endif() +if(NOT cvc_FOUND) + message(FATAL_ERROR + "libcvc ${LIBCVC_VERSION} or newer was not found.\n" + "F2Dock consumes libcvc from cvcpkg. Provision it with:\n" + " cvcpkg install-deps cvcpkg/recipes/f2dock --prefix deps " + "--config release --link shared\n" + "then configure with -DCMAKE_PREFIX_PATH=.") endif() -# 3. Source build (fallback) -if(NOT _libcvc_usable) - message(STATUS "Building libcvc ${LIBCVC_TAG} from source") - FetchContent_Declare( - libcvc - GIT_REPOSITORY https://github.com/transfix/libcvc.git - GIT_TAG ${LIBCVC_GIT_SHA} - ) - FetchContent_MakeAvailable(libcvc) +# F2DockServer is built on libcvc's XML-RPC module. A libcvc bundle published +# without -DCVC_USING_XMLRPC=ON exports no cvc::xmlrpc and ships no +# lib/libxmlrpc archive, only include/xmlrpc/ headers -- fail loudly and name +# the minimum revision rather than letting the link fail later. +if(NOT TARGET cvc::xmlrpc) + message(FATAL_ERROR + "libcvc ${cvc_VERSION} was found but exports no cvc::xmlrpc target.\n" + "F2DockServer requires it. Bundles before libcvc 3.3.0+cvc.4 were " + "published with CVC_USING_XMLRPC off and are unusable here; install " + "3.3.0+cvc.4 or newer.") endif() +message(STATUS "Using libcvc ${cvc_VERSION} from ${cvc_DIR}") #output set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib") set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin") @@ -211,6 +209,14 @@ configure_file( @ONLY) include_directories("${CMAKE_BINARY_DIR}/inc") +# Applied here rather than beside the option() above so the definitions reach +# F2Dock's own targets (src/ and tests/unit/, which compiles IcpRefine.cpp +# directly) without leaking into the libcvc subproject that FetchContent adds +# between the two points. +if(F2DOCK_ENABLE_GPL_COMPONENTS) + add_compile_definitions(F2DOCK_WITH_SPARSEFFT=1 F2DOCK_WITH_LIBICP=1) +endif() + add_subdirectory (src) # ── Testing ── @@ -240,7 +246,7 @@ install(FILES DESTINATION share/F2Dock/data) # Install documentation and examples -install(FILES README.md DESTINATION .) +install(FILES README.md LICENSE DESTINATION .) install(FILES tests/1A2K.inp tests/1ACB.inp tests/1AHW.inp tests/1JZD.inp DESTINATION share/F2Dock/examples) @@ -260,7 +266,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fast Fourier protein-protein docking") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/INSTALL") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") # DEB-specific set(CPACK_DEBIAN_PACKAGE_MAINTAINER "CVC Lab ") diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/LICENSE @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/README.md b/README.md index c3d881a..0e3fd6f 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,65 @@ Developed at the [Computational Visualization Center](https://cvc-lab.github.io) | Dependency | Notes | |---|---| | C++20 compiler | GCC 13+, Clang 16+, or MSVC 19.4+ | -| CMake 3.16+ | | -| FFTW 3 | `libfftw3-dev` (apt), `fftw` (brew), or via vcpkg | -| pthreads | Built-in on Linux/macOS; PThreads4W via vcpkg on Windows | +| Python 3.9+ | Only to run `cvcpkg` itself | +| [cvcpkg](https://cvcpkg.org) | `pip install cvcpkg` | + +Everything else — libcvc, FFTW3, Boost, CGAL, HDF5, ImageMagick, pthreads4w +on Windows, and even CMake and Ninja — is installed from the cvcpkg catalog. +F2Dock does not use apt, Homebrew or vcpkg, and does not build libcvc from +source. ### Build ```bash -cmake -B build -DCMAKE_BUILD_TYPE=Release +pip install cvcpkg +cvcpkg install-deps cvcpkg/recipes/f2dock --prefix deps \ + --config release --link shared --include-host-tools +cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$PWD/deps" cmake --build build --parallel ``` -Executables are placed in `build/bin/`. +Executables are placed in `build/bin/`. The dependency set is whatever +[`cvcpkg/recipes/f2dock/recipe.yaml`](cvcpkg/recipes/f2dock/recipe.yaml) +declares, resolved transitively — the same recipe CI uses, and the same one +that builds and publishes the `f2dock` package. + +### Packaging + +F2Dock ships as a cvcpkg package under the `cvc` organization: + +```bash +cvcpkg install f2dock --prefix /some/prefix --config release --link shared +``` + +#### Optional GPL components + +Two vendored modules are GPL-2.0-or-later while F2Dock itself is LGPL-2.1-only, +so they are **not built by default**: + +| Module | Feature it backs | Upstream | +|---|---|---| +| `sparsefft3` | `useSparseFFT` — sparse 3-D FFT | MIT 2000, modified at CVC Lab | +| `libicp` | `icpRefine` — point-to-plane pose refinement | Andreas Geiger, KIT | + +The default build uses the **dense FFTW** transform instead of the sparse one. +It is slower, and it produces the same scores. `icpRefine` is unavailable. +Both parameters are rejected with an explanatory message rather than silently +ignored, and the binary prints which modules it contains at startup: + +``` +GPL components: sparseFFT=no libicp=no (build licence: LGPL-2.1-only) +FFT path: dense (FFTW) +``` + +To build them: + +```bash +cmake -B build -DCMAKE_BUILD_TYPE=Release -DF2DOCK_ENABLE_GPL_COMPONENTS=ON +``` + +The resulting binary is a combined work covered by the GNU GPL v2 or later, +**not** by F2Dock's LGPL-2.1. See [THIRD-PARTY.md](THIRD-PARTY.md). ### Run @@ -94,6 +141,8 @@ numThreads 4 | `rerank` / `numRerank` | Enable GB-Rerank rescoring and number of top poses to rescore | | `outFile` | Output file for ranked docking poses | | `numThreads` | Number of CPU threads | +| `useSparseFFT` | Sparse FFT instead of dense FFTW. Requires `-DF2DOCK_ENABLE_GPL_COMPONENTS=ON`; see [Optional GPL components](#optional-gpl-components) | +| `icpRefine` | Point-to-plane ICP refinement of the top poses. Requires `-DF2DOCK_ENABLE_GPL_COMPONENTS=ON` | All file paths are relative to the current working directory. See [doc/params/](doc/params/) for the full parameter reference. @@ -160,7 +209,7 @@ src/ GB-rerank/ GB-Rerank standalone rescoring tool hbondFilter/ Hydrogen-bond post-filter math/ Pairing heap, spherical harmonics - libmol/ Molecule I/O (PDB/PQR/F2D) + libmol/ Molecule I/O (PDB/PQR/F2D) -- not built; see THIRD-PARTY.md utils/ Parameter parsing, timers inc/ Headers (mirrors src/ structure) tests/unit/ Google Test suite @@ -175,6 +224,12 @@ doc/ Parameter and dependency documentation ## License [GNU Lesser General Public License v2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) +only. The full text is in [`LICENSE`](LICENSE), and it is what CPack ships in +generated packages. + +Vendored third-party code, its licences, and which of it the default build +compiles are inventoried in [THIRD-PARTY.md](THIRD-PARTY.md). Two entries there +are unresolved and are flagged as such. ## Contact diff --git a/THIRD-PARTY.md b/THIRD-PARTY.md new file mode 100644 index 0000000..aa62705 --- /dev/null +++ b/THIRD-PARTY.md @@ -0,0 +1,294 @@ +# Third-party code in F2Dock + +F2Dock is distributed under the GNU Lesser General Public License, version 2.1 +only — see [`LICENSE`](LICENSE). Most of the tree is that: work by the +Computational Visualization Center at The University of Texas at Austin, +carrying the UT Austin LGPL-2.1 banner. + +The rest is vendored from elsewhere. This file inventories every such tree with +its upstream, author and licence, and says whether the default build compiles +it. + +This is a record of what the source files say. It is not legal advice, and two +entries below (`libmol`, `ElementInformation.h`) are open questions rather than +settled facts. + +## Summary + +| Tree | Files | Licence | In the default build? | +|---|---:|---|---| +| [`inc/libmol`, `src/libmol`](#libmol) | 76 | Boston University notice — **not free, not redistributable** | No (`HAVE_LIBMOL=OFF`) | +| [`inc/fft-utils/sparsefft3*`, `src/fft-utils/sparsefft3*`](#sparsefft3) | 4 | GPL-2.0-or-later | No (`F2DOCK_ENABLE_GPL_COMPONENTS=OFF`) | +| [`inc/libicp`, `src/f3dock-icp`](#libicp) | 8 | GPL-2.0-or-later, plus AFL-1.1 | No (`F2DOCK_ENABLE_GPL_COMPONENTS=OFF`) | +| [`src/f3dock-loop-closure/tripep_closure.*`](#tripeptide-loop-closure) | 2 | **No grant stated** | Yes | +| [`src/f3dock-loop-closure/sturm.h`](#sturm-solver) | 1 | Graphics Gems, grant not restated | Yes | +| [`inc/fast-GB/SSEApproxMath.*`](#sse-approximate-math) | 2 | zlib | Yes | +| [`inc/fft-utils/fftw3.h`](#vendored-fftw3h) | 1 | BSD-2-Clause (header only) | Yes | +| [`inc/PG-range/cuckoo.h`, `src/PG-range/cuckoo.cc`](#cuckoo-hashing) | 2 | Permissive, attribution required | Yes | +| [`inc/PG-range/dsexceptions.h`](#dsexceptionsh) | 1 | **Provenance unknown** | Yes | + +External libraries F2Dock links but does not vendor — FFTW3, pthreads, +libcvc, and the optional Eigen3 / LAPACK / NFFT3 — are not listed here. FFTW3 +is itself GPL-2.0-or-later and is linked dynamically. + +## The GPL build switch + +Two of the vendored trees are GPL-2.0-or-later. Linking either into F2Dock +makes the resulting binary a combined work covered by the GPL, which is not +what this project distributes, so both are behind one option that is **OFF by +default**: + +``` +cmake -S . -B build -DF2DOCK_ENABLE_GPL_COMPONENTS=ON +``` + +With the option OFF the GPL sources are not compiled and not linked, and: + +- `useSparseFFT` defaults to `false` and is refused if a parameter file asks + for it. Transforms go through dense FFTW instead — slower, same scores. +- `icpRefine` is refused if a parameter file asks for it, and + `f2dock::refine_pose_point_to_plane` is a no-op returning `refined == false`. + +With the option ON, CMake emits a warning and the binary reports +`build licence: GPL-2.0-or-later` at startup. Do not ship that binary under +F2Dock's own licence. + +The LGPL core does not `#include` the GPL headers in either configuration. +`inc/fft-utils/sparsefft3-api.h` is the seam: it forwards to the real header +when the module is built and declares the same entry points against an +incomplete type otherwise. + +--- + +## libmol + +- **Path:** `inc/libmol/` (38 headers), `src/libmol/` (38 sources + CMake) +- **Upstream:** Structural Bioinformatics Laboratory, Boston University +- **Contact of record:** Dima Kozakov, Department of Biomedical Engineering, + `midas@bu.edu` +- **Licence:** none of the usual ones. 72 of the 76 files carry the notice at + `inc/libmol/mask.h:3`–`16`; the remaining four (`newgetline.{h,cpp}`, + `test.cpp`, `testHbond.cpp`) have no header, but they are part of the same + vendored tree. + +The notice grants copy-and-modify rights **only** to "US Universities and US +Government supported Research Institutions", **only** for "educational and +research purposes", and states that the software "may not be distributed to +any other institution without express permission from the Structural +Bioinformatics Laboratory and Boston University". + +That is a field-of-use and class-of-licensee restriction. It is incompatible +with the LGPL, incompatible with the GPL, and incompatible with redistribution +generally. + +`HAVE_LIBMOL` is OFF by default (`src/CMakeLists.txt`), so the tree is not +compiled — but it is present in the published source tree, and source +redistribution is exactly what the notice restricts. Neither `CVC-Lab/F2Dock` +nor `CVC-Lab/F3Dock` ships `libmol`, while `CVC-Lab/F3Dock`'s +`src/CMakeLists.txt` still calls `ADD_SUBDIRECTORY (libmol)` for a directory +that is not in its checkout — consistent with the tree having been stripped +before those repositories were published. + +`src/hbondFilter/` is UT Austin's own LGPL code, but it only builds when +`HAVE_LIBMOL` is ON because it consumes libmol. + +**Status: open.** Removing the tree, or obtaining permission for it, is a +decision for UT — not something to settle in a commit. Until it is settled, +this repository should be treated as not redistributable to third parties. + +## sparsefft3 + +- **Path:** `inc/fft-utils/sparsefft3.h`, `inc/fft-utils/sparsefft3-timers.h`, + `src/fft-utils/sparsefft3.cpp`, `src/fft-utils/sparsefft3-plan.cpp` +- **Upstream:** Massachusetts Institute of Technology, 2000 (the sparse 3-D + FFT distributed alongside FFTW); modified at CVC Lab, UT Austin, for FFTW3 +- **Licence:** GPL-2.0-or-later (`inc/fft-utils/sparsefft3.h:5`–`9`) +- **Used by:** the `useSparseFFT` parameter — the sparse forward/backward + transform pair over the frequency maps + +Not built by default. See [the GPL build switch](#the-gpl-build-switch). + +Replacing this with a permissively-licensed sparse transform is the cleanest +long-term fix, since the dense fallback is slower. + +## libicp + +- **Path:** `inc/libicp/` (5 headers), `src/f3dock-icp/` (6 sources) +- **Upstream:** Institute of Measurement and Control Systems, Karlsruhe + Institute of Technology +- **Author:** Andreas Geiger +- **Licence:** GPL-2.0-or-later (`inc/libicp/icp.h:8`–`10`) for `icp`, + `icpPointToPoint`, `icpPointToPlane` and `matrix` +- **Used by:** the `icpRefine` parameter — point-to-plane refinement of the + top-N final poses + +`inc/libicp/kdtree.h` and `src/f3dock-icp/kdtree.cpp` are different: they are +(c) Matthew B. Kennel, Institute for Nonlinear Science, UCSD (2004), under the +**Academic Free License version 1.1**, and the header points at "file LICENSE +with additional provisions in that same file" — **a file that is not in this +tree**. The additional provisions are therefore unknown. AFL-1.1 is also not +GPL-compatible, so `kdtree` sitting inside a GPL library is its own problem. + +`src/f3dock-icp/IcpAligner.cpp` and `inc/f3dock/icp/IcpAligner.h` are UT +Austin's own LGPL wrapper, but they have nothing to wrap without libicp, so +the whole target is gated together. + +Not built by default. See [the GPL build switch](#the-gpl-build-switch). + +## Tripeptide loop closure + +- **Path:** `src/f3dock-loop-closure/tripep_closure.h`, + `src/f3dock-loop-closure/tripep_closure.cpp` +- **Authors:** Chaok Seok, Evangelos Coutsias, Matthew Jacobson, Ken Dill + (UCSF and University of New Mexico), 2003; written by Chaok Seok 2003, ported + to C++ by Nathan Clement 2017 +- **Licence:** **none stated.** The files carry a bare copyright line and no + grant of any kind. + +A bare copyright notice with no licence grants no rights. This is built by +default, via `F2DOCK_ENABLE_F3DOCK_EXPERIMENTAL`. + +**Status: open.** The algorithm is published (Coutsias et al., *J. Comput. +Chem.* 25:510, 2004) and the original Fortran/C is widely redistributed, which +suggests the omission is an oversight rather than a restriction — but that is a +guess, and the fix is to ask the authors for an explicit grant. + +## Sturm solver + +- **Path:** `src/f3dock-loop-closure/sturm.h`, and the `sturm` routines + compiled with the loop-closure module +- **Upstream:** "Using Sturm Sequences to Bracket Real Roots of Polynomial + Equations", D. G. Hook and P. R. McAree, *Graphics Gems*, Academic Press, + 1990, via `acm.org/pubs/tog/GraphicsGems`; modified by Chaok Seok 2003 and + Nathan Clement 2017 +- **Licence:** not restated in this tree. The Graphics Gems series + distributed its code under a blanket permission notice from the publisher, + but that notice does not appear here, and these copies have been modified + twice since. + +Built by default. Left without a header deliberately: stamping F2Dock's own +banner on it would misattribute it. + +## SSE approximate math + +- **Path:** `inc/fast-GB/SSEApproxMath.h`, `src/fast-GB/SSEApproxMath.cpp` +- **Author:** Julien Pommier, 2007 (SIMD `exp`/`log`, after the Intel + Approximate Math library and cephes) +- **Licence:** zlib + +Permissive, attribution preserved in the file, LGPL-compatible. Built by +default. No action needed. + +## Vendored fftw3.h + +- **Path:** `inc/fft-utils/fftw3.h` +- **Authors:** Matteo Frigo and MIT, 2003/2006 +- **Licence:** BSD-2-Clause. The file says so explicitly: the BSD terms apply + "*only* to this header file, and *not* to the other files distributed with + FFTW or derived therefrom". The FFTW library itself is GPL-2.0-or-later and + is linked dynamically. + +Permissive and LGPL-compatible. It does shadow the system `fftw3.h`, which is a +maintenance hazard independent of licensing. + +### The library behind that header is the largest open licensing question + +The *header* is BSD-2. **The library is GPL-2.0-or-later**, and the cvcpkg +recipe agrees (`recipes/fftw3/recipe.yaml`: `license: GPL-2.0-or-later`). +`SetupFFTW()` is called unconditionally at `CMakeLists.txt:32` and `FFTW_LIB` +is linked unconditionally, so **every F2Dock binary is a combined work with +GPL code** — independently of the vendored `sparsefft3` and `libicp` this file +already covers, and not fixed by gating those off. Under the usual reading, +dynamic linking does not change that. + +That makes an FFT-provider swap the load-bearing item for LGPL status, not an +optimisation. The swap itself is small: F2Dock's whole FFTW surface is already +funnelled through the `FFTW_*` macros in `inc/fft-utils/fftwPrecision.h`, and +amounts to `plan_dft_3d` (11 sites), `plan_dft_1d` (5), `plan_dft_r2c_3d` (4), +`plan_dft_c2r_3d` (3), `plan_dft_2d` (2), plus `execute`/`destroy_plan`/ +`malloc`/`free`. No threads, no guru interface, no wisdom, no advanced plans. + +**Measured, so the trade is a number rather than a guess.** PocketFFT +(BSD-3-Clause, the transform NumPy and SciPy use) against FFTW 3, double +precision, 3-D complex-to-complex, plan-once/execute-many, on this workstation: + +| N | FFTW s/exec | PocketFFT s/exec | ratio | max abs diff | +|---|---|---|---|---| +| 64 | 0.00295 | 0.00435 | 1.47x | 5.8e-13 | +| 100 | 0.01507 | 0.02280 | 1.51x | 1.6e-12 | +| **120** (F2Dock's real `numFreq`) | **0.03535** | **0.04640** | **1.31x** | 2.3e-12 | +| 128 | 0.03444 | 0.06339 | 1.84x | 2.2e-12 | +| 200 | 0.17976 | 0.22878 | 1.27x | 4.9e-12 | +| 256 | 0.36164 | 0.59289 | 1.64x | 7.3e-12 | + +Numerically the two agree to float64 round-off, so PocketFFT is a valid drop-in +on correctness. On speed, the honest figure is *throughput at equal core +count*, because F2Dock parallelises over rotations with single-threaded +transforms rather than threading inside one. Measuring W concurrent +single-threaded transforms at N=120: + +| workers | FFTW (xf/s) | PocketFFT (xf/s) | FFTW faster by | +|---|---|---|---| +| 1 | 26.9 | 16.2 | 1.66x | +| 2 | 53.2 | 30.7 | 1.73x | +| 4 | 102.1 | 67.9 | 1.50x | +| 8 | 161.3 | 114.0 | 1.41x | + +So **PocketFFT costs roughly 1.4–1.7x FFT throughput** in F2Dock's actual +architecture. (A single-transform latency comparison flatters PocketFFT — +`nthreads=4` makes one transform 2.6x *faster* than single-threaded FFTW — but +that is spending four cores to do one transform, and F2Dock already spends +those cores on four rotations.) + +Options, in order of licensing cleanliness: + +1. **PocketFFT (BSD-3)** — clean LGPL, header-only, no new bundle needed, at + ~1.4–1.7x FFT cost. +2. **Intel MKL or cuFFT** — proprietary but redistributable, which LGPL-2.1 + permits linking; likely matches or beats FFTW. This is the cvcpkg roadmap's + D9 item. +3. **Buy FFTW's commercial licence from MIT** — no code change at all. + +`sparsefft3` sits on top of whichever base transform is chosen: it is a pruned +FFT exploiting input/output sparsity, and its output is *identical* to the +dense path (verified on 1A2K), so it is recoverable as a pure optimisation +against a permissive base rather than something that must be kept. + +## Cuckoo hashing + +- **Path:** `inc/PG-range/cuckoo.h`, `src/PG-range/cuckoo.cc` +- **Authors:** Rasmus Pagh and Flemming Friche Rodler, BRICS, Department of + Computer Science, University of Aarhus, 2001 +- **Licence:** permissive — use, copy, modify and distribute for any purpose + without fee, provided due acknowledgement to the authors is given and the + permission notice appears in all copies. + +LGPL-compatible. Built by default. The acknowledgement requirement is met by +this file and by the notice in the sources. + +## dsexceptions.h + +- **Path:** `inc/PG-range/dsexceptions.h` +- **Licence:** none stated; nine lines declaring five empty exception classes. + +Arrived with the original 2012 import. The name and content match a +long-circulating teaching header, so it is probably not original to this +project — hence no F2Dock banner on it. Given that it is five empty class +declarations there is likely nothing copyrightable in it either, but the +provenance is genuinely unknown. + +**Status: minor, open.** The cheap fix is to replace it with an equivalent +written here. + +--- + +## Two things this file does not settle + +**`inc/f2dock/ElementInformation.h` provenance.** The same file is +GPL-2.0-or-later in both `CVC-Lab/F2Dock` and `CVC-Lab/F3Dock`, and +LGPL-2.1-only here, with the copyright year changed 2003 → 2011. UT Austin +holds both, so UT can legitimately relicense its own work — but nothing in the +tree or in the git history records that decision. It needs a note from whoever +made it, not a commit from whoever noticed. + +**`libmol`.** See above. It is the sharpest item in this file. diff --git a/cvcpkg/recipes/_common/env-windows.ps1 b/cvcpkg/recipes/_common/env-windows.ps1 new file mode 100644 index 0000000..4bfc636 --- /dev/null +++ b/cvcpkg/recipes/_common/env-windows.ps1 @@ -0,0 +1,456 @@ +# recipes/_common/env-windows.ps1 — shared environment for Windows recipe builds. +# +# Dot-sourced by every build.ps1 on Windows. +$ErrorActionPreference = 'Stop' + +if (-not $env:CVC_BUILD_TYPE) { $env:CVC_BUILD_TYPE = 'Release' } +if (-not $env:CVC_LINK) { $env:CVC_LINK = 'shared' } +if (-not $env:CVC_JOBS) { $env:CVC_JOBS = [Environment]::ProcessorCount } +if (-not $env:CVC_INSTALL_DIR) { throw 'CVC_INSTALL_DIR must be set' } +if (-not $env:CVC_SOURCE_DIR) { throw 'CVC_SOURCE_DIR must be set' } +if (-not $env:CVC_BUILD_DIR) { throw 'CVC_BUILD_DIR must be set' } + +$cmakeBuildType = switch ($env:CVC_BUILD_TYPE.ToLower()) { + 'release' { 'Release' } + 'debug' { 'Debug' } + default { 'Release' } +} + +$buildSharedLibs = if ($env:CVC_LINK -eq 'static') { 'OFF' } else { 'ON' } + +# MSVC runtime library: static link -> /MT (static CRT), shared -> /MD (dynamic CRT) +# The Debug infix goes BEFORE DLL: MultiThreaded[Debug][DLL] +$msvcRuntime = if ($env:CVC_LINK -eq 'static') { + 'MultiThreaded$<$:Debug>' +} else { + 'MultiThreaded$<$:Debug>DLL' +} + +# CMAKE_PREFIX_PATH spans both dependency roots: +# CVC_DEPS_PREFIX — the runtime closure (install prefix; these ship) +# CVC_BUILD_PREFIX — the build closure (build prefix; stripped on install) +# Both are searchable at build time; only the former is part of the deliverable. +# For legacy single-prefix layouts CVC_BUILD_PREFIX is unset or equal, so this +# collapses to the old behaviour. +$cvcRoots = @($env:CVC_DEPS_PREFIX, $env:CVC_BUILD_PREFIX) | + Where-Object { $_ } | Select-Object -Unique +if ($cvcRoots) { + $env:CMAKE_PREFIX_PATH = ($cvcRoots -join ';') +} + +# On Windows we ALWAYS build with MSVC (cl.exe). A prior builder image +# happened to have Strawberry Perl's g++ ahead of cl on PATH, and the +# Ninja generator silently picked it, producing GNU-ar '.a' archives +# with Itanium-mangled symbols that MSVC-mangled downstream consumers +# (protobuf, grpc, etc.) cannot resolve — 100+ "unresolved external" +# link errors. Force cl.exe here so the mangling and archive format +# stay consistent across the whole dep set. +$env:CC = 'cl' +$env:CXX = 'cl' + +# ── Auto-import MSVC developer environment ────────────────────────── +# +# When the builder daemon is launched as a service (or from a plain +# PowerShell prompt) cl.exe / link.exe / rc.exe are NOT on PATH. +# GitHub Actions runs ilammy/msvc-dev-cmd before invoking us; the +# self-hosted builder does not, so do it ourselves here if needed. +function Import-CvcMsvcEnv { + if (Get-Command cl.exe -ErrorAction SilentlyContinue) { return } + + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (-not (Test-Path $vswhere)) { + $vswhere = "$env:ProgramFiles\Microsoft Visual Studio\Installer\vswhere.exe" + } + if (-not (Test-Path $vswhere)) { + throw "cl.exe not on PATH and vswhere.exe not found — install Visual Studio Build Tools or run from a Developer PowerShell." + } + + $vsRoot = & $vswhere -latest -products '*' ` + -requires 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' ` + -property installationPath 2>$null | Select-Object -First 1 + if (-not $vsRoot) { + throw "vswhere.exe found no Visual Studio install with the C++ workload." + } + + $vcvars = Join-Path $vsRoot 'VC\Auxiliary\Build\vcvars64.bat' + if (-not (Test-Path $vcvars)) { + throw "vcvars64.bat not found under $vsRoot" + } + + # Run vcvars64.bat via a small temp .cmd (properly quoted inside the + # batch) and dump the resulting environment. Invoking a single clean + # helper path avoids the fragile inline `cmd /c "..."` quote passing, + # whose handling of embedded quotes differs across PowerShell editions + # (Windows PowerShell 5.1 vs pwsh 7) and can silently mangle the quoted + # vcvars path (which lives under "C:\Program Files (x86)\..."). + $helper = Join-Path ([System.IO.Path]::GetTempPath()) ("cvc-vcvars-{0}.cmd" -f ([guid]::NewGuid().ToString('N'))) + $body = "@echo off`r`ncall `"$vcvars`" >nul 2>&1`r`nset`r`n" + Set-Content -LiteralPath $helper -Value $body -Encoding Ascii + try { + $dump = & cmd.exe /c $helper + } finally { + Remove-Item -LiteralPath $helper -ErrorAction SilentlyContinue + } + foreach ($line in $dump) { + if ($line -match '^([^=]+)=(.*)$') { + $name = $matches[1] + $val = $matches[2] + # Skip a few obviously-per-process env vars we don't want + # to clobber. + if ($name -in @('_', 'PROMPT')) { continue } + [Environment]::SetEnvironmentVariable($name, $val, 'Process') + } + } + if (-not (Get-Command cl.exe -ErrorAction SilentlyContinue)) { + throw "Import-CvcMsvcEnv ran but cl.exe still not on PATH — vcvars64.bat likely failed silently." + } +} +Import-CvcMsvcEnv + +function Invoke-CvcCMakeBuild { + param([string[]]$ExtraArgs = @()) + + # Strip MinGW/MSYS2 dirs from PATH for the duration of the MSVC + # cmake build. CMake's find_path()/find_library() default search + # includes "for each dir in PATH, look in ../include and ../lib" — + # which means if C:\msys64\mingw64\bin is on Machine PATH the + # MinGW-w64 headers (stdio.h with __asm__, __builtin_va_list, etc.) + # get picked up by cl.exe. Those headers are gcc-only and produce + # thousands of parse errors under MSVC. MSVC builds have zero use + # for anything under C:\msys64\, so drop them entirely here. + $origPath = $env:PATH + $filteredPath = ($env:PATH -split ';' | + Where-Object { $_ -notmatch '(?i)\\msys64\\' -and $_ -notmatch '(?i)\\msys32\\' }) -join ';' + $env:PATH = $filteredPath + + try { + $allArgs = @( + '-G', 'Ninja', + '-S', $env:CVC_SOURCE_DIR, + '-B', $env:CVC_BUILD_DIR, + "-DCMAKE_INSTALL_PREFIX=$env:CVC_INSTALL_DIR", + "-DCMAKE_BUILD_TYPE=$cmakeBuildType", + "-DBUILD_SHARED_LIBS=$buildSharedLibs", + "-DCMAKE_MSVC_RUNTIME_LIBRARY=$msvcRuntime", + "-DCMAKE_POLICY_VERSION_MINIMUM=3.5", + '-DCMAKE_C_COMPILER=cl', + '-DCMAKE_CXX_COMPILER=cl' + ) + $ExtraArgs + + & cmake @allArgs + if ($LASTEXITCODE -ne 0) { throw "cmake configure failed" } + + & cmake --build $env:CVC_BUILD_DIR -j $env:CVC_JOBS + if ($LASTEXITCODE -ne 0) { throw "cmake build failed" } + + & cmake --install $env:CVC_BUILD_DIR + if ($LASTEXITCODE -ne 0) { throw "cmake install failed" } + } finally { + $env:PATH = $origPath + } + + Invoke-CvcRewriteInstallPaths +} + +# ── Relocatability helper ─────────────────────────────────────────── +# +# Rewrite absolute $env:CVC_INSTALL_DIR paths inside installed .pc and +# .cmake files so downstream consumers keep working when the package is +# unpacked at a different prefix. .pc files anchor at ${pcfiledir} +# and .cmake files at ${CMAKE_CURRENT_LIST_DIR}; the ../ suffix is +# computed per-file from its depth under $env:CVC_INSTALL_DIR. CMake +# on Windows writes paths with forward slashes into generated files, +# but MSVC/PowerShell APIs return backslash form, so we search for +# both variants. Idempotent. + +function Invoke-CvcRewriteInstallPaths { + $root = $env:CVC_INSTALL_DIR + if (-not $root) { return } + $root = $root.TrimEnd('\','/') + if (-not (Test-Path -LiteralPath $root)) { return } + + $rootBack = $root + $rootFwd = $root -replace '\\','/' + $forms = @($rootBack, $rootFwd) | Sort-Object -Unique + + $files = Get-ChildItem -Path $root -Recurse -File -ErrorAction SilentlyContinue | + Where-Object { $_.Extension -eq '.pc' -or $_.Extension -eq '.cmake' } + $count = 0 + foreach ($f in $files) { + $text = Get-Content -Raw -LiteralPath $f.FullName -ErrorAction SilentlyContinue + if (-not $text) { continue } + $needsRewrite = $false + foreach ($form in $forms) { + if ($text.Contains($form)) { $needsRewrite = $true; break } + } + if (-not $needsRewrite) { continue } + + $dirNorm = ($f.DirectoryName -replace '\\','/') + $rootFwdTrim = $rootFwd + $remainder = $dirNorm.Substring($rootFwdTrim.Length).TrimStart('/') + $depth = if ($remainder) { ($remainder -split '/').Length } else { 0 } + $rel = if ($depth -gt 0) { (('../' * $depth)).TrimEnd('/') } else { '.' } + $anchor = if ($f.Extension -eq '.pc') { '${pcfiledir}' } else { '${CMAKE_CURRENT_LIST_DIR}' } + $prefix = "$anchor/$rel" + + foreach ($form in $forms) { + $text = $text -replace [regex]::Escape($form), $prefix.Replace('$','$$') + } + Set-Content -LiteralPath $f.FullName -Value $text -NoNewline + $count++ + } + if ($count -gt 0) { + Write-Host "── Invoke-CvcRewriteInstallPaths: normalized $count file(s) under $root ──" + } +} + +# ── MSYS2 / MinGW autotools helper ────────────────────────────────── +# +# A handful of dependencies (gmp, mpfr, gsl) have no working native +# MSVC build (upstream autotools is Unix-only, no CMake, GNU-only +# assembly). For those we build via MinGW-w64 gcc + GNU make driven +# through Git Bash — this produces cdecl-C DLLs that MSVC downstream +# consumers can link against through the mingw-generated import +# library. When CVC_LINK=static we use the mingw static archive +# directly; it links cleanly from MSVC for pure-C libraries with no +# libgcc/libstdc++ dependencies (which is the case for gmp/mpfr/gsl). +# +# The builder is expected to have Git Bash on PATH (as env-wasm.ps1 +# already assumes) plus MSYS2 mingw-w64 gcc + make + m4 + libtool. +# See vm-provisioning docs for the required MSYS2 packages. + +function Get-CvcGitBash { + # Return a bash.exe that has (or can find) mingw-w64 gcc + make + + # autotools on its PATH. Priority order: + # 1. CVC_MSYS2_DIR env var (manual override) + # 2. CVC_DEPS_PREFIX\msys2 (installed by the msys2 cvcpkg recipe) + # 3. Well-known MSYS2 system paths (C:\msys64, C:\tools\msys64) + # 4. Git Bash fallback (no MinGW — usable only for non-compile scripts) + $candidates = [System.Collections.Generic.List[string]]@() + if ($env:CVC_MSYS2_DIR) { + $candidates.Add((Join-Path $env:CVC_MSYS2_DIR 'usr\bin\bash.exe')) + } + if ($env:CVC_DEPS_PREFIX) { + $candidates.Add((Join-Path $env:CVC_DEPS_PREFIX 'msys2\usr\bin\bash.exe')) + } + $candidates.AddRange([string[]]@( + 'C:\msys64\usr\bin\bash.exe', + 'C:\tools\msys64\usr\bin\bash.exe', + "$env:ProgramFiles\Git\usr\bin\bash.exe", + "$env:ProgramFiles\Git\bin\bash.exe", + "${env:ProgramFiles(x86)}\Git\usr\bin\bash.exe" + )) + foreach ($candidate in $candidates) { + if (Test-Path $candidate) { return $candidate } + } + $found = Get-Command bash -ErrorAction SilentlyContinue | + Where-Object { $_.Source -notmatch 'System32' } | + Select-Object -First 1 + if ($found) { return $found.Source } + throw 'bash.exe not found (looked under CVC_MSYS2_DIR, CVC_DEPS_PREFIX\msys2\usr\bin\, C:\msys64\usr\bin\, Git\usr\bin\, and PATH)' +} + +function ConvertTo-CvcMsysPath { + # Convert C:\foo\bar → /c/foo/bar for autotools scripts. + param([string]$Path) + if ($Path -match '^([A-Za-z]):(.*)$') { + $drive = $Matches[1].ToLower() + $rest = $Matches[2] -replace '\\','/' + return "/$drive$rest" + } + return ($Path -replace '\\','/') +} + +function Invoke-CvcMsysAutotoolsBuild { + <# + .SYNOPSIS + Configure + make + make install via Git Bash + MinGW gcc. + .PARAMETER ConfigureArgs + Extra arguments to pass to ./configure (beyond --prefix + --host). + .PARAMETER HostTriple + Cross-compilation host triple. Defaults to x86_64-w64-mingw32 + (native MinGW-w64 on Windows). + .PARAMETER Jobs + Override make -j parallelism. Defaults to $env:CVC_JOBS. + Set to 1 for fork-heavy libtool builds that deadlock MSYS2 under + the SYSTEM account (gmp, mpfr, ...). + #> + param( + [string[]]$ConfigureArgs = @(), + [string]$HostTriple = 'x86_64-w64-mingw32', + [int]$Jobs = 0 + ) + if ($Jobs -le 0) { $Jobs = [int]$env:CVC_JOBS } + if ($Jobs -le 0) { $Jobs = 1 } + + $bash = Get-CvcGitBash + $msysPrefix = ConvertTo-CvcMsysPath $env:CVC_INSTALL_DIR + $msysSource = ConvertTo-CvcMsysPath $env:CVC_SOURCE_DIR + $msysDeps = if ($env:CVC_DEPS_PREFIX) { ConvertTo-CvcMsysPath $env:CVC_DEPS_PREFIX } else { '' } + $depsFlag = if ($msysDeps) { "PATH='$msysDeps/bin:'`$PATH" } else { '' } + + # Force the MinGW-w64 64-bit subsystem so that /mingw64/bin + # (gcc, make, libtool, autoconf, m4, ...) is on the shell PATH. + # Without MSYSTEM set, MSYS2's bash defaults to the plain msys + # environment where gcc is not present. MSYS_NO_PATHCONV=1 + # prevents MSYS from mangling Windows-style arguments passed to + # non-MSYS binaries invoked from configure/libtool. + $env:MSYSTEM = 'MINGW64' + $env:MSYS_NO_PATHCONV = '1' + $env:CHERE_INVOKING = '1' + + # Clear MSVC compiler env inherited from the outer PowerShell + # session — env-windows.ps1 sets CC=cl / CXX=cl for Invoke-CvcCMakeBuild, + # but for the autotools path we need bash's PATH to select the + # MinGW-w64 gcc from /mingw64/bin. Autoconf's ./configure would + # otherwise take CC=cl at face value, produce nonsense build-system + # detection, and choke on the first Unix-only linker flag (e.g. + # -lm → LINK: cannot open input file 'm.lib'). + Remove-Item Env:CC -ErrorAction SilentlyContinue + Remove-Item Env:CXX -ErrorAction SilentlyContinue + Remove-Item Env:LD -ErrorAction SilentlyContinue + Remove-Item Env:AR -ErrorAction SilentlyContinue + Remove-Item Env:NM -ErrorAction SilentlyContinue + Remove-Item Env:RANLIB -ErrorAction SilentlyContinue + Remove-Item Env:CFLAGS -ErrorAction SilentlyContinue + Remove-Item Env:CXXFLAGS -ErrorAction SilentlyContinue + Remove-Item Env:LDFLAGS -ErrorAction SilentlyContinue + + $sharedFlags = if ($env:CVC_LINK -eq 'static') { + '--enable-static --disable-shared' + } else { + '--enable-shared --enable-static' + } + + # Pre-flight: verify that required MSYS2/MinGW tools are available. + # These should be provided by their own cvcpkg recipes (m4, autoconf, + # automake, libtool) declared as host_tools in the calling recipe. + # The $depsFlag prepends CVC_DEPS_PREFIX/bin so shim wrappers installed + # by those recipes are found before any system copies. + $probe = & $bash -lc "$depsFlag command -v m4 >/dev/null && command -v libtool >/dev/null && command -v autoconf >/dev/null && command -v automake >/dev/null && command -v make >/dev/null && echo OK" + if ($probe -notmatch 'OK') { + throw 'MSYS2 autotools tools (m4, autoconf, automake, libtool, make) not found. Declare them as host_tools in recipe.yaml.' + } + + # Build one big command line for bash; the caller-provided extras + # win over defaults because they come last. + $extras = ($ConfigureArgs -join ' ') + $cmd = "$depsFlag cd '$msysSource' && ./configure --prefix='$msysPrefix' --host='$HostTriple' $sharedFlags $extras" + Write-Host "cvcpkg: bash -lc `"$cmd`"" + & $bash -lc $cmd + if ($LASTEXITCODE -ne 0) { + $cfgLog = Join-Path $env:CVC_SOURCE_DIR 'config.log' + if (Test-Path $cfgLog) { + Write-Host '--- config.log (last 80 lines) ---' + Get-Content $cfgLog -Tail 80 + } + throw "configure failed" + } + + & $bash -lc "cd '$msysSource' && make -j $Jobs" + if ($LASTEXITCODE -ne 0) { throw "make failed" } + + & $bash -lc "cd '$msysSource' && make install" + if ($LASTEXITCODE -ne 0) { throw "make install failed" } + + # Post-process installed libraries so MSVC downstream can link: + # libfoo.dll.a → foo.lib (import library for shared) + # libfoo.a → foo.lib (static archive; only used when + # CVC_LINK=static — safe for + # pure-C libs without libgcc deps) + # Copies rather than renames so both mingw-style names and + # MSVC-style names are present, and downstream find_library() can + # locate whichever it looks for. + $installLib = Join-Path $env:CVC_INSTALL_DIR 'lib' + if (Test-Path $installLib) { + foreach ($f in Get-ChildItem -Path $installLib -File -Filter 'lib*.dll.a' -ErrorAction SilentlyContinue) { + $stem = $f.Name.Substring(3, $f.Name.Length - 3 - 6) # strip "lib" prefix + ".dll.a" suffix + $dest = Join-Path $installLib ($stem + '.lib') + if (-not (Test-Path $dest)) { Copy-Item -Force $f.FullName $dest } + } + if ($env:CVC_LINK -eq 'static') { + foreach ($f in Get-ChildItem -Path $installLib -File -Filter 'lib*.a' -ErrorAction SilentlyContinue) { + if ($f.Name -like '*.dll.a') { continue } + $stem = $f.Name.Substring(3, $f.Name.Length - 3 - 2) # strip "lib" prefix + ".a" suffix + $dest = Join-Path $installLib ($stem + '.lib') + if (-not (Test-Path $dest)) { Copy-Item -Force $f.FullName $dest } + } + } + } +} + +# ── Meson / MSVC helper ───────────────────────────────────────────── +# +# Build a Meson project with the native MSVC toolchain (cl.exe). This +# produces proper Windows .dll/.lib files (MSVC ABI, not MinGW ABI) so +# consumers built with cl.exe can link directly. +# +# Meson and Ninja must be on PATH. Declare them as host_tools in the +# calling recipe.yaml (depends.host_tools: [meson, ninja]). The PATH +# check below will throw a clear error if they are missing. +# MinGW/MSYS2 directories are stripped from PATH for the duration of +# the build to prevent gcc headers from contaminating the MSVC build. +# +# Usage: +# Invoke-CvcMesonBuild [-MesonArgs ] +function Invoke-CvcMesonBuild { + param([string[]]$MesonArgs = @()) + + # Verify meson and ninja are available; they must come from their + # own cvcpkg recipes declared as host_tools — do NOT install here. + if (-not (Get-Command meson -ErrorAction SilentlyContinue)) { + throw 'meson not found on PATH. Declare "meson" as a host_tool in recipe.yaml.' + } + if (-not (Get-Command ninja -ErrorAction SilentlyContinue)) { + throw 'ninja not found on PATH. Declare "ninja" as a host_tool in recipe.yaml.' + } + + # Strip MinGW/MSYS2 from PATH so meson selects cl.exe, not gcc. + $origPath = $env:PATH + $filteredPath = ($env:PATH -split ';' | + Where-Object { $_ -notmatch '(?i)\\msys64\\' -and $_ -notmatch '(?i)\\msys32\\' }) -join ';' + $env:PATH = $filteredPath + + # Meson defaults: shared/static, release/debug, MSVC runtime. + $defaultLibrary = if ($env:CVC_LINK -eq 'static') { 'static' } else { 'shared' } + $buildtype = $cmakeBuildType.ToLower() + + $pkgConfigPath = if ($env:CVC_DEPS_PREFIX) { + Join-Path $env:CVC_DEPS_PREFIX 'lib\pkgconfig' + } else { '' } + + try { + $setupArgs = @( + 'setup', + "--prefix=$env:CVC_INSTALL_DIR", + "--buildtype=$buildtype", + '--libdir=lib', + "--default-library=$defaultLibrary" + ) + if ($pkgConfigPath -and (Test-Path $pkgConfigPath)) { + $setupArgs += "--pkg-config-path=$pkgConfigPath" + } + if ($env:CVC_DEPS_PREFIX) { + $setupArgs += "-Dcmake_prefix_path=$env:CVC_DEPS_PREFIX" + } + $setupArgs += $MesonArgs + $setupArgs += $env:CVC_BUILD_DIR + $setupArgs += $env:CVC_SOURCE_DIR + + & meson @setupArgs + if ($LASTEXITCODE -ne 0) { throw 'meson setup failed' } + + & meson compile -C $env:CVC_BUILD_DIR -j $env:CVC_JOBS + if ($LASTEXITCODE -ne 0) { throw 'meson compile failed' } + + & meson install -C $env:CVC_BUILD_DIR + if ($LASTEXITCODE -ne 0) { throw 'meson install failed' } + } finally { + $env:PATH = $origPath + } + + Invoke-CvcRewriteInstallPaths +} + +Write-Host "-- env-windows.ps1 loaded --" +Write-Host " BUILD_TYPE=$cmakeBuildType LINK=$env:CVC_LINK JOBS=$env:CVC_JOBS" diff --git a/cvcpkg/recipes/f2dock/build.ps1 b/cvcpkg/recipes/f2dock/build.ps1 new file mode 100644 index 0000000..84d84d3 --- /dev/null +++ b/cvcpkg/recipes/f2dock/build.ps1 @@ -0,0 +1,24 @@ +# cvcpkg/recipes/f2dock/build.ps1 — build F2Dock against an installed libcvc SDK. +# +# Windows goes through _common/env-windows.ps1 rather than a hand-rolled +# `-G Ninja`: it forces CC/CXX=cl, imports the MSVC developer environment, +# strips MinGW/MSYS dirs from PATH, and sets CMAKE_MSVC_RUNTIME_LIBRARY so the +# CRT matches the link mode. That is an ABI requirement -- every cvcpkg windows +# dep bundle is MSVC-built, so a gcc-compiled object could not link them, and +# CMake would otherwise pick C:\mingw64\bin\c++.exe off the runner PATH. +$ErrorActionPreference = 'Stop' + +if (-not $env:CVC_SOURCE_DIR) { throw 'CVC_SOURCE_DIR must be set' } +if (-not $env:CVC_BUILD_DIR) { throw 'CVC_BUILD_DIR must be set' } +if (-not $env:CVC_INSTALL_DIR) { throw 'CVC_INSTALL_DIR must be set' } + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +. "$scriptDir\..\_common\env-windows.ps1" + +# CMAKE_PREFIX_PATH is deliberately NOT passed: env-windows.ps1 sets it to +# CVC_DEPS_PREFIX;CVC_BUILD_PREFIX, and a -D here would override that and drop +# the build prefix. +Invoke-CvcCMakeBuild @( + '-DF2DOCK_BUILD_TESTS=OFF' + '-DF2DOCK_ENABLE_GPL_COMPONENTS=OFF' +) diff --git a/cvcpkg/recipes/f2dock/build.sh b/cvcpkg/recipes/f2dock/build.sh new file mode 100755 index 0000000..c36744a --- /dev/null +++ b/cvcpkg/recipes/f2dock/build.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# cvcpkg/recipes/f2dock/build.sh — build F2Dock against an installed libcvc SDK. +# +# libcvc is NOT rebuilt here: it comes from the deps prefix as a published +# cvcpkg bundle, which is the whole point. Building it from source is what +# dragged CGAL and the platform toolchains into F2Dock's build and broke +# macOS (CGAL 6.2) and Windows (v180 CL.exe) -- see the top-level +# CMakeLists.txt comment on find_package(cvc). +set -euo pipefail + +: "${CVC_SOURCE_DIR:?CVC_SOURCE_DIR must be set}" +: "${CVC_BUILD_DIR:?CVC_BUILD_DIR must be set}" +: "${CVC_INSTALL_DIR:?CVC_INSTALL_DIR must be set}" + +CVC_BUILD_TYPE="${CVC_BUILD_TYPE:-Release}" +CVC_JOBS="${CVC_JOBS:-$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)}" + +case "$(echo "$CVC_BUILD_TYPE" | tr '[:upper:]' '[:lower:]')" in + debug) CMAKE_BUILD_TYPE=Debug ;; + *) CMAKE_BUILD_TYPE=Release ;; +esac + +CMAKE_ARGS=( + -G Ninja + -S "$CVC_SOURCE_DIR" + -B "$CVC_BUILD_DIR" + -DCMAKE_INSTALL_PREFIX="$CVC_INSTALL_DIR" + -DCMAKE_BUILD_TYPE="$CMAKE_BUILD_TYPE" + # Tests pull googletest over the network; a recipe build is not the place + # for that. CI runs the suite separately from a normal source build. + -DF2DOCK_BUILD_TESTS=OFF + # The GPL modules (sparsefft3, libicp) stay OFF so the published bundle is + # unambiguously LGPL-2.1. See THIRD-PARTY.md. + -DF2DOCK_ENABLE_GPL_COMPONENTS=OFF +) + +# The deps prefix carries libcvc (find_package(cvc CONFIG)), FFTW and the +# whole transitive closure libcvc's config file find_dependency()s. +if [[ -n "${CVC_DEPS_PREFIX:-}" ]]; then + CMAKE_ARGS+=("-DCMAKE_PREFIX_PATH=$CVC_DEPS_PREFIX") +fi + +cmake "${CMAKE_ARGS[@]}" +cmake --build "$CVC_BUILD_DIR" -j "$CVC_JOBS" +cmake --install "$CVC_BUILD_DIR" diff --git a/cvcpkg/recipes/f2dock/recipe.yaml b/cvcpkg/recipes/f2dock/recipe.yaml new file mode 100644 index 0000000..0609664 --- /dev/null +++ b/cvcpkg/recipes/f2dock/recipe.yaml @@ -0,0 +1,80 @@ +schema_version: 1 +recipe: + name: f2dock + upstream_version: "2.1.0" + cvc_revision: 1 + maintainer: "cvcpkg group" + maintainer_email: "info@cvcpkg.org" + maintainer_url: "https://cvcpkg.org" + description: "F2Dock — FFT-accelerated rigid-body protein-protein docking (F2 mode) and flexible docking (F3 mode), plus the GB-Rerank Generalized-Born rescoring tool. Built on the libcvc SDK." + homepage: https://github.com/transfix/F2Dock + license: LGPL-2.1-only + tags: [scientific, molecular, docking, bioinformatics, fft] + +provides: ["f2dock"] + +source: + # Co-located with the F2Dock source tree; ../../.. is the repo root. + # `pack-from-prefix` does not consume this, but the schema requires it. + type: vendored + path: ../../.. + +patches: [] + +depends: + # F2Dock's own direct surface is small: FFTW for the correlation core, + # libcvc for volume I/O (src/vol/RAWIV.cpp) and cvc::xmlrpc (F2DockServer), + # and pthreads on Windows. Everything else -- Boost, CGAL, HDF5, + # ImageMagick, assimp, libiimod, grpc -- arrives transitively through + # libcvc's own closure, which cvcpkg resolves; cvcConfig.cmake + # find_dependency()s Boost and assimp unconditionally, so they must be in + # the prefix even though F2Dock never names them. + # + # NOTE: the GPL components (sparsefft3, libicp) are OFF by default -- see + # THIRD-PARTY.md -- so this bundle is unambiguously LGPL-2.1 and needs no + # extra deps for them. + build: + - name: libcvc + - name: fftw3 + # Unit tests only -- but a build dep, not a runtime one, so it is not in + # the runtime list below and does not end up in the published bundle. + - name: googletest + - name: pthreads4w + platforms: [windows] + runtime: + - name: libcvc + - name: fftw3 + - name: pthreads4w + platforms: [windows] + host_tools: + - cmake + - ninja + +build: + matrix: + - platform: linux + script: build.sh + - platform: macos + script: build.sh + env: + MACOSX_DEPLOYMENT_TARGET: "13.0" + - platform: windows + script: build.ps1 + +package: + files: + # F2Dock, GB-Rerank, FilterOutput and F2DockServer. The install() rules + # in the top-level CMakeLists place all four under bin/. + - bin/F2Dock* + - bin/GB-Rerank* + - bin/FilterOutput* + - bin/F2DockServer* + # Rotation matrices and the example inputs the binaries read at runtime. + - share/F2Dock/ + # LICENSE ships beside README.md at the prefix root (see the top-level + # install(FILES README.md LICENSE ...) rule). + - LICENSE + - README.md + +abi: + cxx_std: 20 diff --git a/doc/F3DOCK_MIGRATION_MATRIX.md b/doc/F3DOCK_MIGRATION_MATRIX.md index bd0b5de..e1ddc5e 100644 --- a/doc/F3DOCK_MIGRATION_MATRIX.md +++ b/doc/F3DOCK_MIGRATION_MATRIX.md @@ -46,6 +46,23 @@ Completed capabilities have moved to the [Completed work](#completed-work) secti | NFFT-based acceleration paths | Medium-High (for some workloads) | Medium | Medium | Phase 5 below. Optional, behind an explicit input-file flag; dependency detection already in place, do not hard-require. | | Full F3Dock executable behavior parity | Very High long-term | Very High | Very High | Tracked as the sum of remaining Phase 3 close-out + Phase 4 + deferred items above | +## Licensing constraint on the ICP path + +`libicp` (`inc/libicp/`, `src/f3dock-icp/`) is **GPL-2.0-or-later** while F2Dock +is LGPL-2.1-only, so the whole `f3dock-icp` target -- including UT Austin's own +`IcpAligner` wrapper, which has nothing to wrap without it -- sits behind +`-DF2DOCK_ENABLE_GPL_COMPONENTS=ON` and is **not built by default**. The +`icpRefine` parameter is rejected with an explanation in a default build, and +`f2dock::refine_pose_point_to_plane` compiles to a no-op returning +`refined == false`. Everything described under Phase 2 and Phase 4 task 4 below +is therefore accurate but only reachable in a GPL build. + +The same applies to the sparse FFT (`sparsefft3`) behind `useSparseFFT`; the +default build uses dense FFTW, which produces the same scores. + +Any future F3Dock parity work that reaches for `IcpAligner` needs either that +build flag or a permissively-licensed ICP. See [THIRD-PARTY.md](../THIRD-PARTY.md). + ## Porting Principles 1. Keep legacy-derived code optional and isolated behind build options. diff --git a/inc/f2dock/Docking.h b/inc/f2dock/Docking.h index aed6783..9c51290 100644 --- a/inc/f2dock/Docking.h +++ b/inc/f2dock/Docking.h @@ -40,11 +40,9 @@ #include "math/Gaussian.h" #include "math/Vector.h" #include "math/SmoothingFunction.h" -#include "fft-utils/fftw3.h" #include "fft-utils/fftwPrecision.h" #include "fft-utils/rank-fftw.h" -#include "fft-utils/sparsefft3.h" -#include "fft-utils/sparsefft3-timers.h" +#include "fft-utils/sparsefft3-api.h" #include "fft-utils/fastfft.h" #include "fft-utils/rank-fftw.h" #include "fast-clash/clashFilter.h" diff --git a/inc/f2dock/IcpRefine.h b/inc/f2dock/IcpRefine.h index 21e7f50..ef07bf5 100644 --- a/inc/f2dock/IcpRefine.h +++ b/inc/f2dock/IcpRefine.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include diff --git a/inc/f3dock/DockMode.h b/inc/f3dock/DockMode.h index de13d75..b28878e 100644 --- a/inc/f3dock/DockMode.h +++ b/inc/f3dock/DockMode.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-License-Identifier: LGPL-2.1-only // // DockMode.h // diff --git a/inc/f3dock/domain/DomainGraph.h b/inc/f3dock/domain/DomainGraph.h index 25a13fd..a26abf4 100644 --- a/inc/f3dock/domain/DomainGraph.h +++ b/inc/f3dock/domain/DomainGraph.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include diff --git a/inc/f3dock/domain/DomainPartition.h b/inc/f3dock/domain/DomainPartition.h index 03ef9db..d3a53fc 100644 --- a/inc/f3dock/domain/DomainPartition.h +++ b/inc/f3dock/domain/DomainPartition.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include "f3dock/domain/DomainGraph.h" diff --git a/inc/f3dock/domain/DomainSampler.h b/inc/f3dock/domain/DomainSampler.h index 550abb2..506eb8a 100644 --- a/inc/f3dock/domain/DomainSampler.h +++ b/inc/f3dock/domain/DomainSampler.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include "f3dock/domain/DomainGraph.h" diff --git a/inc/f3dock/domain/DomainSpec.h b/inc/f3dock/domain/DomainSpec.h index d767f8a..bdbd022 100644 --- a/inc/f3dock/domain/DomainSpec.h +++ b/inc/f3dock/domain/DomainSpec.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include "f3dock/domain/DomainGraph.h" diff --git a/inc/f3dock/flex/FlexApply.h b/inc/f3dock/flex/FlexApply.h index 46558d8..8faefbb 100644 --- a/inc/f3dock/flex/FlexApply.h +++ b/inc/f3dock/flex/FlexApply.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include "f3dock/flex/FlexKinematics.h" diff --git a/inc/f3dock/flex/FlexKinematics.h b/inc/f3dock/flex/FlexKinematics.h index 4f5e3f2..c73ec22 100644 --- a/inc/f3dock/flex/FlexKinematics.h +++ b/inc/f3dock/flex/FlexKinematics.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include diff --git a/inc/f3dock/flex/FlexSampler.h b/inc/f3dock/flex/FlexSampler.h index 47188be..8043cad 100644 --- a/inc/f3dock/flex/FlexSampler.h +++ b/inc/f3dock/flex/FlexSampler.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include "f3dock/flex/FlexKinematics.h" diff --git a/inc/f3dock/icp/IcpAligner.h b/inc/f3dock/icp/IcpAligner.h index a1a5237..85bd05d 100644 --- a/inc/f3dock/icp/IcpAligner.h +++ b/inc/f3dock/icp/IcpAligner.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #pragma once #include diff --git a/inc/f3dock/loop_closure/LoopClosureSolver.h b/inc/f3dock/loop_closure/LoopClosureSolver.h index 078726a..7cc8305 100644 --- a/inc/f3dock/loop_closure/LoopClosureSolver.h +++ b/inc/f3dock/loop_closure/LoopClosureSolver.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #ifndef F2DOCK_F3DOCK_LOOP_CLOSURE_SOLVER_H #define F2DOCK_F3DOCK_LOOP_CLOSURE_SOLVER_H diff --git a/inc/f3dock/nfft/FastGaussianSum.h b/inc/f3dock/nfft/FastGaussianSum.h index 8a297e6..6cbf379 100644 --- a/inc/f3dock/nfft/FastGaussianSum.h +++ b/inc/f3dock/nfft/FastGaussianSum.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + // FastGaussianSum.h // // Phase 5 task 2: a thin wrapper that evaluates a 3D Gaussian sum diff --git a/inc/f3dock/util/StringUtil.h b/inc/f3dock/util/StringUtil.h index e822c44..6b1ff88 100644 --- a/inc/f3dock/util/StringUtil.h +++ b/inc/f3dock/util/StringUtil.h @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #ifndef F3DOCK_UTIL_STRING_UTIL_H #define F3DOCK_UTIL_STRING_UTIL_H diff --git a/inc/fft-utils/fastfft.h b/inc/fft-utils/fastfft.h index e8e4943..e6e3609 100644 --- a/inc/fft-utils/fastfft.h +++ b/inc/fft-utils/fastfft.h @@ -1,10 +1,31 @@ +/* + Copyright 2011 The University of Texas at Austin + + Authors: Rezaul Alam Chowdhury + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #ifndef CCV_NDFT_H #define CCV_NDFT_H -#include "fftw3.h" #include "fftwPrecision.h" #include "math/SmoothingFunction.h" -#include "sparsefft3.h" +#include "sparsefft3-api.h" void gridding(int M, double *x, double *y, double *z, float *r, char *type, FFTW_complex *f, double blobbiness, int n, int m, bool smoothSkin, diff --git a/inc/fft-utils/fft_provider.h b/inc/fft-utils/fft_provider.h new file mode 100644 index 0000000..2f7e847 --- /dev/null +++ b/inc/fft-utils/fft_provider.h @@ -0,0 +1,112 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef F2DOCK_FFT_UTILS_FFT_PROVIDER_H +#define F2DOCK_FFT_UTILS_FFT_PROVIDER_H + +/* + Provider-neutral FFT interface. + + WHY THIS EXISTS. FFTW is GPL-2.0-or-later. F2Dock is LGPL-2.1-only, so a + binary linking FFTW is a combined work under the GPL -- which is the whole + reason this seam exists, not performance. Gating the vendored GPL modules + (sparsefft3, libicp) cleaned the source tree but left the linked library + problem untouched. See THIRD-PARTY.md. + + WHY IT IS SMALL. The engine never touched FFTW directly: every call already + went through the FFTW_* macros in fftwPrecision.h. The surface those macros + cover, in the core engine, is only what appears below. `plan_many_dft` and + `execute_dft` are used solely by the (removed) sparsefft3 module, and FFTW's + wisdom API solely by rank-fftw's grid-timing utility, so neither is part of + this interface. + + SEMANTICS. Deliberately FFTW's, so a provider swap is not a behaviour change: + + * Transforms are UNNORMALISED in both directions, exactly like FFTW. A + forward followed by a backward scales by n0*n1*n2. Docking.cpp relies on + this; a provider that silently normalised would change every score. + * sign is FFTW_FORWARD (-1) or FFTW_BACKWARD (+1). + * r2c/c2r use FFTW's half-complex layout: the complex side has + n0 * n1 * (n2/2 + 1) elements. + * A plan captures its buffers at creation. execute() re-runs on those same + buffers, which is how the engine reuses one plan across many rotations. + * flags are advisory. FFTW uses them to pick an algorithm; providers with + no planning stage ignore them. + + ONE DELIBERATE DIVERGENCE: FFTW's c2r destroys its input array. Providers + here are not required to, and PocketFFT does not. Nothing in F2Dock reads a + c2r input after transforming it, so preserving it is strictly safer. +*/ + +#include + +// Precision follows the same switch the rest of the tree uses. +#ifdef FFTW_SINGLE_PRECISION +#define F2DOCK_FFT_REAL float +#else +#define F2DOCK_FFT_REAL double +#endif + +namespace cvc { +namespace fft { + +typedef F2DOCK_FFT_REAL real; +// Interleaved re/im, layout-compatible with fftw_complex and +// std::complex, so buffers pass between providers without a copy. +typedef real complex[2]; + +// Opaque; each provider defines its own. +struct plan_impl; +typedef plan_impl *plan; + +// Sign and flag values are FFTW's, so a build configured against FFTW can map +// straight through without translating them. +enum { + sign_forward = -1, + sign_backward = 1, +}; + +// Aligned allocation suitable for the provider's vectorised kernels. +void *alloc(std::size_t bytes); +void release(void *p); + +plan dft_1d(int n, complex *in, complex *out, int sign, unsigned flags); +plan dft_2d(int n0, int n1, complex *in, complex *out, int sign, + unsigned flags); +plan dft_3d(int n0, int n1, int n2, complex *in, complex *out, int sign, + unsigned flags); +plan dft_r2c_3d(int n0, int n1, int n2, real *in, complex *out, unsigned flags); +plan dft_c2r_3d(int n0, int n1, int n2, complex *in, real *out, unsigned flags); + +void execute(plan p); +void destroy(plan p); + +// Human-readable provider name, for the startup banner so a run log records +// which transform produced its numbers. +const char *provider_name(); + +// True when the linked provider is GPL (i.e. FFTW), so callers can warn. +bool provider_is_gpl(); + +} // namespace fft +} // namespace cvc + +#endif // F2DOCK_FFT_UTILS_FFT_PROVIDER_H diff --git a/inc/fft-utils/fftwPrecision.h b/inc/fft-utils/fftwPrecision.h index e18a633..5881df2 100644 --- a/inc/fft-utils/fftwPrecision.h +++ b/inc/fft-utils/fftwPrecision.h @@ -1,43 +1,133 @@ -#ifndef FFTW_PRECISION_DEFINED -#define FFTW_PRECISION_DEFINED - -#ifdef FFTW_SINGLE_PRECISION -#define FFTW_DATA_TYPE float -#define FFTW_complex fftwf_complex -#define FFTW_plan fftwf_plan -#define FFTW_execute fftwf_execute -#define FFTW_execute_dft fftwf_execute_dft -#define FFTW_free fftwf_free -#define FFTW_malloc fftwf_malloc -#define FFTW_plan_many_dft fftwf_plan_many_dft -#define FFTW_plan_dft_1d fftwf_plan_dft_1d -#define FFTW_plan_dft_2d fftwf_plan_dft_2d -#define FFTW_plan_dft_3d fftwf_plan_dft_3d -#define FFTW_plan_dft_r2c_3d fftwf_plan_dft_r2c_3d -#define FFTW_plan_dft_c2r_3d fftwf_plan_dft_c2r_3d -#define FFTW_destroy_plan fftwf_destroy_plan -#define FFTW_export_wisdom_to_file fftwf_export_wisdom_to_file -#define FFTW_import_wisdom_from_file fftwf_import_wisdom_from_file -#else -#define FFTW_DATA_TYPE double -#define FFTW_complex fftw_complex -#define FFTW_plan fftw_plan -#define FFTW_execute fftw_execute -#define FFTW_execute_dft fftw_execute_dft -#define FFTW_free fftw_free -#define FFTW_malloc fftw_malloc -#define FFTW_plan_many_dft fftw_plan_many_dft -#define FFTW_plan_dft_1d fftw_plan_dft_1d -#define FFTW_plan_dft_2d fftw_plan_dft_2d -#define FFTW_plan_dft_3d fftw_plan_dft_3d -#define FFTW_plan_dft_r2c_3d fftw_plan_dft_r2c_3d -#define FFTW_plan_dft_c2r_3d fftw_plan_dft_c2r_3d -#define FFTW_destroy_plan fftw_destroy_plan -#define FFTW_export_wisdom_to_file fftw_export_wisdom_to_file -#define FFTW_import_wisdom_from_file fftw_import_wisdom_from_file -#endif - -#ifndef OPT_FFTW_SEARCH_TYPE -#define OPT_FFTW_SEARCH_TYPE FFTW_MEASURE -#endif -#endif +/* + Copyright 2011 The University of Texas at Austin + + Authors: Rezaul Alam Chowdhury + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef FFTW_PRECISION_DEFINED +#define FFTW_PRECISION_DEFINED + +/* + The FFTW_* names below are the engine's entire FFT vocabulary -- Docking.cpp + and fastfft.cpp never call a transform library directly. That makes this the + one place a provider is chosen, and why swapping FFTW out costs no churn in + the 8000-line scoring loop. + + F2DOCK_FFT_PROVIDER_FFTW selects FFTW itself and maps these straight onto it, + as before. It is OPT-IN: FFTW is GPL-2.0-or-later, so that build produces a + GPL binary rather than an LGPL-2.1 one. Every other provider goes through + cvc::fft (see fft_provider.h), which deliberately keeps FFTW's semantics -- + unnormalised both ways, half-complex r2c layout, plans that capture their + buffers -- so the choice of provider is not a change in behaviour. +*/ + +#ifdef F2DOCK_FFT_PROVIDER_FFTW + +#include + +#ifdef FFTW_SINGLE_PRECISION +#define FFTW_DATA_TYPE float +#define FFTW_complex fftwf_complex +#define FFTW_plan fftwf_plan +#define FFTW_execute fftwf_execute +#define FFTW_execute_dft fftwf_execute_dft +#define FFTW_free fftwf_free +#define FFTW_malloc fftwf_malloc +#define FFTW_plan_many_dft fftwf_plan_many_dft +#define FFTW_plan_dft_1d fftwf_plan_dft_1d +#define FFTW_plan_dft_2d fftwf_plan_dft_2d +#define FFTW_plan_dft_3d fftwf_plan_dft_3d +#define FFTW_plan_dft_r2c_3d fftwf_plan_dft_r2c_3d +#define FFTW_plan_dft_c2r_3d fftwf_plan_dft_c2r_3d +#define FFTW_destroy_plan fftwf_destroy_plan +#define FFTW_export_wisdom_to_file fftwf_export_wisdom_to_file +#define FFTW_import_wisdom_from_file fftwf_import_wisdom_from_file +#else +#define FFTW_DATA_TYPE double +#define FFTW_complex fftw_complex +#define FFTW_plan fftw_plan +#define FFTW_execute fftw_execute +#define FFTW_execute_dft fftw_execute_dft +#define FFTW_free fftw_free +#define FFTW_malloc fftw_malloc +#define FFTW_plan_many_dft fftw_plan_many_dft +#define FFTW_plan_dft_1d fftw_plan_dft_1d +#define FFTW_plan_dft_2d fftw_plan_dft_2d +#define FFTW_plan_dft_3d fftw_plan_dft_3d +#define FFTW_plan_dft_r2c_3d fftw_plan_dft_r2c_3d +#define FFTW_plan_dft_c2r_3d fftw_plan_dft_c2r_3d +#define FFTW_destroy_plan fftw_destroy_plan +#define FFTW_export_wisdom_to_file fftw_export_wisdom_to_file +#define FFTW_import_wisdom_from_file fftw_import_wisdom_from_file +#endif + +#else /* provider-neutral path: PocketFFT, MKL, cuFFT, ... */ + +#include "fft-utils/fft_provider.h" + +#define FFTW_DATA_TYPE cvc::fft::real +#define FFTW_complex cvc::fft::complex +#define FFTW_plan cvc::fft::plan +#define FFTW_execute cvc::fft::execute +#define FFTW_free cvc::fft::release +#define FFTW_malloc cvc::fft::alloc +#define FFTW_plan_dft_1d cvc::fft::dft_1d +#define FFTW_plan_dft_2d cvc::fft::dft_2d +#define FFTW_plan_dft_3d cvc::fft::dft_3d +#define FFTW_plan_dft_r2c_3d cvc::fft::dft_r2c_3d +#define FFTW_plan_dft_c2r_3d cvc::fft::dft_c2r_3d +#define FFTW_destroy_plan cvc::fft::destroy + +/* + Deliberately NOT defined here: FFTW_plan_many_dft, FFTW_execute_dft and the + wisdom pair. The first two were used only by the GPL sparsefft3 module and + the wisdom pair only by rank-fftw's grid-timing utility, both of which are + FFTW-only. Leaving them undefined means any future use outside an FFTW build + is a compile error naming the symbol, rather than a silent fallback. +*/ + +/* FFTW's own numeric values, so a plan flag or sign written for one provider + means the same thing under another. */ +#ifndef FFTW_FORWARD +#define FFTW_FORWARD (-1) +#endif +#ifndef FFTW_BACKWARD +#define FFTW_BACKWARD (1) +#endif +#ifndef FFTW_MEASURE +#define FFTW_MEASURE (0U) +#endif +#ifndef FFTW_ESTIMATE +#define FFTW_ESTIMATE (1U << 6) +#endif +#ifndef FFTW_PATIENT +#define FFTW_PATIENT (1U << 5) +#endif +/* rank-fftw passes this when timing a size; providers with no planning stage + ignore it, and nothing reads the input array afterwards either way. */ +#ifndef FFTW_DESTROY_INPUT +#define FFTW_DESTROY_INPUT (1U << 0) +#endif + +#endif /* F2DOCK_FFT_PROVIDER_FFTW */ + +#ifndef OPT_FFTW_SEARCH_TYPE +#define OPT_FFTW_SEARCH_TYPE FFTW_MEASURE +#endif +#endif diff --git a/inc/fft-utils/rank-fftw.h b/inc/fft-utils/rank-fftw.h index 7891148..ba662b3 100644 --- a/inc/fft-utils/rank-fftw.h +++ b/inc/fft-utils/rank-fftw.h @@ -1,3 +1,25 @@ +/* + Copyright 2011 The University of Texas at Austin + + Authors: Rezaul Alam Chowdhury + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #ifndef RANKFFTW_H_ #define RANKFFTW_H_ diff --git a/inc/fft-utils/sparsefft3-api.h b/inc/fft-utils/sparsefft3-api.h new file mode 100644 index 0000000..911b630 --- /dev/null +++ b/inc/fft-utils/sparsefft3-api.h @@ -0,0 +1,79 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef F2DOCK_FFT_UTILS_SPARSEFFT3_API_H +#define F2DOCK_FFT_UTILS_SPARSEFFT3_API_H + +/* + Licence seam for the optional sparse 3-D FFT module. + + sparsefft3.h / sparsefft3.cpp / sparsefft3-plan.cpp are GPL-2.0-or-later + (MIT 2000, modified at CVC Lab), while F2Dock as a whole is LGPL-2.1-only. + The LGPL core therefore must not #include the GPL headers directly: they + carry substantive definitions -- structs, enums, macros -- not just + prototypes. + + This header is the seam. Include it instead of sparsefft3.h. When the build + opts in to the GPL components (F2DOCK_ENABLE_GPL_COMPONENTS=ON, which sets + F2DOCK_WITH_SPARSEFFT), it forwards to the real header. Otherwise it + declares the same entry points against an incomplete plan type, which is + all the LGPL core ever needs: the plan is only ever held and passed as an + opaque pointer. + + In the default build the plan pointers are held at NULL (Docking.cpp, at + the `if (!useSparseFFT)` branch) and every call site falls through to the + dense FFTW path, so none of the functions declared below is reached. + src/fft-utils/sparsefft3-stub.cpp satisfies the link. +*/ + +#include "fftw3.h" +#include "fftwPrecision.h" + +#ifdef F2DOCK_WITH_SPARSEFFT + +#include "sparsefft3.h" + +#else + +/* Incomplete type: never dereferenced outside the GPL module. */ +typedef struct sparse3DFFT_plan_opaque_ *sparse3DFFT_plan; + +typedef enum { + SPARSE3DFFT_SPARSEINPUT, + SPARSE3DFFT_SPARSEOUTPUT +} sparse3DFFT_sparsedir; + +typedef int (*sparse3DFFT_nonzero_func)(int x[3], void *data); + +extern sparse3DFFT_plan +sparse3DFFT_create_plan(int nx, int ny, int nz, int dir, int flags, + sparse3DFFT_sparsedir sparsedir, + sparse3DFFT_nonzero_func nonzero, void *nonzero_data, + FFTW_complex *data_in, FFTW_complex *data_out); + +extern void sparse3DFFT_destroy_plan(sparse3DFFT_plan p); + +extern void sparse3DFFT(sparse3DFFT_plan p, FFTW_complex *data_in, + FFTW_complex *data_out); + +#endif /* F2DOCK_WITH_SPARSEFFT */ + +#endif /* F2DOCK_FFT_UTILS_SPARSEFFT3_API_H */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30b5496..d440bed 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,7 +22,13 @@ ENDIF(HAVE_LIBMOL) ADD_SUBDIRECTORY (PG-range) if(F2DOCK_ENABLE_F3DOCK_EXPERIMENTAL) ADD_SUBDIRECTORY (f3dock-loop-closure) +# libicp (src/f3dock-icp/{icp,icpPointToPoint,icpPointToPlane,matrix}.cpp +# and inc/libicp/) is GPL-2.0-or-later, and kdtree.cpp is AFL-1.1. The whole +# target is gated: IcpAligner is a thin wrapper over libicp and has nothing +# to wrap without it. +if(F2DOCK_ENABLE_GPL_COMPONENTS) ADD_SUBDIRECTORY (f3dock-icp) +endif() ADD_SUBDIRECTORY (f3dock-flex) ADD_SUBDIRECTORY (f3dock-domain) ADD_SUBDIRECTORY (f3dock-nfft) diff --git a/src/PostFiltering/FilterOutput.cpp b/src/PostFiltering/FilterOutput.cpp index 7d679d7..5db1bfb 100644 --- a/src/PostFiltering/FilterOutput.cpp +++ b/src/PostFiltering/FilterOutput.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2011 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "fast-clash/clashFilter.h" #include #include diff --git a/src/f2dock/CMakeLists.txt b/src/f2dock/CMakeLists.txt index 51c23a5..3d65c5c 100755 --- a/src/f2dock/CMakeLists.txt +++ b/src/f2dock/CMakeLists.txt @@ -31,7 +31,10 @@ SET(F2DOCK_LINK_LIBS vol fft-utils misc-ident - ${FFTW_LIB} + # No ${FFTW_LIB} here: the transform library is whatever + # F2DOCK_FFT_PROVIDER selected, and fft-utils links it PUBLIC so it + # propagates. Naming FFTW here would drag the GPL library into every + # build regardless of the provider chosen. Threads::Threads ) if(UNIX) diff --git a/src/f2dock/F2Dock.cpp b/src/f2dock/F2Dock.cpp index 99ed7a1..934aa5a 100644 --- a/src/f2dock/F2Dock.cpp +++ b/src/f2dock/F2Dock.cpp @@ -1343,11 +1343,21 @@ bool setParamFromFile(PARAMS_IN *p, char *paramFile) { return false; } } else if (strcasecmp(key, "useSparseFFT") == 0) { - if (strcasecmp(val, "true") == 0) + if (strcasecmp(val, "true") == 0) { +#ifdef F2DOCK_WITH_SPARSEFFT p->useSparseFFT = true; - else if (strcasecmp(val, "false") == 0) +#else + printf("Error: useSparseFFT=true requested but this F2Dock build " + "was configured without the sparse 3-D FFT module, which " + "is GPL-licensed (F2DOCK_WITH_SPARSEFFT undefined). " + "Rebuild with -DF2DOCK_ENABLE_GPL_COMPONENTS=ON -- which " + "produces a GPL binary -- or set useSparseFFT=false to use " + "the dense FFTW transform.\n"); + return false; +#endif + } else if (strcasecmp(val, "false") == 0) { p->useSparseFFT = false; - else { + } else { printf("Error: %s must be a Boolean value!\n", key); return false; } @@ -1670,11 +1680,20 @@ bool setParamFromFile(PARAMS_IN *p, char *paramFile) { p->domainMaxStates = ival; } else if (strcasecmp(key, "icpRefine") == 0) { - if (strcasecmp(val, "true") == 0) + if (strcasecmp(val, "true") == 0) { +#ifdef F2DOCK_WITH_LIBICP p->icpRefineEnabled = true; - else if (strcasecmp(val, "false") == 0) +#else + printf("Error: icpRefine=true requested but this F2Dock build was " + "configured without libicp, which is GPL-licensed " + "(F2DOCK_WITH_LIBICP undefined). Rebuild with " + "-DF2DOCK_ENABLE_GPL_COMPONENTS=ON -- which produces a GPL " + "binary -- or set icpRefine=false.\n"); + return false; +#endif + } else if (strcasecmp(val, "false") == 0) { p->icpRefineEnabled = false; - else { + } else { printf("Error: %s must be a Boolean value!\n", key); return false; } @@ -2294,8 +2313,15 @@ int main(int argc, char *argv[]) { // unless either explicitly set or randomRotate is 'true' ) pr.initRot.reset(); - pr.useSparseFFT = - true; // speed up FFT using the sparsity of input and/or output matrices + // Speed up the FFT using the sparsity of the input and/or output matrices. + // The sparse transform is GPL-licensed and optional (see LICENSE and + // THIRD-PARTY.md); when it is not built the default is the dense FFTW + // path, which is slower but produces the same scores. +#ifdef F2DOCK_WITH_SPARSEFFT + pr.useSparseFFT = true; +#else + pr.useSparseFFT = false; +#endif pr.narrowBand = true; // if 'true', consider only the solutions within a // narrow band in the output grid @@ -2628,6 +2654,25 @@ int main(int argc, char *argv[]) { pr.nfftAccelerate ? "on" : "off", nfft_available ? "yes" : "no", nfft_active ? "yes" : "no"); + // Same three axes for the two optional GPL modules, so a run log records + // which FFT path actually executed and whether this binary is the plain + // LGPL build or the combined GPL one. See THIRD-PARTY.md. +#ifdef F2DOCK_WITH_SPARSEFFT + const bool sparsefft_available = true; +#else + const bool sparsefft_available = false; +#endif +#ifdef F2DOCK_WITH_LIBICP + const bool libicp_available = true; +#else + const bool libicp_available = false; +#endif + printf("GPL components: sparseFFT=%s libicp=%s (build licence: %s)\n", + sparsefft_available ? "yes" : "no", libicp_available ? "yes" : "no", + (sparsefft_available || libicp_available) ? "GPL-2.0-or-later" + : "LGPL-2.1-only"); + printf("FFT path: %s\n", pr.useSparseFFT ? "sparse" : "dense (FFTW)"); + // F3Dock mode: enumerate hinge/shear flex states up front so the FFT // scoring loop can iterate `pr.flexStates` unconditionally. With no // sweeps configured this is a single identity state, keeping F3Dock diff --git a/src/f2dock/IcpRefine.cpp b/src/f2dock/IcpRefine.cpp index bbfa015..543a33a 100644 --- a/src/f2dock/IcpRefine.cpp +++ b/src/f2dock/IcpRefine.cpp @@ -1,5 +1,28 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f2dock/IcpRefine.h" +#ifdef F2DOCK_WITH_LIBICP + #include #include @@ -94,3 +117,39 @@ IcpRefineResult refine_pose_point_to_plane( } } // namespace f2dock + +#else /* !F2DOCK_WITH_LIBICP */ + +// The ICP solver behind this pass (inc/libicp, src/f3dock-icp) is +// GPL-2.0-or-later and is not built unless F2DOCK_ENABLE_GPL_COMPONENTS is +// ON. Without it the refinement is a no-op that leaves the pose untouched +// and reports refined == false, which is exactly what the caller in +// Docking.cpp already does when ICP fails to converge. F2Dock.cpp refuses +// the `icpRefine` parameter in this configuration, so this path is only +// reached by a direct caller. + +namespace f2dock { + +IcpRefineResult refine_pose_point_to_plane( + const double *receptor_x, const double *receptor_y, + const double *receptor_z, int n_receptor, const double *ligand_x, + const double *ligand_y, const double *ligand_z, int n_ligand, + std::array, 3> *rotation, + std::array *translation, const IcpRefineConfig &config) { + (void)receptor_x; + (void)receptor_y; + (void)receptor_z; + (void)n_receptor; + (void)ligand_x; + (void)ligand_y; + (void)ligand_z; + (void)n_ligand; + (void)rotation; + (void)translation; + (void)config; + return IcpRefineResult{}; +} + +} // namespace f2dock + +#endif /* F2DOCK_WITH_LIBICP */ diff --git a/src/f3dock-domain/DomainGraph.cpp b/src/f3dock-domain/DomainGraph.cpp index 1bfcfa6..529bcde 100644 --- a/src/f3dock-domain/DomainGraph.cpp +++ b/src/f3dock-domain/DomainGraph.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/domain/DomainGraph.h" namespace { diff --git a/src/f3dock-domain/DomainPartition.cpp b/src/f3dock-domain/DomainPartition.cpp index 47d654f..ce538e6 100644 --- a/src/f3dock-domain/DomainPartition.cpp +++ b/src/f3dock-domain/DomainPartition.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/domain/DomainPartition.h" #include diff --git a/src/f3dock-domain/DomainSampler.cpp b/src/f3dock-domain/DomainSampler.cpp index 3787ba4..85f72ab 100644 --- a/src/f3dock-domain/DomainSampler.cpp +++ b/src/f3dock-domain/DomainSampler.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/domain/DomainSampler.h" #include "f3dock/util/StringUtil.h" diff --git a/src/f3dock-domain/DomainSpec.cpp b/src/f3dock-domain/DomainSpec.cpp index d87fce2..be4ba90 100644 --- a/src/f3dock-domain/DomainSpec.cpp +++ b/src/f3dock-domain/DomainSpec.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/domain/DomainSpec.h" #include "f3dock/domain/DomainSampler.h" diff --git a/src/f3dock-flex/FlexApply.cpp b/src/f3dock-flex/FlexApply.cpp index c87eecd..8c3487d 100644 --- a/src/f3dock-flex/FlexApply.cpp +++ b/src/f3dock-flex/FlexApply.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/flex/FlexApply.h" #include diff --git a/src/f3dock-flex/FlexKinematics.cpp b/src/f3dock-flex/FlexKinematics.cpp index 7bfef39..4772cd4 100644 --- a/src/f3dock-flex/FlexKinematics.cpp +++ b/src/f3dock-flex/FlexKinematics.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/flex/FlexKinematics.h" #include diff --git a/src/f3dock-flex/FlexSampler.cpp b/src/f3dock-flex/FlexSampler.cpp index 1431374..298abe9 100644 --- a/src/f3dock-flex/FlexSampler.cpp +++ b/src/f3dock-flex/FlexSampler.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/flex/FlexSampler.h" #include "f3dock/util/StringUtil.h" diff --git a/src/f3dock-icp/IcpAligner.cpp b/src/f3dock-icp/IcpAligner.cpp index ed48ba1..01d7519 100644 --- a/src/f3dock-icp/IcpAligner.cpp +++ b/src/f3dock-icp/IcpAligner.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/icp/IcpAligner.h" #include diff --git a/src/f3dock-loop-closure/LoopClosureSolver.cpp b/src/f3dock-loop-closure/LoopClosureSolver.cpp index 7e1a06a..df18c01 100644 --- a/src/f3dock-loop-closure/LoopClosureSolver.cpp +++ b/src/f3dock-loop-closure/LoopClosureSolver.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "f3dock/loop_closure/LoopClosureSolver.h" #include diff --git a/src/f3dock-nfft/FastGaussianSum.cpp b/src/f3dock-nfft/FastGaussianSum.cpp index 12a0ad4..1a683f7 100644 --- a/src/f3dock-nfft/FastGaussianSum.cpp +++ b/src/f3dock-nfft/FastGaussianSum.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + // FastGaussianSum.cpp -- implementation. See FastGaussianSum.h for the // contract. The NFFT3 fastsum path is currently a no-op stub gated by // F2DOCK_HAVE_NFFT_WIRED so that the library compiles uniformly on every diff --git a/src/fft-utils/CMakeLists.txt b/src/fft-utils/CMakeLists.txt index 04d7208..f0a1e62 100755 --- a/src/fft-utils/CMakeLists.txt +++ b/src/fft-utils/CMakeLists.txt @@ -1,6 +1,36 @@ cmake_minimum_required(VERSION 3.16) -FILE(GLOB SOURCE_FILES *.cpp) +# sparsefft3.cpp / sparsefft3-plan.cpp are GPL-2.0-or-later; the rest of +# this directory is LGPL-2.1. Keep them out of the glob so the default build +# links no GPL object, and swap in the LGPL stub that satisfies the three +# entry points instead. See inc/fft-utils/sparsefft3-api.h. +SET(SOURCE_FILES + fastfft.cpp + # rank-fftw times candidate grid sizes to build fftw-rank.txt, and + # computeEffGrid() is called from the engine, so it builds for every + # provider -- which is also more correct: the efficient sizes should + # reflect the transform actually in use. Its only FFTW-specific calls are + # the wisdom pair, already dead behind #ifdef SAVE_WISDOM_TO_FILE (never + # defined anywhere in the tree). + rank-fftw.cpp +) + +# Exactly one provider backend is compiled. +if(_f2dock_fft_provider STREQUAL "fftw") + LIST(APPEND SOURCE_FILES fft_fftw.cpp) +elseif(_f2dock_fft_provider STREQUAL "pocketfft") + LIST(APPEND SOURCE_FILES fft_pocketfft.cpp) +elseif(_f2dock_fft_provider STREQUAL "mkl") + LIST(APPEND SOURCE_FILES fft_mkl.cpp) +elseif(_f2dock_fft_provider STREQUAL "cufft") + LIST(APPEND SOURCE_FILES fft_cufft.cpp) +endif() +if(F2DOCK_ENABLE_GPL_COMPONENTS) + LIST(APPEND SOURCE_FILES sparsefft3.cpp sparsefft3-plan.cpp) +else() + LIST(APPEND SOURCE_FILES sparsefft3-stub.cpp) +endif() + FILE(GLOB INCLUDE_FILES ../../inc/fft-utils/*.[Hh]) SOURCE_GROUP("Source Files" FILES ${SOURCE_FILES}) @@ -12,3 +42,22 @@ INCLUDE_DIRECTORIES( ) ADD_LIBRARY (fft-utils STATIC ${SOURCE_FILES} ${INCLUDE_FILES}) + +if(_f2dock_fft_provider STREQUAL "fftw") + target_compile_definitions(fft-utils PUBLIC F2DOCK_FFT_PROVIDER_FFTW=1) + target_link_libraries(fft-utils PUBLIC ${FFTW_LIB}) +elseif(_f2dock_fft_provider STREQUAL "pocketfft") + # Header-only, from the cvcpkg pocketfft bundle. find_path rather than + # find_package: upstream ships no CMake config, only the header. + find_path(POCKETFFT_INCLUDE_DIR pocketfft_hdronly.h REQUIRED) + target_include_directories(fft-utils PUBLIC ${POCKETFFT_INCLUDE_DIR}) + message(STATUS "F2Dock: FFT provider = PocketFFT (BSD-3) from ${POCKETFFT_INCLUDE_DIR}") +elseif(_f2dock_fft_provider STREQUAL "mkl") + find_package(MKL CONFIG REQUIRED) + target_link_libraries(fft-utils PUBLIC MKL::MKL) + message(STATUS "F2Dock: FFT provider = Intel oneMKL") +elseif(_f2dock_fft_provider STREQUAL "cufft") + find_package(CUDAToolkit REQUIRED) + target_link_libraries(fft-utils PUBLIC CUDA::cufft) + message(STATUS "F2Dock: FFT provider = NVIDIA cuFFT") +endif() diff --git a/src/fft-utils/fft_fftw.cpp b/src/fft-utils/fft_fftw.cpp new file mode 100644 index 0000000..778c351 --- /dev/null +++ b/src/fft-utils/fft_fftw.cpp @@ -0,0 +1,111 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// FFTW backend -- OPT-IN ONLY. +// +// FFTW is GPL-2.0-or-later. Building this file links it, and the resulting +// F2Dock binary is then a combined work covered by the GPL, NOT by F2Dock's +// own LGPL-2.1. It is compiled only when the build is configured with +// -DF2DOCK_FFT_PROVIDER=fftw, which also prints a warning at configure time +// and makes the binary say so at startup. +// +// It is kept because FFTW is the fastest option here (1.41-1.73x over +// PocketFFT on throughput at equal core count) and because reproducing an +// older result may require the exact transform that produced it. + +#include "fft-utils/fft_provider.h" + +#include + +#ifdef FFTW_SINGLE_PRECISION +#define FFTW_(sym) fftwf_##sym +#else +#define FFTW_(sym) fftw_##sym +#endif + +namespace cvc { +namespace fft { + +// FFTW already has a plan object; this is a straight pass-through, so the +// provider seam costs nothing when FFTW is the one selected. +struct plan_impl { + FFTW_(plan) p; +}; + +void *alloc(std::size_t bytes) { return FFTW_(malloc)(bytes); } +void release(void *p) { FFTW_(free)(p); } + +static plan wrap(FFTW_(plan) p) { + plan_impl *w = new plan_impl; + w->p = p; + return w; +} + +plan dft_1d(int n, complex *in, complex *out, int sign, unsigned flags) { + return wrap(FFTW_(plan_dft_1d)(n, reinterpret_cast(in), + reinterpret_cast(out), sign, + flags)); +} + +plan dft_2d(int n0, int n1, complex *in, complex *out, int sign, + unsigned flags) { + return wrap(FFTW_(plan_dft_2d)(n0, n1, reinterpret_cast(in), + reinterpret_cast(out), sign, + flags)); +} + +plan dft_3d(int n0, int n1, int n2, complex *in, complex *out, int sign, + unsigned flags) { + return wrap( + FFTW_(plan_dft_3d)(n0, n1, n2, reinterpret_cast(in), + reinterpret_cast(out), sign, flags)); +} + +plan dft_r2c_3d(int n0, int n1, int n2, real *in, complex *out, + unsigned flags) { + return wrap(FFTW_(plan_dft_r2c_3d)( + n0, n1, n2, in, reinterpret_cast(out), flags)); +} + +plan dft_c2r_3d(int n0, int n1, int n2, complex *in, real *out, + unsigned flags) { + return wrap(FFTW_(plan_dft_c2r_3d)( + n0, n1, n2, reinterpret_cast(in), out, flags)); +} + +void execute(plan p) { + if (p) + FFTW_(execute)(p->p); +} + +void destroy(plan p) { + if (!p) + return; + FFTW_(destroy_plan)(p->p); + delete p; +} + +const char *provider_name() { return "FFTW3 (GPL-2.0-or-later)"; } + +bool provider_is_gpl() { return true; } + +} // namespace fft +} // namespace cvc diff --git a/src/fft-utils/fft_pocketfft.cpp b/src/fft-utils/fft_pocketfft.cpp new file mode 100644 index 0000000..e925a25 --- /dev/null +++ b/src/fft-utils/fft_pocketfft.cpp @@ -0,0 +1,217 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// PocketFFT backend (BSD-3-Clause, from the cvcpkg `pocketfft` bundle). +// +// This is the default provider because it is the fastest transform F2Dock can +// use without making the binary GPL. Verified against FFTW on the shape the +// hot loop runs (3-D c2c, double, N=64..256): agrees to float64 round-off, +// <= 7.3e-12. It is slower -- FFTW leads by 1.41-1.73x on throughput at equal +// core count -- which is the price of the licence, and why MKL and cuFFT are +// also selectable. +// +// PocketFFT has no planning stage: it computes twiddles per call and caches +// them internally. So a "plan" here is just the captured shape and buffers, +// and `flags` (FFTW_MEASURE and friends) are accepted and ignored. + +#include "fft-utils/fft_provider.h" + +#include +#include +#include +#include + +#include + +namespace cvc { +namespace fft { + +namespace { + +enum kind_t { KIND_C2C, KIND_R2C, KIND_C2R }; + +// Byte alignment for the transform buffers. PocketFFT vectorises over the +// contiguous axis, so give it what the widest SIMD it may pick wants. +const std::size_t kAlign = 64; + +pocketfft::stride_t contiguous_strides(const pocketfft::shape_t &shape, + std::size_t elem) { + pocketfft::stride_t s(shape.size()); + std::ptrdiff_t acc = static_cast(elem); + for (std::size_t i = shape.size(); i-- > 0;) { + s[i] = acc; + acc *= static_cast(shape[i]); + } + return s; +} + +} // namespace + +// A plan is the arguments, retained. execute() replays them. +struct plan_impl { + kind_t kind; + pocketfft::shape_t shape; // logical dimensions + int sign; // c2c only + void *in; + void *out; +}; + +void *alloc(std::size_t bytes) { + if (bytes == 0) + bytes = 1; + // Round up so the size is a multiple of the alignment, which + // std::aligned_alloc requires and some libcs enforce. + const std::size_t rounded = ((bytes + kAlign - 1) / kAlign) * kAlign; +#if defined(_MSC_VER) + void *p = _aligned_malloc(rounded, kAlign); +#else + void *p = std::aligned_alloc(kAlign, rounded); +#endif + if (!p) + throw std::bad_alloc(); + return p; +} + +void release(void *p) { + if (!p) + return; +#if defined(_MSC_VER) + _aligned_free(p); +#else + std::free(p); +#endif +} + +static plan make_c2c(const pocketfft::shape_t &shape, complex *in, complex *out, + int sign) { + plan_impl *p = new plan_impl; + p->kind = KIND_C2C; + p->shape = shape; + p->sign = sign; + p->in = in; + p->out = out; + return p; +} + +plan dft_1d(int n, complex *in, complex *out, int sign, unsigned /*flags*/) { + return make_c2c(pocketfft::shape_t{static_cast(n)}, in, out, + sign); +} + +plan dft_2d(int n0, int n1, complex *in, complex *out, int sign, + unsigned /*flags*/) { + return make_c2c(pocketfft::shape_t{static_cast(n0), + static_cast(n1)}, + in, out, sign); +} + +plan dft_3d(int n0, int n1, int n2, complex *in, complex *out, int sign, + unsigned /*flags*/) { + return make_c2c(pocketfft::shape_t{static_cast(n0), + static_cast(n1), + static_cast(n2)}, + in, out, sign); +} + +plan dft_r2c_3d(int n0, int n1, int n2, real *in, complex *out, + unsigned /*flags*/) { + plan_impl *p = new plan_impl; + p->kind = KIND_R2C; + p->shape = pocketfft::shape_t{static_cast(n0), + static_cast(n1), + static_cast(n2)}; + p->sign = sign_forward; + p->in = in; + p->out = out; + return p; +} + +plan dft_c2r_3d(int n0, int n1, int n2, complex *in, real *out, + unsigned /*flags*/) { + plan_impl *p = new plan_impl; + p->kind = KIND_C2R; + p->shape = pocketfft::shape_t{static_cast(n0), + static_cast(n1), + static_cast(n2)}; + p->sign = sign_backward; + p->in = in; + p->out = out; + return p; +} + +void execute(plan p) { + if (!p) + return; + + // fct = 1.0 in BOTH directions: FFTW is unnormalised, and Docking.cpp's + // scoring depends on that. Normalising here would change every score. + const real fct = static_cast(1); + + const std::size_t ndim = p->shape.size(); + pocketfft::shape_t axes(ndim); + for (std::size_t i = 0; i < ndim; ++i) + axes[i] = i; + + switch (p->kind) { + case KIND_C2C: { + const pocketfft::stride_t st = + contiguous_strides(p->shape, sizeof(std::complex)); + pocketfft::c2c(p->shape, st, st, axes, + p->sign == sign_forward ? pocketfft::FORWARD + : pocketfft::BACKWARD, + reinterpret_cast *>(p->in), + reinterpret_cast *>(p->out), fct); + break; + } + case KIND_R2C: { + // FFTW's half-complex layout: the complex side is n0 x n1 x (n2/2 + 1). + pocketfft::shape_t cshape = p->shape; + cshape[ndim - 1] = p->shape[ndim - 1] / 2 + 1; + const pocketfft::stride_t sin = contiguous_strides(p->shape, sizeof(real)); + const pocketfft::stride_t sout = + contiguous_strides(cshape, sizeof(std::complex)); + pocketfft::r2c(p->shape, sin, sout, axes, pocketfft::FORWARD, + reinterpret_cast(p->in), + reinterpret_cast *>(p->out), fct); + break; + } + case KIND_C2R: { + pocketfft::shape_t cshape = p->shape; + cshape[ndim - 1] = p->shape[ndim - 1] / 2 + 1; + const pocketfft::stride_t sin = + contiguous_strides(cshape, sizeof(std::complex)); + const pocketfft::stride_t sout = contiguous_strides(p->shape, sizeof(real)); + pocketfft::c2r(p->shape, sin, sout, axes, pocketfft::BACKWARD, + reinterpret_cast *>(p->in), + reinterpret_cast(p->out), fct); + break; + } + } +} + +void destroy(plan p) { delete p; } + +const char *provider_name() { return "PocketFFT (BSD-3-Clause)"; } + +bool provider_is_gpl() { return false; } + +} // namespace fft +} // namespace cvc diff --git a/src/fft-utils/sparsefft3-stub.cpp b/src/fft-utils/sparsefft3-stub.cpp new file mode 100644 index 0000000..f147d5d --- /dev/null +++ b/src/fft-utils/sparsefft3-stub.cpp @@ -0,0 +1,83 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + Link-time stand-in for the GPL sparse 3-D FFT module, compiled in place of + sparsefft3.cpp / sparsefft3-plan.cpp when F2DOCK_ENABLE_GPL_COMPONENTS is + OFF (the default). See inc/fft-utils/sparsefft3-api.h. + + Nothing here is reachable in a well-formed run: the engine forces + useSparseFFT off when the module is absent, which pins both plan pointers + to NULL and routes every transform through dense FFTW. The bodies exist so + that a future caller which forgets that guard fails loudly rather than + silently producing a wrong score. +*/ + +#include "fft-utils/sparsefft3-api.h" + +#ifndef F2DOCK_WITH_SPARSEFFT + +#include +#include + +static void sparsefft3_unavailable(const char *fn) { + fprintf(stderr, + "F2Dock: %s was called, but the sparse 3-D FFT module is not part " + "of this build.\n" + " It is GPL-licensed and is only compiled when F2Dock is " + "configured with\n" + " -DF2DOCK_ENABLE_GPL_COMPONENTS=ON. Set 'useSparseFFT " + "false' in the\n" + " parameter file to use the dense FFTW path instead.\n", + fn); +} + +sparse3DFFT_plan +sparse3DFFT_create_plan(int nx, int ny, int nz, int dir, int flags, + sparse3DFFT_sparsedir sparsedir, + sparse3DFFT_nonzero_func nonzero, void *nonzero_data, + FFTW_complex *data_in, FFTW_complex *data_out) { + (void)nx; + (void)ny; + (void)nz; + (void)dir; + (void)flags; + (void)sparsedir; + (void)nonzero; + (void)nonzero_data; + (void)data_in; + (void)data_out; + sparsefft3_unavailable("sparse3DFFT_create_plan"); + return NULL; +} + +void sparse3DFFT_destroy_plan(sparse3DFFT_plan p) { (void)p; } + +void sparse3DFFT(sparse3DFFT_plan p, FFTW_complex *data_in, + FFTW_complex *data_out) { + (void)p; + (void)data_in; + (void)data_out; + sparsefft3_unavailable("sparse3DFFT"); + abort(); +} + +#endif /* !F2DOCK_WITH_SPARSEFFT */ diff --git a/src/vol/RAWIV.cpp b/src/vol/RAWIV.cpp old mode 100755 new mode 100644 index b897eec..bd57064 --- a/src/vol/RAWIV.cpp +++ b/src/vol/RAWIV.cpp @@ -36,32 +36,31 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include "RAWIV.h" namespace { #ifdef FFTW_SINGLE_PRECISION -constexpr CVC_NAMESPACE::data_type kFftwVoxelType = CVC_NAMESPACE::Float; +constexpr cvc::data_type kFftwVoxelType = cvc::Float; #else -constexpr CVC_NAMESPACE::data_type kFftwVoxelType = CVC_NAMESPACE::Double; +constexpr cvc::data_type kFftwVoxelType = cvc::Double; #endif // Build a libcvc bounding_box from the (xCenter, yCenter, zCenter, scale) // convention used throughout F2Dock. F2Dock stores `scale` as the inverse of // the cube edge length, so the half-extent in each dimension is 0.5/scale. -CVC_NAMESPACE::bounding_box centerScaleToBox(double xCenter, double yCenter, - double zCenter, double scale) { +cvc::bounding_box centerScaleToBox(double xCenter, double yCenter, + double zCenter, double scale) { const double half = 0.5 / scale; - return CVC_NAMESPACE::bounding_box(xCenter - half, yCenter - half, - zCenter - half, xCenter + half, - yCenter + half, zCenter + half); + return cvc::bounding_box(xCenter - half, yCenter - half, zCenter - half, + xCenter + half, yCenter + half, zCenter + half); } // Helper: write an n^3 cube of FFTW samples to a RAWIV file via libcvc. @@ -73,11 +72,10 @@ int writeRAWIVCube(const FFTW_DATA_TYPE *vol, int n, double xCenter, } try { - CVC_NAMESPACE::app ctx; - CVC_NAMESPACE::volume cvol( - ctx, reinterpret_cast(vol), - CVC_NAMESPACE::dimension(n, n, n), kFftwVoxelType, - centerScaleToBox(xCenter, yCenter, zCenter, scale)); + cvc::app ctx; + cvc::volume cvol(ctx, reinterpret_cast(vol), + cvc::dimension(n, n, n), kFftwVoxelType, + centerScaleToBox(xCenter, yCenter, zCenter, scale)); cvol.write(std::string(fileName)); return 1; } catch (const std::exception &e) { @@ -99,8 +97,8 @@ int readRAWIVCube(FFTW_DATA_TYPE **outVol, int *xDim, int *yDim, int *zDim, } try { - CVC_NAMESPACE::app ctx; - CVC_NAMESPACE::volume cvol(ctx, std::string(fileName)); + cvc::app ctx; + cvc::volume cvol(ctx, std::string(fileName)); *xDim = static_cast(cvol.XDim()); *yDim = static_cast(cvol.YDim()); @@ -128,20 +126,20 @@ int readRAWIVCube(FFTW_DATA_TYPE **outVol, int *xDim, int *yDim, int *zDim, // Cast through the per-element accessor so we get a clean conversion to // FFTW_DATA_TYPE regardless of whether the on-disk type was Float, // Double, or UChar. - const CVC_NAMESPACE::data_type vt = cvol.voxelType(); + const cvc::data_type vt = cvol.voxelType(); const unsigned char *raw = *cvol; if (vt == kFftwVoxelType) { memcpy(*outVol, raw, n * sizeof(FFTW_DATA_TYPE)); - } else if (vt == CVC_NAMESPACE::Float) { + } else if (vt == cvc::Float) { const float *src = reinterpret_cast(raw); for (std::size_t i = 0; i < n; ++i) (*outVol)[i] = static_cast(src[i]); - } else if (vt == CVC_NAMESPACE::Double) { + } else if (vt == cvc::Double) { const double *src = reinterpret_cast(raw); for (std::size_t i = 0; i < n; ++i) (*outVol)[i] = static_cast(src[i]); - } else if (vt == CVC_NAMESPACE::UChar) { + } else if (vt == cvc::UChar) { const unsigned char *src = raw; for (std::size_t i = 0; i < n; ++i) (*outVol)[i] = static_cast(src[i]); @@ -235,8 +233,8 @@ int readRAWIVHeader(int *xDim, int *yDim, int *zDim, double *xCenter, return 0; try { - CVC_NAMESPACE::app ctx; - CVC_NAMESPACE::volume_file_info info(ctx, std::string(fileName)); + cvc::app ctx; + cvc::volume_file_info info(ctx, std::string(fileName)); *xDim = static_cast(info.XDim()); *yDim = static_cast(info.YDim()); diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index a3619d8..c4e330e 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -1,16 +1,11 @@ cmake_minimum_required(VERSION 3.16) -include(FetchContent) -FetchContent_Declare( - googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # v1.14.0 -) -# Prevent GTest from overriding our compiler/linker options on Windows -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -# Don't install GTest headers/libs with our project -set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(googletest) +# GoogleTest comes from cvcpkg like every other dependency -- it is declared +# in cvcpkg/recipes/f2dock/recipe.yaml, so `cvcpkg install-deps` puts it in +# the same prefix as libcvc and FFTW. This used to FetchContent v1.14.0 from +# github at configure time, which was the last network fetch in an otherwise +# hermetic build. +find_package(GTest CONFIG REQUIRED) include(GoogleTest) diff --git a/tests/unit/test_clash_filter.cpp b/tests/unit/test_clash_filter.cpp index b96799d..2125316 100644 --- a/tests/unit/test_clash_filter.cpp +++ b/tests/unit/test_clash_filter.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + /* * Unit tests for clashFilter. * diff --git a/tests/unit/test_dock_mode.cpp b/tests/unit/test_dock_mode.cpp index d430073..cd833b2 100644 --- a/tests/unit/test_dock_mode.cpp +++ b/tests/unit/test_dock_mode.cpp @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-License-Identifier: LGPL-2.1-only // // Unit tests for f3dock::DockMode parsing and stringification. diff --git a/tests/unit/test_f2dock_icp_refine.cpp b/tests/unit/test_f2dock_icp_refine.cpp index 03979d3..59ab093 100644 --- a/tests/unit/test_f2dock_icp_refine.cpp +++ b/tests/unit/test_f2dock_icp_refine.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include #include diff --git a/tests/unit/test_f3dock_domain.cpp b/tests/unit/test_f3dock_domain.cpp index 315a51f..b7d1e09 100644 --- a/tests/unit/test_f3dock_domain.cpp +++ b/tests/unit/test_f3dock_domain.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include diff --git a/tests/unit/test_f3dock_domain_partition.cpp b/tests/unit/test_f3dock_domain_partition.cpp index d9b59bb..6c92631 100644 --- a/tests/unit/test_f3dock_domain_partition.cpp +++ b/tests/unit/test_f3dock_domain_partition.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + // Unit tests for the Phase 4 task-2 receptor-domain atom partition. // Mirrors the apply()/state pattern used by f3dock::flex. diff --git a/tests/unit/test_f3dock_domain_sampler.cpp b/tests/unit/test_f3dock_domain_sampler.cpp index 07f83fb..e6fa7cd 100644 --- a/tests/unit/test_f3dock_domain_sampler.cpp +++ b/tests/unit/test_f3dock_domain_sampler.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + // Unit tests for the Phase 4 task-3 receptor-domain hinge sampler. // Mirrors the pattern used by FlexSampler / DomainPartition tests. diff --git a/tests/unit/test_f3dock_domain_spec.cpp b/tests/unit/test_f3dock_domain_spec.cpp index af38436..3d5f67c 100644 --- a/tests/unit/test_f3dock_domain_spec.cpp +++ b/tests/unit/test_f3dock_domain_spec.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + // Unit tests for the Phase 4 task-1 receptor domain-spec parser and // validator. Parser is a static class mirroring f3dock::flex::FlexSampler. // diff --git a/tests/unit/test_f3dock_flex.cpp b/tests/unit/test_f3dock_flex.cpp index 78885a2..2a9cb26 100644 --- a/tests/unit/test_f3dock_flex.cpp +++ b/tests/unit/test_f3dock_flex.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include diff --git a/tests/unit/test_f3dock_flex_apply.cpp b/tests/unit/test_f3dock_flex_apply.cpp index fea8ff4..29b7321 100644 --- a/tests/unit/test_f3dock_flex_apply.cpp +++ b/tests/unit/test_f3dock_flex_apply.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include diff --git a/tests/unit/test_f3dock_flex_sampler.cpp b/tests/unit/test_f3dock_flex_sampler.cpp index 73316b9..907c78b 100644 --- a/tests/unit/test_f3dock_flex_sampler.cpp +++ b/tests/unit/test_f3dock_flex_sampler.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include #include diff --git a/tests/unit/test_f3dock_icp.cpp b/tests/unit/test_f3dock_icp.cpp index 1113b85..8493618 100644 --- a/tests/unit/test_f3dock_icp.cpp +++ b/tests/unit/test_f3dock_icp.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include #include diff --git a/tests/unit/test_f3dock_loop_closure.cpp b/tests/unit/test_f3dock_loop_closure.cpp index 20994d6..e4ad33c 100644 --- a/tests/unit/test_f3dock_loop_closure.cpp +++ b/tests/unit/test_f3dock_loop_closure.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include diff --git a/tests/unit/test_f3dock_nfft_fast_gaussian_sum.cpp b/tests/unit/test_f3dock_nfft_fast_gaussian_sum.cpp index fb1c4e5..9ffdb70 100644 --- a/tests/unit/test_f3dock_nfft_fast_gaussian_sum.cpp +++ b/tests/unit/test_f3dock_nfft_fast_gaussian_sum.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + // Unit tests for f3dock::nfft::FastGaussianSum. // // Locks in: diff --git a/tests/unit/test_file_formats.cpp b/tests/unit/test_file_formats.cpp index 4c1b0fa..369eb09 100644 --- a/tests/unit/test_file_formats.cpp +++ b/tests/unit/test_file_formats.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + /* * Unit tests for F2Dock file formats and parameter parsing. * diff --git a/tests/unit/test_math.cpp b/tests/unit/test_math.cpp index 7510754..0d60ff6 100644 --- a/tests/unit/test_math.cpp +++ b/tests/unit/test_math.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + /* * Unit tests for CCVOpenGLMath::Matrix, CCVOpenGLMath::Vector, * CCVOpenGLMath::Tuple diff --git a/tests/unit/test_pairing_heap.cpp b/tests/unit/test_pairing_heap.cpp index 168b549..6165a8c 100644 --- a/tests/unit/test_pairing_heap.cpp +++ b/tests/unit/test_pairing_heap.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + /* * Unit tests for PairingHeap. * diff --git a/tests/unit/test_pg_range.cpp b/tests/unit/test_pg_range.cpp index 3252fbf..29c54a2 100644 --- a/tests/unit/test_pg_range.cpp +++ b/tests/unit/test_pg_range.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + /* * Unit tests for the PG (Dynamic Packing Grid) data structure. * diff --git a/tests/unit/test_value_position.cpp b/tests/unit/test_value_position.cpp index 1775942..b994548 100644 --- a/tests/unit/test_value_position.cpp +++ b/tests/unit/test_value_position.cpp @@ -1,3 +1,24 @@ +/* + Copyright 2026 The University of Texas at Austin + + Advisor: Chandrajit Bajaj + + This file is part of F2Dock. + + F2Dock is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + F2Dock is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + /* * Unit tests for ValuePosition3D. *