Build Packages / Create release (push) Successful in 16s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 8m27s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m15s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m11s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m6s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m44s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m1s
Build Packages / build:windows:nocuda (push) Successful in 17m29s
Build Packages / build:windows:cuda (push) Successful in 19m58s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 24m7s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m8s
Build Packages / build:rugnux:windows (push) Successful in 10m58s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 20m46s
Build Packages / Generate python client (push) Successful in 53s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m13s
Build Packages / Build documentation (push) Successful in 1m36s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m57s
Build Packages / build:rpm (rocky8) (push) Successful in 18m7s
Build Packages / build:rpm (rocky9) (push) Successful in 18m54s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 19m32s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 17m30s
Build Packages / Unit tests (push) Successful in 1h39m2s
* Fixed `jfjoch_broker` cancelling every data collection with a CUDA "out of memory" error after long operation: GPU memory no longer leaks with each collection. * Rugnux scales a rotation sweep until the per-frame scales settle instead of for a fixed three rounds, and says so when they did not - merged intensities, and the space group, resolution cut and frame rejection read off them, change accordingly; `--scaling-iterations` is now the cap on that loop (default 100). * Rugnux places every frame of a marCCD, SMV or miniCBF series at the spindle angle its own header states, so a series with missing frames, or with angles written modulo 360, is no longer read at the wrong geometry or refused. * Every rotation run writes two diagnostic files beside its reflections: `<prefix>_detector.jpg`, the detector projection with the pixel mask and the detected beam-stop shadow drawn on it, and `<prefix>_plot.txt`, one row per image. Reviewed-on: #82 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
127 lines
6.9 KiB
CMake
127 lines
6.9 KiB
CMake
# Eigen has to be resolved BEFORE Ceres is added below. Whichever find_package(Eigen3) runs first
|
|
# creates the Eigen3::Eigen imported target, and every later one leaves an existing target alone --
|
|
# so the first one wins for the whole build, Ceres included. See the guard after Ceres for why that
|
|
# matters here.
|
|
FIND_PACKAGE(Eigen3 3.4 REQUIRED NO_MODULE) # provides Eigen3::Eigen
|
|
|
|
SET(PROVIDE_UNINSTALL_TARGET OFF)
|
|
# Force Ceres to build WITHOUT its own CUDA support: Jungfraujoch never uses Ceres' GPU solvers, so
|
|
# this just drops unused code and build time (Ceres would otherwise enable CUDA whenever a toolkit is
|
|
# found). See the Eigen note in the top-level CMakeLists for the related Windows/cmake history.
|
|
SET(USE_CUDA OFF CACHE BOOL "Force Ceres to build without CUDA (Jungfraujoch does not use Ceres' GPU solvers)" FORCE)
|
|
|
|
# Ceres' sparse and LAPACK back-ends are dead weight here: every Ceres solve in this project picks a
|
|
# DENSE solver explicitly (DENSE_QR / DENSE_NORMAL_CHOLESKY / DENSE_SCHUR) and none sets
|
|
# dense_linear_algebra_library_type, which defaults to EIGEN -- so no sparse factorization and no
|
|
# LAPACK call is ever reachable. Left at their defaults they cost rugnux six shared libraries
|
|
# (libopenblas, libmetis, and libgfortran/libquadmath/libgomp/libz behind them), and SuiteSparse
|
|
# turns itself on or off depending on what happens to sit on the build host, so two machines build
|
|
# different Ceres from the same source. Pinning all three off leaves the results bit-identical.
|
|
# EIGENSPARSE stays ON: it keeps a sparse implementation available without an external library.
|
|
SET(SUITESPARSE OFF CACHE BOOL "Ceres: no sparse solver is ever selected" FORCE)
|
|
SET(LAPACK OFF CACHE BOOL "Ceres: dense solves go through Eigen, not LAPACK" FORCE)
|
|
SET(EIGENMETIS OFF CACHE BOOL "Ceres: METIS ordering only applies to sparse factorization" FORCE)
|
|
|
|
# Prevent MKL from being found (guarantees no MKL)
|
|
SET(CMAKE_DISABLE_FIND_PACKAGE_MKL TRUE)
|
|
SET(CERES_THREADING_MODEL "CXX_THREADS")
|
|
|
|
# Ceres is the only dependency that needs more than a plain tarball: it carries abseil as a git
|
|
# SUBMODULE, so a source archive leaves third_party/abseil-cpp empty. Ceres tests exactly that
|
|
# directory and, finding it empty, demands find_package(absl REQUIRED 20240116) instead -- which no
|
|
# build image can satisfy (Ubuntu 24.04 still ships 20230802). So populate the two archives
|
|
# separately and hand Ceres the tree a submodule checkout would have produced: abseil unpacked into
|
|
# third_party/abseil-cpp, and only then the subdirectory added.
|
|
#
|
|
# Populate-then-add rather than FetchContent_MakeAvailable(ceres), because MakeAvailable populates
|
|
# and add_subdirectory()s in one step, leaving no window to fill the submodule -- and the URL
|
|
# population clears its source directory, so abseil cannot be put there beforehand.
|
|
#
|
|
# FetchContent_Populate(<name>) is deprecated from CMake 3.30 (CMP0169) in favour of the
|
|
# MakeAvailable that cannot be used here, so ask for the old behaviour rather than let every build
|
|
# on a newer CMake print the deprecation.
|
|
IF (POLICY CMP0169)
|
|
CMAKE_POLICY(PUSH)
|
|
CMAKE_POLICY(SET CMP0169 OLD)
|
|
ENDIF()
|
|
|
|
FetchContent_Declare(
|
|
ceres
|
|
URL https://github.com/ceres-solver/ceres-solver/archive/0c70ed3a1a2d6ba47c06c7e8b3b040880bc474db.tar.gz
|
|
URL_HASH SHA256=bf0bcc78fae884e59dd893693e52510da7cc6866a7444fdae9ba8f19eae266cd
|
|
)
|
|
FetchContent_Populate(ceres)
|
|
|
|
# The exact commit Ceres' submodule points at (abseil lts_2025_01_27), so the tree matches what a
|
|
# recursive clone of the pinned Ceres would have checked out.
|
|
FetchContent_Declare(
|
|
abseil
|
|
URL https://github.com/abseil/abseil-cpp/archive/9ac7062b1860d895fb5a8cbf58c3e9ef8f674b5f.tar.gz
|
|
URL_HASH SHA256=fd5062972ac6c5575bc8fb6fb1cd6e7c563730be96be4c17b8dcca74a9c5892d
|
|
SOURCE_DIR "${ceres_SOURCE_DIR}/third_party/abseil-cpp"
|
|
)
|
|
FetchContent_Populate(abseil)
|
|
|
|
IF (POLICY CMP0169)
|
|
CMAKE_POLICY(POP)
|
|
ENDIF()
|
|
|
|
ADD_SUBDIRECTORY("${ceres_SOURCE_DIR}" "${ceres_BINARY_DIR}" EXCLUDE_FROM_ALL)
|
|
|
|
# Ceres asks for Eigen with a version RANGE -- find_package(Eigen3 3.3.4...5 NO_MODULE) -- and
|
|
# Eigen's own Eigen3ConfigVersion.cmake rejects any range whose two endpoints differ in major
|
|
# version. A 3.4 Eigen therefore reports itself INCOMPATIBLE with Ceres' query and the search falls
|
|
# through to whatever older Eigen comes next on the prefix path (a distro eigen3-devel, say). Having
|
|
# resolved Eigen above, Ceres inherits our Eigen3::Eigen instead, because a generated targets file
|
|
# returns early when its targets already exist. (The config package the top-level CMakeLists writes
|
|
# for the bundled Eigen answers the range as well, so with it Ceres' own query simply succeeds --
|
|
# but an externally provided Eigen still behaves as described.) If that ever stops holding, Ceres compiles against
|
|
# one Eigen and the rest of the project against another; the two versions' identically mangled
|
|
# template instantiations are then merged at link time -- an ODR violation whose symptom is a crash
|
|
# inside Eigen. Refuse to build it.
|
|
GET_PROPERTY(CERES_IMPORTED_TARGETS DIRECTORY ${ceres_SOURCE_DIR} PROPERTY IMPORTED_TARGETS)
|
|
IF ("Eigen3::Eigen" IN_LIST CERES_IMPORTED_TARGETS)
|
|
MESSAGE(FATAL_ERROR "Ceres created an Eigen3::Eigen of its own instead of using the Eigen this "
|
|
"project resolved. Two Eigen versions in one binary is undefined behaviour. Leave a "
|
|
"single Eigen on the find_package path, or point CMAKE_PREFIX_PATH / Eigen3_DIR at the "
|
|
"one to use.")
|
|
ENDIF()
|
|
|
|
ADD_LIBRARY(JFJochImageAnalysis STATIC
|
|
MXAnalysisWithoutFPGA.cpp
|
|
MXAnalysisWithoutFPGA.h
|
|
MXAnalysisAfterFPGA.h
|
|
MXAnalysisAfterFPGA.cpp
|
|
IndexAndRefine.cpp
|
|
IndexAndRefine.h
|
|
dark_mask_analysis/DarkMaskAnalysis.cpp
|
|
dark_mask_analysis/DarkMaskAnalysis.h
|
|
beam_stop/ShadowFinder.cpp
|
|
beam_stop/ShadowFinder.h
|
|
$<$<BOOL:${JFJOCH_CUDA_AVAILABLE}>:beam_stop/ShadowAccumulatorGPU.cu>
|
|
beam_stop/ShadowAccumulatorGPU.h
|
|
rotation_indexer/RotationIndexer.cpp
|
|
rotation_indexer/RotationIndexer.h
|
|
WriteReflections.cpp
|
|
WriteReflections.h
|
|
LoadFCalcFromMtz.cpp
|
|
LoadFCalcFromMtz.h
|
|
UpdateReflectionResolution.cpp
|
|
UpdateReflectionResolution.h
|
|
IntegrationOutcome.h
|
|
rotation_indexer/RotationIndexerCounter.cpp
|
|
rotation_indexer/RotationIndexerCounter.h)
|
|
|
|
ADD_SUBDIRECTORY(spot_finding)
|
|
ADD_SUBDIRECTORY(bragg_integration)
|
|
ADD_SUBDIRECTORY(bragg_prediction)
|
|
ADD_SUBDIRECTORY(indexing)
|
|
ADD_SUBDIRECTORY(geom_refinement)
|
|
ADD_SUBDIRECTORY(lattice_search)
|
|
ADD_SUBDIRECTORY(scale_merge)
|
|
ADD_SUBDIRECTORY(image_preprocessing)
|
|
ADD_SUBDIRECTORY(azint)
|
|
ADD_SUBDIRECTORY(roi)
|
|
|
|
TARGET_LINK_LIBRARIES(JFJochImageAnalysis JFJochAzIntEngine JFJochROIIntegration JFJochImagePreprocessing JFJochBraggPrediction JFJochBraggIntegration JFJochLatticeSearch JFJochIndexing JFJochSpotFinding JFJochCommon JFJochGeomRefinement JFJochScaleMerge gemmi)
|