Compare commits

...
9 Commits
Author SHA1 Message Date
Clifford Yapp ad3cf7ecf0 proc-db: initialize gear pitch radii
The active array elements are initialized before use, but GCC PGO
analysis cannot prove the clamped gear count keeps every indexed value
within that initialized range.

Zero-initialize the fixed array so all possible elements have a defined
value without changing the computed radii.
2026-10-06 16:48:12 +00:00
Clifford Yapp 5075668363 g-x3d: suppress false LTO setjmp warning
GCC can report an anonymous value as maybe uninitialized when LTO
examines the BU_SETJUMP setjmp and longjmp control flow.  The diagnostic
is emitted during linking, so source pragmas cannot affect it.

Check for the linker option and suppress this warning only for the
g-x3d LTO link.  Normal compilation continues to treat the warning as
an error, leaving genuine uninitialized uses visible.
2026-10-06 16:47:58 +00:00
Clifford Yapp d09b59863a step: avoid GCC vector insertion false positive
GCC 14 lowers vector range insertion to a bulk move and can infer an
impossible negative size during PGO, reporting stringop-overflow.

Append the known positions individually.  This preserves their order
and complexity while avoiding the invalid range analysis.
2026-10-06 16:47:43 +00:00
Clifford Yapp 685d63dd71 build: use conventional calloc argument order
GCC 14 diagnoses calls with sizeof in the element-count position as
-Wcalloc-transposed-args.  Since multiplication is commutative, these
calls allocate the intended size, but their ordering obscures intent
and fails PGO and LTO builds with -Werror.

Pass the element count first and the element size second.
2026-10-06 16:47:32 +00:00
Clifford Yapp 00e61a90aa librt: let optimizer choose local inlining
GCC PGO decisions can reject explicit inline requests for cold call
sites, and -Winline then fails the build under -Werror.

Keep these helpers private with static linkage but remove inline.
Optimized builds remain free to inline profitable calls.  Remove the
metaball declaration that is no longer externally visible.
2026-10-06 16:47:19 +00:00
Clifford Yapp 07b2237074 libbu: keep UUID namespace optional
The namespace UUID is optional, but the array parameter syntax tells
GCC the pointer is nonnull.  PGO and LTO propagate that contract and
diagnose the existing null check as contradictory.

Declare the namespace as a pointer.  Array parameters already adjust to
pointers in function types, so this preserves the ABI while accurately
describing the accepted input.
2026-10-06 16:47:05 +00:00
Clifford Yapp 5d4f1f3d01 libbu: batch SHA-1 final padding
GCC interprocedural analysis reports a string overread when
SHA1Final repeatedly calls SHA1Update with a one-byte padding
variable.  The direct block loop is unreachable for those calls,
but PGO and LTO do not retain enough range information to prove it.

Define the SHA-1 block size once and submit the complete final padding
in one update.  This avoids the false object-size path, reduces
repeated update calls, and preserves the required one- or two-block
SHA-1 finalization.
2026-10-06 15:24:32 +00:00
Clifford Yapp 0d4dfb570d Stash (not yet enabling) STABLE brancy autosyncing 2026-10-06 14:56:43 +00:00
Clifford Yapp ea81a17325 Test CI PGO building, as well as MSVC version of PGO 2026-10-06 14:56:43 +00:00
23 changed files with 1034 additions and 94 deletions
+42
View File
@@ -447,3 +447,45 @@ jobs:
export PATH=$GITHUB_WORKSPACE:$PATH
make package
working-directory: ${{ github.workspace }}/build_osx
# BRL-CAD's STABLE branch is intended to represent the most recent
# SHA1 that has successfully passed our primary tests on our CI
# platforms. This job is intended to execute that update if the
# prior tasks succeed. It's "needs" section should contain every
# test that is not already the dependency of another tests.
# sync-stable-branch:
# name: Sync STABLE branch
# runs-on: ubuntu-latest
# needs: [archives, componentbext, windows_std_tools, osx]
# # This job should only run on a successful push to the main branch
# if: github.ref == 'refs/heads/main' && github.event_name == 'push'
# steps:
# # 1. Generate a short-lived token using the GitHub App
# - name: Generate GitHub App Token
# id: generate_token
# uses: tibdex/github-app-token@v2
# with:
# app_id: ${{ secrets.STABLESYNC_APP_ID }}
# private_key: ${{ secrets.STABLESYNC_APP_PRIVATE_KEY }}
# # 2. Checkout the repository using the App Token
# - name: Checkout Code
# uses: actions/checkout@v4
# with:
# token: ${{ steps.generate_token.outputs.token }}
# fetch-depth: 0 # Fetches all history to safely move branches
# # 3. Securely update and push the STABLE branch pointer
# - name: Update STABLE Branch Pointer
# run: |
# # Configure Git to identify as the GitHub Actions bot
# git config --global user.name "github-actions[bot]"
# git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
# echo "Updating STABLE branch to point to the latest successfully CI tested main SHA: ${{ github.sha }}"
# # Force the local STABLE branch to point directly to the current main SHA
# git branch -f STABLE ${{ github.sha }}
# # Push the updated stable branch reference securely back to origin
# git push origin STABLE --force
+352 -21
View File
@@ -15,16 +15,24 @@ on:
schedule:
- cron: '0 3 * * *' # daily at 03:00 UTC
workflow_dispatch:
inputs:
branch:
description: 'The branch ref to run the conditional jobs on (e.g., refs/heads/pgo)'
required: true
default: 'refs/heads/main'
type: string
env:
DEBIAN_FRONTEND: noninteractive
CLANG_VERSION: 18
jobs:
linux_bext:
name: Linux - BRL-CAD bext build
runs-on: ubuntu-latest
runs-on: &ubuntu_runner ubuntu-24.04 # Define the ubuntu runner anchor here
strategy:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
@@ -225,12 +233,13 @@ jobs:
linux_static:
name: Clang Static Analyser
needs: [linux_bext]
runs-on: ubuntu-24.04
runs-on: *ubuntu_runner # Use the ubuntu runner alias
strategy:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: |
!cancelled() &&
(github.event_name == 'workflow_dispatch' && github.ref == inputs.branch ||
github.event_name == 'schedule' && github.ref == 'refs/heads/main')
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
@@ -239,19 +248,19 @@ jobs:
- name: Clang Static Analyzer Setup
run: |
sudo apt-get update
sudo apt-get install clang-18 clang-tools-18
sudo apt-get install -y clang-${{ env.CLANG_VERSION }} clang-tools-${{ env.CLANG_VERSION }}
# Install X/OpenGL dev pkgs
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
sudo apt-get install -y xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
# Install tools
sudo apt-get install astyle re2c xsltproc libxml2-utils
sudo apt-get install -y astyle re2c xsltproc libxml2-utils
# Install dependency dev pkgs
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev
sudo apt-get install -y zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev
# Install XCB/OpenGL dev pkgs for Qt - see:
# https://wiki.qt.io/Building_Qt_6_from_Git
# https://doc.qt.io/qt-6/linux-requirements.html
sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-cursor-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxcb-xinput-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev # Cleanup
sudo apt-get install -y libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-cursor-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxcb-xinput-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev
sudo apt-get install -y libgl-dev
sudo apt-get install -y libinput-dev
- name: Checkout
uses: actions/checkout@v6
@@ -261,7 +270,7 @@ jobs:
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
platform-channel: ubuntu-*ubuntu_version-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
@@ -278,7 +287,7 @@ jobs:
env:
BRLCAD_EXT_DIR: ${{ runner.temp }}/bext_output
run: |
export PATH=$GITHUB_WORKSPACE:/usr/share/clang/scan-build-18/bin:/usr/share/clang/scan-build-18/libexec:$PATH
# The script will now receive the version number and find the tools itself
cp $GITHUB_WORKSPACE/brlcad/misc/clang-static-analyzer-run.sh .
./clang-static-analyzer-run.sh
working-directory: ${{ github.workspace }}/brlcad/build_clangstatic
@@ -290,17 +299,339 @@ jobs:
html2text scan-reports-all/*/index.html
working-directory: ${{ github.workspace }}/brlcad/build_clangstatic
linux_pgo:
name: GCC Profile-Guided Optimization
needs: [linux_bext]
runs-on: *ubuntu_runner # Use the ubuntu runner alias
timeout-minutes: 180
strategy:
fail-fast: true
env:
CMAKE_BUILD_PARALLEL_LEVEL: "2"
PGO_PATH: ${{ github.workspace }}/pgo-profile
PGO_BENCHMARK_TARGETS: >-
rt pixcmp benchmark_cp BENCHMARK_PIX_cp PIX_LOG_cp
bldg391.g m35.g moss.g sphflake.g star.g world.g
PGO_TRAINING_TARGETS: >-
havoc.g Generic_Twin.g NIST_MBE_PMI_2.g
PGO_TRAINING_SIZE: "512"
PGO_TRAINING_AZIMUTH: "35"
PGO_TRAINING_ELEVATION: "25"
PGO_BENCHMARK_TIMEFRAME: "8"
PGO_BENCHMARK_MAXTIME: "60"
PGO_BENCHMARK_AVERAGE: "3"
PGO_BENCHMARK_DEVIATION: "3"
PGO_MIN_SPEEDUP: "1.0"
if: |
!cancelled() &&
(github.event_name == 'workflow_dispatch' && github.ref == inputs.branch ||
github.event_name == 'schedule' && github.ref == 'refs/heads/main')
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Install apt dependencies
run: |
sudo apt-get update
# Install X/OpenGL dev pkgs
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
# Install tools
sudo apt-get install astyle re2c xsltproc libxml2-utils
# Install dependency dev pkgs
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev
# Install XCB/OpenGL dev pkgs for a fallback bext build
sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-cursor-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxcb-xinput-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev
sudo apt-get install libgl-dev libinput-dev
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-*ubuntu_version-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: |
set -euo pipefail
cmake -E make_directory $HOME/.cache/BRL-CAD
if [[ -e "$PGO_PATH" ]]; then
echo "::error::PGO profile path unexpectedly exists before the generation build"
exit 1
fi
- name: Configure baseline build
run: |
cmake -S brlcad -B build_pgo_baseline -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBUILD_TESTING=ON \
-DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output \
-DBRLCAD_ENABLE_QT=OFF \
-DBRLCAD_ENABLE_STEP=ON \
-DBRLCAD_ENABLE_STRICT=ON
- name: Build baseline
run: cmake --build build_pgo_baseline --target $PGO_BENCHMARK_TARGETS
- name: Configure profile-generation build
run: |
cmake -S brlcad -B build_pgo -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBUILD_TESTING=ON \
-DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output \
-DBRLCAD_ENABLE_QT=OFF \
-DBRLCAD_ENABLE_STEP=ON \
-DBRLCAD_ENABLE_STRICT=ON \
-DBRLCAD_PGO=ON
grep -q -- '-fprofile-generate=' build_pgo/compile_commands.json
- name: Build profile-generation binaries
run: cmake --build build_pgo --target $PGO_BENCHMARK_TARGETS $PGO_TRAINING_TARGETS
- name: Generate profile data
run: |
cmake \
-DPGO_MODE=TRAIN \
-DPGO_BUILD_DIR="$GITHUB_WORKSPACE/build_pgo" \
-DPGO_RESULTS_DIR="$GITHUB_WORKSPACE/pgo-training" \
-DPGO_PROFILE_DIR="$PGO_PATH" \
-DPGO_TIMEFRAME="$PGO_BENCHMARK_TIMEFRAME" \
-DPGO_MAXTIME="$PGO_BENCHMARK_MAXTIME" \
-DPGO_AVERAGE="$PGO_BENCHMARK_AVERAGE" \
-DPGO_DEVIATION="$PGO_BENCHMARK_DEVIATION" \
-DPGO_TRAINING_SIZE="$PGO_TRAINING_SIZE" \
-DPGO_TRAINING_AZIMUTH="$PGO_TRAINING_AZIMUTH" \
-DPGO_TRAINING_ELEVATION="$PGO_TRAINING_ELEVATION" \
-P brlcad/misc/CMake/scripts/pgo_benchmark.cmake
- name: Configure profile-use build
run: |
# GCC incorporates the build path into profile filenames, so both
# compilation passes must use the same build directory.
cmake -E rm -rf build_pgo
cmake -S brlcad -B build_pgo -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBUILD_TESTING=ON \
-DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output \
-DBRLCAD_ENABLE_QT=OFF \
-DBRLCAD_ENABLE_STEP=ON \
-DBRLCAD_ENABLE_STRICT=ON \
-DBRLCAD_PGO=ON
grep -q -- '-fprofile-use=' build_pgo/compile_commands.json
- name: Build profile-guided binaries
run: cmake --build build_pgo --target $PGO_BENCHMARK_TARGETS
- name: Benchmark and compare profile-guided build
run: |
cmake \
-DPGO_MODE=COMPARE \
-DPGO_BASELINE_BUILD_DIR="$GITHUB_WORKSPACE/build_pgo_baseline" \
-DPGO_OPTIMIZED_BUILD_DIR="$GITHUB_WORKSPACE/build_pgo" \
-DPGO_RESULTS_DIR="$GITHUB_WORKSPACE/pgo-results" \
-DPGO_TIMEFRAME="$PGO_BENCHMARK_TIMEFRAME" \
-DPGO_MAXTIME="$PGO_BENCHMARK_MAXTIME" \
-DPGO_AVERAGE="$PGO_BENCHMARK_AVERAGE" \
-DPGO_DEVIATION="$PGO_BENCHMARK_DEVIATION" \
-DPGO_MIN_SPEEDUP="$PGO_MIN_SPEEDUP" \
-P brlcad/misc/CMake/scripts/pgo_benchmark.cmake
windows_pgo:
name: MSVC Profile-Guided Optimization
needs: [windows_bext]
runs-on: windows-latest
timeout-minutes: 180
strategy:
fail-fast: true
env:
CMAKE_BUILD_PARALLEL_LEVEL: "2"
PGO_BENCHMARK_TARGETS: >-
rt pixcmp benchmark_cp BENCHMARK_PIX_cp PIX_LOG_cp
bldg391.g m35.g moss.g sphflake.g star.g world.g
PGO_TRAINING_TARGETS: >-
havoc.g Generic_Twin.g NIST_MBE_PMI_2.g
PGO_TRAINING_SIZE: "512"
PGO_TRAINING_AZIMUTH: "35"
PGO_TRAINING_ELEVATION: "25"
PGO_BENCHMARK_TIMEFRAME: "8"
PGO_BENCHMARK_MAXTIME: "60"
PGO_BENCHMARK_AVERAGE: "3"
PGO_BENCHMARK_DEVIATION: "3"
PGO_MIN_SPEEDUP: "1.0"
if: |
!cancelled() &&
(github.event_name == 'workflow_dispatch' && github.ref == inputs.branch ||
github.event_name == 'schedule' && github.ref == 'refs/heads/main')
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Add cl.exe to PATH
uses: ilammy/msvc-dev-cmd@v1
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: windows-2025-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Set up PGO paths
shell: pwsh
run: |
# Short build roots keep STEP-generated paths below Windows MAX_PATH.
$paths = @{
PGO_PATH = Join-Path $env:RUNNER_TEMP 'pgo-d'
PGO_BASELINE_BUILD_DIR = Join-Path $env:RUNNER_TEMP 'pgo-b'
PGO_GENERATE_BUILD_DIR = Join-Path $env:RUNNER_TEMP 'pgo-g'
PGO_OPTIMIZED_BUILD_DIR = Join-Path $env:RUNNER_TEMP 'pgo-u'
PGO_TRAINING_RESULTS_DIR = Join-Path $env:RUNNER_TEMP 'pgo-t'
PGO_RESULTS_DIR = Join-Path $env:RUNNER_TEMP 'pgo-r'
}
if (Test-Path -LiteralPath $paths.PGO_PATH) {
throw "PGO profile path unexpectedly exists before the generation build: $($paths.PGO_PATH)"
}
foreach ($path in $paths.GetEnumerator()) {
Add-Content -Path $env:GITHUB_ENV -Value "$($path.Key)=$($path.Value)"
}
- name: Configure baseline build
shell: pwsh
run: |
cmake -S brlcad -B "$env:PGO_BASELINE_BUILD_DIR" -G Ninja `
-DCMAKE_C_COMPILER=cl.exe `
-DCMAKE_CXX_COMPILER=cl.exe `
-DCMAKE_BUILD_TYPE=Release `
-DBUILD_TESTING=ON `
"-DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output" `
-DBRLCAD_ENABLE_QT=OFF `
-DBRLCAD_ENABLE_STEP=ON `
-DBRLCAD_ENABLE_STRICT=ON
- name: Build baseline
shell: pwsh
run: |
$targets = $env:PGO_BENCHMARK_TARGETS -split '\s+'
$arguments = @('--build', $env:PGO_BASELINE_BUILD_DIR, '--target') + $targets
cmake @arguments
- name: Configure profile-generation build
shell: pwsh
run: |
cmake -S brlcad -B "$env:PGO_GENERATE_BUILD_DIR" -G Ninja `
-DCMAKE_C_COMPILER=cl.exe `
-DCMAKE_CXX_COMPILER=cl.exe `
-DCMAKE_BUILD_TYPE=Release `
-DBUILD_TESTING=ON `
"-DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output" `
-DBRLCAD_ENABLE_QT=OFF `
-DBRLCAD_ENABLE_STEP=ON `
-DBRLCAD_ENABLE_STRICT=ON `
-DBRLCAD_PGO=ON
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
if (-not (Select-String -Path "$env:PGO_GENERATE_BUILD_DIR/build.ninja" -SimpleMatch '/GENPROFILE:PGD=' -Quiet)) {
throw 'The profile-generation build does not contain /GENPROFILE.'
}
- name: Build profile-generation binaries
shell: pwsh
run: |
$targets = ($env:PGO_BENCHMARK_TARGETS + ' ' + $env:PGO_TRAINING_TARGETS) -split '\s+'
$arguments = @('--build', $env:PGO_GENERATE_BUILD_DIR, '--target') + $targets
cmake @arguments
- name: Generate profile data
shell: pwsh
run: |
cmake `
-DPGO_MODE=TRAIN `
"-DPGO_BUILD_DIR=$env:PGO_GENERATE_BUILD_DIR" `
"-DPGO_RESULTS_DIR=$env:PGO_TRAINING_RESULTS_DIR" `
"-DPGO_PROFILE_DIR=$env:PGO_PATH" `
"-DPGO_TIMEFRAME=$env:PGO_BENCHMARK_TIMEFRAME" `
"-DPGO_MAXTIME=$env:PGO_BENCHMARK_MAXTIME" `
"-DPGO_AVERAGE=$env:PGO_BENCHMARK_AVERAGE" `
"-DPGO_DEVIATION=$env:PGO_BENCHMARK_DEVIATION" `
"-DPGO_TRAINING_SIZE=$env:PGO_TRAINING_SIZE" `
"-DPGO_TRAINING_AZIMUTH=$env:PGO_TRAINING_AZIMUTH" `
"-DPGO_TRAINING_ELEVATION=$env:PGO_TRAINING_ELEVATION" `
-P brlcad/misc/CMake/scripts/pgo_benchmark.cmake
- name: Configure profile-use build
shell: pwsh
run: |
cmake -S brlcad -B "$env:PGO_OPTIMIZED_BUILD_DIR" -G Ninja `
-DCMAKE_C_COMPILER=cl.exe `
-DCMAKE_CXX_COMPILER=cl.exe `
-DCMAKE_BUILD_TYPE=Release `
-DBUILD_TESTING=ON `
"-DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output" `
-DBRLCAD_ENABLE_QT=OFF `
-DBRLCAD_ENABLE_STEP=ON `
-DBRLCAD_ENABLE_STRICT=ON `
-DBRLCAD_PGO=ON
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
if (-not (Select-String -Path "$env:PGO_OPTIMIZED_BUILD_DIR/build.ninja" -SimpleMatch '/USEPROFILE:PGD=' -Quiet)) {
throw 'The profile-use build does not contain /USEPROFILE.'
}
- name: Build profile-guided binaries
shell: pwsh
run: |
$targets = $env:PGO_BENCHMARK_TARGETS -split '\s+'
$arguments = @('--build', $env:PGO_OPTIMIZED_BUILD_DIR, '--target') + $targets
cmake @arguments
- name: Benchmark and compare profile-guided build
shell: pwsh
run: |
cmake `
-DPGO_MODE=COMPARE `
"-DPGO_BASELINE_BUILD_DIR=$env:PGO_BASELINE_BUILD_DIR" `
"-DPGO_OPTIMIZED_BUILD_DIR=$env:PGO_OPTIMIZED_BUILD_DIR" `
"-DPGO_RESULTS_DIR=$env:PGO_RESULTS_DIR" `
"-DPGO_TIMEFRAME=$env:PGO_BENCHMARK_TIMEFRAME" `
"-DPGO_MAXTIME=$env:PGO_BENCHMARK_MAXTIME" `
"-DPGO_AVERAGE=$env:PGO_BENCHMARK_AVERAGE" `
"-DPGO_DEVIATION=$env:PGO_BENCHMARK_DEVIATION" `
"-DPGO_MIN_SPEEDUP=$env:PGO_MIN_SPEEDUP" `
-P brlcad/misc/CMake/scripts/pgo_benchmark.cmake
# See https://app.codecov.io/gh/BRL-CAD/brlcad for analysis results
linux_cov:
name: LCOV Coverage testing
needs: [linux_bext]
runs-on: ubuntu-24.04
runs-on: *ubuntu_runner # Use the ubuntu runner alias
strategy:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: |
!cancelled() &&
(github.event_name == 'workflow_dispatch' && github.ref == inputs.branch ||
github.event_name == 'schedule' && github.ref == 'refs/heads/main')
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
@@ -331,7 +662,7 @@ jobs:
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
platform-channel: ubuntu-*ubuntu_version-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
+104 -6
View File
@@ -1338,6 +1338,90 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
brlcad_deferred_define("BRLCAD_HAS_BIG_STACK 1")
endif()
# Profile-Guided Optimization uses a shared profile location for both compiler
# families. A path that does not exist selects the instrumentation pass; an
# existing path selects the profile-use pass in a fresh build tree.
if("$ENV{PGO_PATH}" STREQUAL "")
set(BRLCAD_PGO_PATH "${CMAKE_BINARY_DIR}/profiling")
else()
file(TO_CMAKE_PATH "$ENV{PGO_PATH}" BRLCAD_PGO_PATH)
endif()
# MSVC creates one profile database per linked image. The target-dependent
# generator expression gives every executable and DLL a distinct database,
# while /GL also covers code contributed through object and static libraries.
if(MSVC AND BRLCAD_PGO)
if(DEFINED BRLCAD_MSVC_PGO_PHASE)
if(NOT "${BRLCAD_MSVC_PGO_PATH}" STREQUAL "${BRLCAD_PGO_PATH}")
message(
FATAL_ERROR
"PGO_PATH changed from '${BRLCAD_MSVC_PGO_PATH}' to '${BRLCAD_PGO_PATH}'. "
"Use a fresh build directory when changing PGO phases or profile locations."
)
endif()
elseif(EXISTS "${BRLCAD_PGO_PATH}")
set(BRLCAD_MSVC_PGO_PHASE USE)
else()
set(BRLCAD_MSVC_PGO_PHASE GENERATE)
endif()
if(NOT BRLCAD_MSVC_PGO_PHASE MATCHES "^(GENERATE|USE)$")
message(FATAL_ERROR "Invalid internal MSVC PGO phase '${BRLCAD_MSVC_PGO_PHASE}'")
endif()
set(BRLCAD_MSVC_PGO_PHASE "${BRLCAD_MSVC_PGO_PHASE}" CACHE INTERNAL "MSVC PGO build phase" FORCE)
set(BRLCAD_MSVC_PGO_PATH "${BRLCAD_PGO_PATH}" CACHE INTERNAL "MSVC PGO profile path" FORCE)
if(BRLCAD_MSVC_PGO_PHASE STREQUAL "GENERATE")
# link.exe requires the PGD parent directory to exist before it links the
# instrumented image. Cache the phase above so an in-place CMake rerun
# does not mistake this newly created directory for completed profiles.
file(MAKE_DIRECTORY "${BRLCAD_PGO_PATH}")
set(_brlcad_msvc_pgo_link_mode GENPROFILE)
message(
STATUS
"MSVC PGO generation enabled; set VCPROFILE_PATH=${BRLCAD_PGO_PATH} while running training workloads"
)
distclean("${BRLCAD_PGO_PATH}")
else()
message(STATUS "MSVC PGO profile use enabled from ${BRLCAD_PGO_PATH}")
endif()
add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX>:/GL>")
add_link_options(/LTCG)
if(_brlcad_msvc_pgo_link_mode)
add_link_options(
"/${_brlcad_msvc_pgo_link_mode}:PGD=${BRLCAD_PGO_PATH}/$<TARGET_PROPERTY:NAME>.pgd"
)
endif()
unset(_brlcad_msvc_pgo_link_mode)
endif()
# Apply profile-use only to images exercised during training. link.exe emits
# C4961 for an untrained PGD, and strict builds promote that warning to an
# error during LTCG. The generation pass names PGC files after the target's
# PGD, so this check also works when OUTPUT_NAME changes the binary name.
function(_BRLCAD_MSVC_PGO_APPLY_PROFILES directory)
get_property(_brlcad_pgo_targets DIRECTORY "${directory}" PROPERTY BUILDSYSTEM_TARGETS)
foreach(_brlcad_pgo_target IN LISTS _brlcad_pgo_targets)
get_target_property(_brlcad_pgo_target_type ${_brlcad_pgo_target} TYPE)
if(_brlcad_pgo_target_type MATCHES "^(EXECUTABLE|SHARED_LIBRARY|MODULE_LIBRARY)$")
set(_brlcad_pgo_database "${BRLCAD_PGO_PATH}/${_brlcad_pgo_target}.pgd")
file(GLOB _brlcad_pgo_counts LIST_DIRECTORIES FALSE "${BRLCAD_PGO_PATH}/${_brlcad_pgo_target}![0-9]*.pgc")
if(EXISTS "${_brlcad_pgo_database}" AND _brlcad_pgo_counts)
target_link_options(${_brlcad_pgo_target} PRIVATE "/USEPROFILE:PGD=${_brlcad_pgo_database}")
set_property(GLOBAL APPEND PROPERTY BRLCAD_MSVC_PGO_TRAINED_TARGETS ${_brlcad_pgo_target})
endif()
unset(_brlcad_pgo_counts)
unset(_brlcad_pgo_database)
endif()
endforeach()
get_property(_brlcad_pgo_subdirectories DIRECTORY "${directory}" PROPERTY SUBDIRECTORIES)
foreach(_brlcad_pgo_subdirectory IN LISTS _brlcad_pgo_subdirectories)
_brlcad_msvc_pgo_apply_profiles("${_brlcad_pgo_subdirectory}")
endforeach()
endfunction()
# The following tests are almost entirely for gcc/llvm style flags, so
# we don't unnecessarily slow down the Windows build.
if(NOT MSVC)
@@ -1400,11 +1484,6 @@ if(NOT MSVC)
# variable set to a temp folder
set(pgo_flags_found "")
if("$ENV{PGO_PATH}" STREQUAL "")
set(BRLCAD_PGO_PATH "${CMAKE_BINARY_DIR}/profiling")
else(NOT "$ENV{PGO_PATH}" STREQUAL "")
set(BRLCAD_PGO_PATH "$ENV{PGO_PATH}")
endif("$ENV{PGO_PATH}" STREQUAL "")
if(BRLCAD_PGO AND NOT EXISTS "${BRLCAD_PGO_PATH}")
if("${CMAKE_C_FLAGS}" MATCHES ".*fprofile-use.*")
@@ -1450,7 +1529,8 @@ if(NOT MSVC)
# gcc-style USE
if("${pgo_flags_found}" STREQUAL "")
cmake_push_check_state()
set(flags "fprofile-use=\"${BRLCAD_PGO_PATH}\" -Wno-error=coverage-mismatch -fprofile-correction")
set(flags "fprofile-use=\"${BRLCAD_PGO_PATH}\" -Wno-error=coverage-mismatch")
string(APPEND flags " -Wno-error=missing-profile -fprofile-correction")
set(CMAKE_REQUIRED_FLAGS "-${flags}")
check_c_flag("${flags}" GROUPS OPTIMIZE_C_FLAGS VARS pgo_flags_found)
check_cxx_flag("${flags}" GROUPS OPTIMIZE_CXX_FLAGS)
@@ -2973,6 +3053,24 @@ verbose_add_subdirectory("" doc)
# NOTE: misc/tools is added separately (earlier)
verbose_add_subdirectory("" misc)
if(MSVC AND BRLCAD_PGO AND BRLCAD_MSVC_PGO_PHASE STREQUAL "USE")
set_property(GLOBAL PROPERTY BRLCAD_MSVC_PGO_TRAINED_TARGETS)
_brlcad_msvc_pgo_apply_profiles("${CMAKE_SOURCE_DIR}")
get_property(_brlcad_msvc_pgo_targets GLOBAL PROPERTY BRLCAD_MSVC_PGO_TRAINED_TARGETS)
list(LENGTH _brlcad_msvc_pgo_targets _brlcad_msvc_pgo_target_count)
if(_brlcad_msvc_pgo_target_count EQUAL 0)
message(
FATAL_ERROR
"No MSVC PGO counter files were found in ${BRLCAD_PGO_PATH}. "
"Set VCPROFILE_PATH to that directory while running the training workloads "
"before configuring the profile-use build."
)
endif()
message(STATUS "MSVC PGO will use training data for ${_brlcad_msvc_pgo_target_count} linked targets")
unset(_brlcad_msvc_pgo_target_count)
unset(_brlcad_msvc_pgo_targets)
endif()
#------------------------------------------------------------------------------
# CMake package configuration files for modern find_package(BRLCAD CONFIG)
#
+1 -1
View File
@@ -55,7 +55,7 @@ __BEGIN_DECLS
* version 5 UUID suitable for repeatable identifier hashing.
*/
BU_EXPORT int
bu_uuid_create(uint8_t uuid[STATIC_ARRAY(16)], size_t nbytes, const uint8_t *bytes, const uint8_t namespace_uuid[STATIC_ARRAY(16)]);
bu_uuid_create(uint8_t uuid[STATIC_ARRAY(16)], size_t nbytes, const uint8_t *bytes, const uint8_t *namespace_uuid);
/**
* This is a convenience UUID comparison routine compatible with
+7 -5
View File
@@ -471,11 +471,13 @@ if(BRLCAD_VERBOSE)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif(BRLCAD_VERBOSE)
# Build with profile-guided optimization support. this requires a two-pass
# compile, once with BRLCAD_PGO=ON on a location that did not exist beforehand
# (specified via the PGO_PATH environment variable), and again to use profiling
# metrics captured on "typical" operations and data. By default, path is
# BUILDDIR/profiling
# Build with profile-guided optimization support. This requires a two-pass
# compile, once with BRLCAD_PGO=ON and a profile location that did not exist
# beforehand (specified via the PGO_PATH environment variable), and again in a
# fresh build directory to use metrics captured on "typical" operations and
# data. By default, the path is BUILDDIR/profiling. For MSVC, set
# VCPROFILE_PATH to PGO_PATH while running the instrumented programs so their
# per-binary .pgc files are available beside the corresponding .pgd files.
option(BRLCAD_PGO "Enable profile-guided optimization (set PGO_PATH environment variable)")
mark_as_advanced(BRLCAD_PGO)
+1
View File
@@ -108,6 +108,7 @@ set(
probe_validation/README.md
probe_validation/CMakeLists.txt
probe_validation/probe_validation.cpp
scripts/pgo_benchmark.cmake
scripts/printtime.cmake
scripts/tcl_mkindex.cmake
scripts/timestamp.cmake
+435
View File
@@ -0,0 +1,435 @@
# P G O _ B E N C H M A R K . C M A K E
# BRL-CAD
#
# Copyright (c) 2026 United States Government as represented by
# the U.S. Army Research Laboratory.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cmake_minimum_required(VERSION 3.22)
# TRAIN runs the standard benchmark and additional geometry, then verifies
# that compiler profile counters were produced. COMPARE runs the standard
# benchmark from baseline and profile-use build trees and requires its
# equal-weight mean speedup to exceed PGO_MIN_SPEEDUP. The training model
# list accepts build-relative or absolute paths, so external model sets can be
# supplied without changing this script.
#
# Required inputs:
# TRAIN: PGO_BUILD_DIR, PGO_RESULTS_DIR, PGO_PROFILE_DIR
# COMPARE: PGO_BASELINE_BUILD_DIR, PGO_OPTIMIZED_BUILD_DIR,
# PGO_RESULTS_DIR
set(_pgo_valid_modes TRAIN COMPARE)
if(NOT DEFINED PGO_MODE)
message(FATAL_ERROR "PGO_MODE must be TRAIN or COMPARE")
endif()
string(TOUPPER "${PGO_MODE}" PGO_MODE)
if(NOT PGO_MODE IN_LIST _pgo_valid_modes)
message(FATAL_ERROR "PGO_MODE must be TRAIN or COMPARE, not '${PGO_MODE}'")
endif()
set(_pgo_default_models moss world star bldg391 m35 sphflake)
set(
_pgo_default_training_models
share/db/havoc.g
share/db/faa/Generic_Twin.g
share/db/nist/NIST_MBE_PMI_2.g
)
if(NOT DEFINED PGO_MODELS)
set(PGO_MODELS ${_pgo_default_models})
endif()
if(NOT DEFINED PGO_TRAINING_MODELS)
set(PGO_TRAINING_MODELS ${_pgo_default_training_models})
endif()
if(NOT DEFINED PGO_TIMEFRAME)
set(PGO_TIMEFRAME 8)
endif()
if(NOT DEFINED PGO_MAXTIME)
set(PGO_MAXTIME 60)
endif()
if(NOT DEFINED PGO_AVERAGE)
set(PGO_AVERAGE 3)
endif()
if(NOT DEFINED PGO_DEVIATION)
set(PGO_DEVIATION 3)
endif()
if(NOT DEFINED PGO_TRAINING_SIZE)
set(PGO_TRAINING_SIZE 512)
endif()
if(NOT DEFINED PGO_TRAINING_AZIMUTH)
set(PGO_TRAINING_AZIMUTH 35)
endif()
if(NOT DEFINED PGO_TRAINING_ELEVATION)
set(PGO_TRAINING_ELEVATION 25)
endif()
if(NOT DEFINED PGO_MIN_SPEEDUP)
set(PGO_MIN_SPEEDUP 1.0)
endif()
function(_pgo_require variable_name)
if(NOT DEFINED "${variable_name}" OR "${${variable_name}}" STREQUAL "")
message(FATAL_ERROR "${variable_name} is required for PGO_MODE=${PGO_MODE}")
endif()
endfunction()
function(_pgo_absolute_path input_path output_variable)
get_filename_component(_pgo_path "${input_path}" ABSOLUTE)
file(TO_CMAKE_PATH "${_pgo_path}" _pgo_path)
set("${output_variable}" "${_pgo_path}" PARENT_SCOPE)
endfunction()
function(_pgo_cache_value build_directory variable_name output_variable)
set(_pgo_cache_file "${build_directory}/CMakeCache.txt")
if(NOT EXISTS "${_pgo_cache_file}")
message(FATAL_ERROR "CMake cache does not exist: ${_pgo_cache_file}")
endif()
file(
STRINGS
"${_pgo_cache_file}"
_pgo_cache_entry
LIMIT_COUNT 1
REGEX "^${variable_name}(:[^=]*)?="
)
if(_pgo_cache_entry)
string(REGEX REPLACE "^[^=]*=" "" _pgo_value "${_pgo_cache_entry}")
else()
set(_pgo_value "")
endif()
set("${output_variable}" "${_pgo_value}" PARENT_SCOPE)
endfunction()
function(_pgo_validate_build build_directory expected_pgo expected_msvc_phase)
_pgo_cache_value("${build_directory}" BRLCAD_PGO _pgo_enabled)
if(expected_pgo AND NOT _pgo_enabled)
message(FATAL_ERROR "BRLCAD_PGO is not enabled in ${build_directory}")
elseif(NOT expected_pgo AND _pgo_enabled)
message(FATAL_ERROR "The baseline build unexpectedly enables BRLCAD_PGO: ${build_directory}")
endif()
_pgo_cache_value("${build_directory}" BRLCAD_MSVC_PGO_PHASE _pgo_msvc_phase)
if(_pgo_msvc_phase AND NOT _pgo_msvc_phase STREQUAL expected_msvc_phase)
message(
FATAL_ERROR
"Expected MSVC PGO phase ${expected_msvc_phase} in ${build_directory}, found ${_pgo_msvc_phase}"
)
endif()
endfunction()
function(_pgo_find_build_file build_directory file_name output_variable)
set(_pgo_candidates "${build_directory}/bin/${file_name}")
if(DEFINED PGO_CONFIG AND NOT "${PGO_CONFIG}" STREQUAL "")
list(
APPEND
_pgo_candidates
"${build_directory}/bin/${PGO_CONFIG}/${file_name}"
"${build_directory}/${PGO_CONFIG}/bin/${file_name}"
)
endif()
if(CMAKE_HOST_WIN32)
set(_pgo_executable_candidates "")
foreach(_pgo_candidate IN LISTS _pgo_candidates)
list(APPEND _pgo_executable_candidates "${_pgo_candidate}.exe")
endforeach()
list(APPEND _pgo_candidates ${_pgo_executable_candidates})
endif()
foreach(_pgo_candidate IN LISTS _pgo_candidates)
if(EXISTS "${_pgo_candidate}")
set("${output_variable}" "${_pgo_candidate}" PARENT_SCOPE)
return()
endif()
endforeach()
message(FATAL_ERROR "Could not find ${file_name} under ${build_directory}/bin")
endfunction()
function(_pgo_find_shell build_directory output_variable)
if(DEFINED PGO_SHELL AND NOT "${PGO_SHELL}" STREQUAL "")
set(_pgo_shell "${PGO_SHELL}")
elseif(EXISTS "${build_directory}/CMakeCache.txt")
file(
STRINGS
"${build_directory}/CMakeCache.txt"
_pgo_shell_cache_entry
LIMIT_COUNT 1
REGEX "^SH_EXEC(:[^=]*)?="
)
if(_pgo_shell_cache_entry)
string(REGEX REPLACE "^[^=]*=" "" _pgo_shell "${_pgo_shell_cache_entry}")
endif()
endif()
if(NOT DEFINED _pgo_shell OR "${_pgo_shell}" STREQUAL "" OR NOT EXISTS "${_pgo_shell}")
unset(_pgo_shell)
unset(_pgo_shell CACHE)
find_program(_pgo_shell NAMES sh bash)
endif()
if(NOT _pgo_shell)
message(FATAL_ERROR "The BRL-CAD benchmark requires a POSIX shell; set PGO_SHELL to its path")
endif()
set("${output_variable}" "${_pgo_shell}" PARENT_SCOPE)
endfunction()
function(_pgo_run_benchmark build_directory result_directory)
_pgo_find_build_file("${build_directory}" benchmark _pgo_benchmark)
_pgo_find_build_file("${build_directory}" rt _pgo_rt)
_pgo_find_build_file("${build_directory}" pixcmp _pgo_pixcmp)
_pgo_find_shell("${build_directory}" _pgo_shell)
file(MAKE_DIRECTORY "${result_directory}")
message(STATUS "Running the BRL-CAD benchmark from ${build_directory}")
execute_process(
COMMAND
"${_pgo_shell}" "${_pgo_benchmark}" run
"TIMEFRAME=${PGO_TIMEFRAME}"
"MAXTIME=${PGO_MAXTIME}"
"AVERAGE=${PGO_AVERAGE}"
"DEVIATION=${PGO_DEVIATION}"
"RT=${_pgo_rt}"
"CMP=${_pgo_pixcmp}"
-P1
WORKING_DIRECTORY "${result_directory}"
RESULT_VARIABLE _pgo_benchmark_result
)
if(NOT "${_pgo_benchmark_result}" STREQUAL "0")
message(FATAL_ERROR "The benchmark from ${build_directory} failed with status ${_pgo_benchmark_result}")
endif()
endfunction()
function(_pgo_extract_rate log_file output_text output_integer)
if(NOT EXISTS "${log_file}")
message(FATAL_ERROR "Benchmark log does not exist: ${log_file}")
endif()
file(READ "${log_file}" _pgo_log)
string(REGEX MATCHALL "[0-9]+(\\.[0-9]+)? rays/sec \\(RTFM\\)" _pgo_rate_lines "${_pgo_log}")
if(NOT _pgo_rate_lines)
message(FATAL_ERROR "No RTFM result was found in ${log_file}")
endif()
list(GET _pgo_rate_lines -1 _pgo_rate_line)
string(REGEX REPLACE " rays/sec.*$" "" _pgo_rate "${_pgo_rate_line}")
if(NOT _pgo_rate MATCHES "^([0-9]+)(\\.([0-9]+))?$")
message(FATAL_ERROR "Invalid RTFM result '${_pgo_rate}' in ${log_file}")
endif()
set(_pgo_whole "${CMAKE_MATCH_1}")
set(_pgo_fraction "${CMAKE_MATCH_3}00")
string(SUBSTRING "${_pgo_fraction}" 0 2 _pgo_fraction)
string(REGEX REPLACE "^0+" "" _pgo_whole "${_pgo_whole}")
string(REGEX REPLACE "^0+" "" _pgo_fraction "${_pgo_fraction}")
if("${_pgo_whole}" STREQUAL "")
set(_pgo_whole 0)
endif()
if("${_pgo_fraction}" STREQUAL "")
set(_pgo_fraction 0)
endif()
math(EXPR _pgo_rate_integer "${_pgo_whole} * 100 + ${_pgo_fraction}")
if(_pgo_rate_integer LESS_EQUAL 0)
message(FATAL_ERROR "Non-positive RTFM result '${_pgo_rate}' in ${log_file}")
endif()
set("${output_text}" "${_pgo_rate}" PARENT_SCOPE)
set("${output_integer}" "${_pgo_rate_integer}" PARENT_SCOPE)
endfunction()
function(_pgo_decimal_to_thousandths value output_variable)
if(NOT "${value}" MATCHES "^([0-9]+)(\\.([0-9]+))?$")
message(FATAL_ERROR "Expected a non-negative decimal number, not '${value}'")
endif()
set(_pgo_whole "${CMAKE_MATCH_1}")
set(_pgo_fraction "${CMAKE_MATCH_3}000")
string(SUBSTRING "${_pgo_fraction}" 0 3 _pgo_fraction)
string(REGEX REPLACE "^0+" "" _pgo_whole "${_pgo_whole}")
string(REGEX REPLACE "^0+" "" _pgo_fraction "${_pgo_fraction}")
if("${_pgo_whole}" STREQUAL "")
set(_pgo_whole 0)
endif()
if("${_pgo_fraction}" STREQUAL "")
set(_pgo_fraction 0)
endif()
math(EXPR _pgo_value "${_pgo_whole} * 1000 + ${_pgo_fraction}")
set("${output_variable}" "${_pgo_value}" PARENT_SCOPE)
endfunction()
function(_pgo_format_thousandths value output_variable)
math(EXPR _pgo_whole "${value} / 1000")
math(EXPR _pgo_fraction "${value} % 1000")
set(_pgo_fraction "00${_pgo_fraction}")
string(LENGTH "${_pgo_fraction}" _pgo_fraction_length)
math(EXPR _pgo_fraction_offset "${_pgo_fraction_length} - 3")
string(SUBSTRING "${_pgo_fraction}" ${_pgo_fraction_offset} 3 _pgo_fraction)
set("${output_variable}" "${_pgo_whole}.${_pgo_fraction}" PARENT_SCOPE)
endfunction()
if(PGO_MODE STREQUAL "TRAIN")
_pgo_require(PGO_BUILD_DIR)
_pgo_require(PGO_RESULTS_DIR)
_pgo_require(PGO_PROFILE_DIR)
_pgo_absolute_path("${PGO_BUILD_DIR}" PGO_BUILD_DIR)
_pgo_absolute_path("${PGO_RESULTS_DIR}" PGO_RESULTS_DIR)
_pgo_absolute_path("${PGO_PROFILE_DIR}" PGO_PROFILE_DIR)
if(NOT IS_DIRECTORY "${PGO_BUILD_DIR}")
message(FATAL_ERROR "PGO_BUILD_DIR does not exist: ${PGO_BUILD_DIR}")
endif()
_pgo_validate_build("${PGO_BUILD_DIR}" TRUE GENERATE)
# MSVC's profile runtime uses this location for each image's PGC files.
# GCC ignores it and writes its GCDA files to the compiled-in PGO path.
file(MAKE_DIRECTORY "${PGO_PROFILE_DIR}")
set(ENV{VCPROFILE_PATH} "${PGO_PROFILE_DIR}")
_pgo_run_benchmark("${PGO_BUILD_DIR}" "${PGO_RESULTS_DIR}/benchmark")
_pgo_find_build_file("${PGO_BUILD_DIR}" rt _pgo_rt)
if(CMAKE_HOST_WIN32)
set(_pgo_null_device NUL)
else()
set(_pgo_null_device /dev/null)
endif()
set(_pgo_training_index 0)
foreach(_pgo_model IN LISTS PGO_TRAINING_MODELS)
math(EXPR _pgo_training_index "${_pgo_training_index} + 1")
if(IS_ABSOLUTE "${_pgo_model}")
set(_pgo_model_path "${_pgo_model}")
else()
set(_pgo_model_path "${PGO_BUILD_DIR}/${_pgo_model}")
endif()
if(NOT EXISTS "${_pgo_model_path}")
message(FATAL_ERROR "Training model does not exist: ${_pgo_model_path}")
endif()
get_filename_component(_pgo_log_name "${_pgo_model_path}" NAME_WE)
string(REGEX REPLACE "[^A-Za-z0-9_.-]" "_" _pgo_log_name "${_pgo_log_name}")
set(_pgo_log_file "${PGO_RESULTS_DIR}/${_pgo_training_index}-${_pgo_log_name}.log")
message(STATUS "Training with ${_pgo_model_path}")
execute_process(
COMMAND
"${_pgo_rt}" -B -P1 "-s${PGO_TRAINING_SIZE}"
"-a${PGO_TRAINING_AZIMUTH}" "-e${PGO_TRAINING_ELEVATION}"
-o "${_pgo_null_device}" "${_pgo_model_path}"
RESULT_VARIABLE _pgo_rt_result
OUTPUT_VARIABLE _pgo_rt_output
ERROR_VARIABLE _pgo_rt_error
)
file(WRITE "${_pgo_log_file}" "${_pgo_rt_output}${_pgo_rt_error}")
if(NOT "${_pgo_rt_result}" STREQUAL "0")
message(FATAL_ERROR "Training ${_pgo_model} failed with status ${_pgo_rt_result}; see ${_pgo_log_file}")
endif()
string(REGEX MATCH "[^\r\n]*rays/sec \\(RTFM\\)" _pgo_rtfm_line "${_pgo_rt_output}${_pgo_rt_error}")
if(NOT _pgo_rtfm_line)
message(FATAL_ERROR "Training ${_pgo_model} did not complete a raytrace; see ${_pgo_log_file}")
endif()
message(STATUS "${_pgo_model}: ${_pgo_rtfm_line}")
endforeach()
file(GLOB_RECURSE _pgo_gcda_files LIST_DIRECTORIES FALSE "${PGO_PROFILE_DIR}/*.gcda")
file(GLOB_RECURSE _pgo_pgc_files LIST_DIRECTORIES FALSE "${PGO_PROFILE_DIR}/*.pgc")
list(LENGTH _pgo_gcda_files _pgo_gcda_count)
list(LENGTH _pgo_pgc_files _pgo_pgc_count)
math(EXPR _pgo_profile_count "${_pgo_gcda_count} + ${_pgo_pgc_count}")
if(_pgo_profile_count EQUAL 0)
message(FATAL_ERROR "Training did not generate GCC GCDA or MSVC PGC data under ${PGO_PROFILE_DIR}")
endif()
message(STATUS "Training generated ${_pgo_profile_count} profile counter files under ${PGO_PROFILE_DIR}")
else()
_pgo_require(PGO_BASELINE_BUILD_DIR)
_pgo_require(PGO_OPTIMIZED_BUILD_DIR)
_pgo_require(PGO_RESULTS_DIR)
_pgo_absolute_path("${PGO_BASELINE_BUILD_DIR}" PGO_BASELINE_BUILD_DIR)
_pgo_absolute_path("${PGO_OPTIMIZED_BUILD_DIR}" PGO_OPTIMIZED_BUILD_DIR)
_pgo_absolute_path("${PGO_RESULTS_DIR}" PGO_RESULTS_DIR)
_pgo_validate_build("${PGO_BASELINE_BUILD_DIR}" FALSE "")
_pgo_validate_build("${PGO_OPTIMIZED_BUILD_DIR}" TRUE USE)
_pgo_run_benchmark("${PGO_BASELINE_BUILD_DIR}" "${PGO_RESULTS_DIR}/baseline")
_pgo_run_benchmark("${PGO_OPTIMIZED_BUILD_DIR}" "${PGO_RESULTS_DIR}/optimized")
set(_pgo_report "### Profile-guided optimization results\n\n")
string(APPEND _pgo_report "| Model | Baseline rays/sec | PGO rays/sec | Speedup |\n")
string(APPEND _pgo_report "| --- | ---: | ---: | ---: |\n")
set(_pgo_speedup_sum 0)
set(_pgo_model_count 0)
set(_pgo_tsv "model\tbaseline_rays_per_second\tpgo_rays_per_second\tspeedup\n")
foreach(_pgo_model IN LISTS PGO_MODELS)
_pgo_extract_rate("${PGO_RESULTS_DIR}/baseline/${_pgo_model}.log" _pgo_baseline_rate _pgo_baseline_integer)
_pgo_extract_rate("${PGO_RESULTS_DIR}/optimized/${_pgo_model}.log" _pgo_optimized_rate _pgo_optimized_integer)
math(
EXPR
_pgo_speedup
"(${_pgo_optimized_integer} * 1000 + ${_pgo_baseline_integer} / 2) / ${_pgo_baseline_integer}"
)
_pgo_format_thousandths("${_pgo_speedup}" _pgo_speedup_text)
math(EXPR _pgo_speedup_sum "${_pgo_speedup_sum} + ${_pgo_speedup}")
math(EXPR _pgo_model_count "${_pgo_model_count} + 1")
string(
APPEND
_pgo_report
"| `${_pgo_model}` | ${_pgo_baseline_rate} | ${_pgo_optimized_rate} | ${_pgo_speedup_text}x |\n"
)
string(
APPEND
_pgo_tsv
"${_pgo_model}\t${_pgo_baseline_rate}\t${_pgo_optimized_rate}\t${_pgo_speedup_text}\n"
)
endforeach()
if(_pgo_model_count EQUAL 0)
message(FATAL_ERROR "PGO_MODELS must name at least one benchmark model")
endif()
math(EXPR _pgo_mean_speedup "(${_pgo_speedup_sum} + ${_pgo_model_count} / 2) / ${_pgo_model_count}")
_pgo_format_thousandths("${_pgo_mean_speedup}" _pgo_mean_speedup_text)
string(APPEND _pgo_report "\nArithmetic mean speedup: ${_pgo_mean_speedup_text}x\n")
file(MAKE_DIRECTORY "${PGO_RESULTS_DIR}")
file(WRITE "${PGO_RESULTS_DIR}/results.tsv" "${_pgo_tsv}")
if(DEFINED PGO_SUMMARY_FILE AND NOT "${PGO_SUMMARY_FILE}" STREQUAL "")
_pgo_absolute_path("${PGO_SUMMARY_FILE}" _pgo_summary_file)
elseif(NOT "$ENV{GITHUB_STEP_SUMMARY}" STREQUAL "")
set(_pgo_summary_file "$ENV{GITHUB_STEP_SUMMARY}")
endif()
if(DEFINED _pgo_summary_file)
file(APPEND "${_pgo_summary_file}" "${_pgo_report}")
endif()
message("${_pgo_report}")
_pgo_decimal_to_thousandths("${PGO_MIN_SPEEDUP}" _pgo_min_speedup)
if(NOT _pgo_mean_speedup GREATER _pgo_min_speedup)
message(
FATAL_ERROR
"PGO raytracing speedup ${_pgo_mean_speedup_text}x did not exceed ${PGO_MIN_SPEEDUP}x"
)
endif()
endif()
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+35 -19
View File
@@ -7,14 +7,25 @@
set -e
set -o pipefail
# Note: we set these variables to tell the ccc-analyzer script which compilers
# to use, but it is not always enough - when some of the sub-builds are
# triggered, they do not seem to inherit these settings and revert to the
# default compiler. The only way so far to avoid this issue reliably seems to
# be to edit the ccc-analyzer script to use the compiler we want as the default
# compiler.
export CCC_CC=clang
export CCC_CXX=clang++
# CLANG_VERSION should be set by User or CI environments to avoid hard-coding
# a particular version into the script
if [ -z "$CLANG_VERSION" ]; then
echo "Error: CLANG_VERSION environment variable is not set." >&2
exit 1
fi
# Derive tool paths from the version
SCAN_BUILD_DIR="/usr/share/clang/scan-build-${CLANG_VERSION}"
SCAN_BUILD_BIN="${SCAN_BUILD_DIR}/bin"
SCAN_BUILD_LIBEXEC="${SCAN_BUILD_DIR}/libexec"
CLANG_ANALYZER_BIN="/usr/bin/clang-${CLANG_VERSION}"
# Add scan-build to the PATH
export PATH="${SCAN_BUILD_BIN}:${SCAN_BUILD_LIBEXEC}:${PATH}"
# Set compilers for the analyzer scripts
export CCC_CC="clang-${CLANG_VERSION}"
export CCC_CXX="clang++-${CLANG_VERSION}"
# This appears to be a workable way to enable the new Z3 static analyzer
# support, but at least as of 2017-12 it greatly slows the testing (by orders
@@ -45,19 +56,24 @@ fi
# Encapsulate the logic to do a scan build
function runtest {
echo "$1"
scan-build --use-analyzer=/usr/bin/$CCC_CC -o ./scan-reports-$1 make -j12 $1
if [ "$(ls -A ./scan-reports-$1)" ]; then
report_cnt=$(ls -l ./scan-reports-$1/*/report* | wc -l)
failure=$(($failure + $report_cnt))
else
rm -rf ./scan-reports-$1
fi
echo "$1"
scan-build --use-analyzer="${CLANG_ANALYZER_BIN}" -o "./scan-reports-$1" make -j12 "$1"
if [ -d "./scan-reports-$1" ] && [ -n "$(ls -A "./scan-reports-$1")" ]; then
report_cnt=$(find "./scan-reports-$1" -name 'report-*.html' | wc -l)
failure=$((failure + report_cnt))
else
rm -rf "./scan-reports-$1"
fi
}
# configure using the correct compiler and values. We don't
# need this report, so clear it after configure is done
scan-build --use-analyzer=/usr/bin/$CCC_CC -o ./scan-reports-config cmake .. -DBRLCAD_EXTRADOCS=OFF -DBRLCAD_ENABLE_QT=ON -DBRLCAD_LTO_MODE=OFF -DBRLCAD_EXT_DIR="$bext_dir" -DCMAKE_C_COMPILER=ccc-analyzer -DCMAKE_CXX_COMPILER=c++-analyzer
# Configure using the correct compiler and values.
scan-build --use-analyzer="${CLANG_ANALYZER_BIN}" -o ./scan-reports-config cmake .. \
-DBRLCAD_EXTRADOCS=OFF \
-DBRLCAD_ENABLE_QT=ON \
-DBRLCAD_LTO_MODE=OFF \
-DBRLCAD_EXT_DIR="$bext_dir" \
-DCMAKE_C_COMPILER=ccc-analyzer \
-DCMAKE_CXX_COMPILER=c++-analyzer
# clear out any old reports
rm -rfv ./scan-reports-*
+10
View File
@@ -109,6 +109,16 @@ brlcad_addexec(g-var g-var.c "librt;libbu;${M_LIBRARY}" FOLDER Conv)
brlcad_addexec(g-vrml g-vrml.c "librt;libnmg;libbu;${M_LIBRARY}" FOLDER Conv)
brlcad_addexec(g-x3d g-x3d.c "librt;libnmg;libbu;${M_LIBRARY}" FOLDER Conv)
# GCC cannot model BU_SETJUMP's longjmp path during LTO and reports an
# anonymous value as potentially uninitialized.
check_linker_flag(
"C"
"-Wno-error=maybe-uninitialized"
G_X3D_LINKER_WNO_MAYBE_UNINITIALIZED
)
if(G_X3D_LINKER_WNO_MAYBE_UNINITIALIZED)
target_link_options(g-x3d PRIVATE -Wno-maybe-uninitialized)
endif()
brlcad_addexec(nastran-g nastran-g.c "libwdb;librt;libnmg;libbu;${M_LIBRARY}" FOLDER Conv)
+6 -6
View File
@@ -326,7 +326,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) {
/* -------------------------------------------------------------------- */
/* Initialize the info structure. */
/* -------------------------------------------------------------------- */
SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1));
SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(1,sizeof(SHPInfo)));
psSHP->bUpdated = FALSE;
memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
@@ -1176,7 +1176,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
psObject->nParts = MAX(1,nParts);
psObject->panPartStart = STATIC_CAST(int *,
calloc(sizeof(int), psObject->nParts));
calloc(psObject->nParts, sizeof(int)));
psObject->panPartType = STATIC_CAST(int *,
malloc(sizeof(int) * psObject->nParts));
@@ -1205,13 +1205,13 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
{
const size_t nSize = sizeof(double) * nVertices;
psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) :
calloc(sizeof(double),nVertices));
calloc(nVertices,sizeof(double)));
psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) :
calloc(sizeof(double),nVertices));
calloc(nVertices,sizeof(double)));
psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) :
calloc(sizeof(double),nVertices));
calloc(nVertices,sizeof(double)));
psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) :
calloc(sizeof(double),nVertices));
calloc(nVertices,sizeof(double)));
if( padfX != SHPLIB_NULLPTR )
memcpy(psObject->padfX, padfX, nSize);
if( padfY != SHPLIB_NULLPTR )
+2 -2
View File
@@ -5545,8 +5545,8 @@ repair_ambiguous_singular_periodic_loop_branches(ON_Brep *brep,
std::vector<int> affected_positions;
affected_positions.reserve(arc_positions.size() + 2);
affected_positions.push_back(first_position);
affected_positions.insert(affected_positions.end(),
arc_positions.begin(), arc_positions.end());
for (const int position : arc_positions)
affected_positions.push_back(position);
affected_positions.push_back(second_position);
for (int shift_sign = -1; shift_sign <= 1 && !repaired;
+20 -16
View File
@@ -50,16 +50,16 @@
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
void SHA1Transform(uint32_t state[5], const unsigned char buffer[SHA1_BLOCK_SIZE])
{
uint32_t a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned char c[SHA1_BLOCK_SIZE];
uint32_t l[16];
} CHAR64LONG16;
#ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
memcpy(block, buffer, 64);
memcpy(block, buffer, sizeof(block));
#else
/* The following had better never be used because it causes the
* pointer-to-const buffer to be cast into a pointer to non-const.
@@ -131,11 +131,11 @@ void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len)
if ((context->count[0] += len << 3) < j)
context->count[1]++;
context->count[1] += (len>>29);
j = (j >> 3) & 63;
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
j = (j >> 3) & (SHA1_BLOCK_SIZE - 1);
if ((j + len) >= SHA1_BLOCK_SIZE) {
memcpy(&context->buffer[j], data, (i = SHA1_BLOCK_SIZE-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
for ( ; i + SHA1_BLOCK_SIZE - 1 < len; i += SHA1_BLOCK_SIZE) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
@@ -149,22 +149,26 @@ void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len)
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
{
unsigned i;
static const unsigned char padding[SHA1_BLOCK_SIZE] = {0x80};
unsigned char finalcount[8];
unsigned char c;
const uint32_t block_size = (uint32_t)sizeof(context->buffer);
const uint32_t length_offset = block_size - (uint32_t)sizeof(finalcount);
uint32_t buffer_used;
uint32_t padding_length;
unsigned i;
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
c = 0200;
SHA1Update(context, &c, 1);
while ((context->count[0] & 504) != 448) {
c = 0000;
SHA1Update(context, &c, 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
buffer_used = (context->count[0] >> 3) & (block_size - 1);
if (buffer_used < length_offset)
padding_length = length_offset - buffer_used;
else
padding_length = block_size + length_offset - buffer_used;
SHA1Update(context, padding, padding_length);
SHA1Update(context, finalcount, (uint32_t)sizeof(finalcount));
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+4 -2
View File
@@ -7,15 +7,17 @@
#include "common.h"
#define SHA1_BLOCK_SIZE 64
typedef struct {
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
unsigned char buffer[SHA1_BLOCK_SIZE];
} SHA1_CTX;
__BEGIN_DECLS
void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
void SHA1Transform(uint32_t state[5], const unsigned char buffer[SHA1_BLOCK_SIZE]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+1 -1
View File
@@ -46,7 +46,7 @@ extern double drand48(void);
int
bu_uuid_create(uint8_t uuid[STATIC_ARRAY(16)], size_t nbytes, const uint8_t *bytes, const uint8_t namespace_uuid[STATIC_ARRAY(16)])
bu_uuid_create(uint8_t uuid[STATIC_ARRAY(16)], size_t nbytes, const uint8_t *bytes, const uint8_t *namespace_uuid)
{
int type = 4; /* random */
+4 -4
View File
@@ -934,7 +934,7 @@ x24_setup(struct fb *ifp, int width, int height)
case FLG_VP8:
case FLG_VS8:
case FLG_VG8:
if ((xi->xi_pix = (unsigned char *) calloc(sizeof(uint8_t), width*height)) == NULL) {
if ((xi->xi_pix = (unsigned char *) calloc(width*height, sizeof(uint8_t))) == NULL) {
fb_log("X24_open: pix8 malloc failed\n");
return -1;
}
@@ -950,7 +950,7 @@ x24_setup(struct fb *ifp, int width, int height)
xi->xi_visual, xi->xi_depth, XYBitmap, 0,
NULL, width, height, 32, 0);
if ((xi->xi_pix = (unsigned char *) calloc(sizeof(uint8_t), xi->xi_image->bytes_per_line * height)) == NULL) {
if ((xi->xi_pix = (unsigned char *) calloc(xi->xi_image->bytes_per_line * height, sizeof(uint8_t))) == NULL) {
fb_log("X24_open: pix1 malloc failed\n");
return -1;
}
@@ -2653,7 +2653,7 @@ X24_configureWindow(struct fb *ifp, int width, int height)
XDestroyImage(xi->xi_image);
/* Make new buffers and new image */
if ((xi->xi_pix = (unsigned char *)calloc(sizeof(uint8_t), xi->xi_xwidth * xi->xi_xheight)) == NULL) {
if ((xi->xi_pix = (unsigned char *)calloc(xi->xi_xwidth * xi->xi_xheight, sizeof(uint8_t))) == NULL) {
fb_log("X24: pix8 malloc failed in resize!\n");
return 1;
}
@@ -2671,7 +2671,7 @@ X24_configureWindow(struct fb *ifp, int width, int height)
xi->xi_visual, xi->xi_depth, XYBitmap, 0,
NULL, xi->xi_xwidth, xi->xi_xheight, 32, 0);
if ((xi->xi_pix = (unsigned char *)calloc(sizeof(uint8_t), xi->xi_image->bytes_per_line * xi->xi_xheight)) == NULL) {
if ((xi->xi_pix = (unsigned char *)calloc(xi->xi_image->bytes_per_line * xi->xi_xheight, sizeof(uint8_t))) == NULL) {
fb_log("X24: pix1 malloc failed in resize!\n");
return 1;
}
+2 -2
View File
@@ -422,12 +422,12 @@ fb_open(const char *file, int width, int height)
if (width < 0 || height < 0)
return FB_NULL;
ifp = (struct fb *)calloc(sizeof(struct fb), 1);
ifp = (struct fb *)calloc(1, sizeof(struct fb));
if (ifp == FB_NULL) {
Malloc_Bomb(sizeof(struct fb));
return FB_NULL;
}
ifp->i = (struct fb_impl *)calloc(sizeof(struct fb_impl), 1);
ifp->i = (struct fb_impl *)calloc(1, sizeof(struct fb_impl));
if (file == NULL || *file == '\0') {
/* No name given, check environment variable first. */
file = (const char *)getenv("FB_FILE");
+2 -2
View File
@@ -114,8 +114,8 @@ struct fb *
fb_open_existing(const char *file, int width, int height, struct fb_platform_specific *fb_p)
{
struct fb *ifp;
ifp = (struct fb *)calloc(sizeof(struct fb), 1);
ifp->i = (struct fb_impl *) calloc(sizeof(struct fb_impl), 1);
ifp = (struct fb *)calloc(1, sizeof(struct fb));
ifp->i = (struct fb_impl *) calloc(1, sizeof(struct fb_impl));
fb_set_interface(ifp, file);
fb_set_magic(ifp, FB_MAGIC);
fb_setup_existing(ifp, width, height, fb_p);
+2 -2
View File
@@ -111,7 +111,7 @@ hlbvh_init_pool(size_t n_primatives) {
}
/* utility functions */
static inline uint32_t left_shift3(uint32_t x)
static uint32_t left_shift3(uint32_t x)
{
BU_ASSERT(x <= (1 << 10));
if (x == (1 << 10)) --x;
@@ -299,7 +299,7 @@ maximum_extent(const fastf_t b[6])
return 2;
}
static inline int
static int
pred(const struct bvh_build_node *node, fastf_t *centroid_bounds,
uint8_t dim, long min_cost_split_bucket)
{
+1 -1
View File
@@ -730,7 +730,7 @@ bot_makesegs_specific(hit_da *hits,
/* r_min can describe a spatial partition cell that begins inside this
* solid. Start BVH traversal just before the ray enters the BoT's own
* root box so entrance triangles behind the ray origin remain visible. */
static inline void
static void
bot_backed_origin(point_t b_pt, const struct xray *rp, const struct bvh_flat_node *root,
const vect_t inv_dir, const struct soltab *stp)
{
+1 -1
View File
@@ -517,7 +517,7 @@ rt_metaball_vshot(struct soltab *stp[], struct xray *rp[], struct seg *segp, int
}
inline void
static void
rt_metaball_norm_internal(vect_t *n, point_t *p, struct rt_metaball_internal *mb)
{
struct wdb_metaball_pnt *mbpt;
-1
View File
@@ -27,7 +27,6 @@ __BEGIN_DECLS
int rt_metaball_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *tol);
fastf_t rt_metaball_get_bounding_sphere(point_t *center, fastf_t threshold, struct rt_metaball_internal *mb);
int rt_metaball_find_intersection(point_t *intersect, const struct rt_metaball_internal *mb, const point_t *a, const point_t *b, fastf_t step, const fastf_t finalstep);
void rt_metaball_norm_internal(vect_t *n, point_t *p, struct rt_metaball_internal *mb);
__END_DECLS
#endif /* LIBRT_PRIMITIVES_METABALL_METABALL_H */
+1 -1
View File
@@ -33,7 +33,7 @@
#define PART_SPHERE_HEIGHT_RATIO 0.001
#define PART_CYLINDER_RADIUS_RATIO 0.001
static inline int
static int
part_update_type(struct rt_part_internal *part)
{
if (!part || !isfinite(part->part_vrad) ||
+1 -1
View File
@@ -337,7 +337,7 @@ main(int ac, char *av[])
unsigned char ground_rgb[3];
unsigned char light_rgb[3];
double pitch_r[MAX_GEARS];
double pitch_r[MAX_GEARS] = {0.0};
double center_x[MAX_GEARS];
double total_span;
double max_outer;