pysif 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. pysif-0.1.0/.gitignore +18 -0
  2. pysif-0.1.0/CMakeLists.txt +410 -0
  3. pysif-0.1.0/COPYING +674 -0
  4. pysif-0.1.0/PKG-INFO +107 -0
  5. pysif-0.1.0/README.md +87 -0
  6. pysif-0.1.0/include/sif/core/macros.h +604 -0
  7. pysif-0.1.0/include/sif/core/settings.h +103 -0
  8. pysif-0.1.0/include/sif/core/system.h +121 -0
  9. pysif-0.1.0/include/sif/finder/exodus_finder.h +268 -0
  10. pysif-0.1.0/include/sif/finder/spherical_finder.h +68 -0
  11. pysif-0.1.0/include/sif/io/catalog_io.h +54 -0
  12. pysif-0.1.0/include/sif/io/field_io.h +154 -0
  13. pysif-0.1.0/include/sif/io/grid_io.h +115 -0
  14. pysif-0.1.0/include/sif/io/hdf5_io.h +266 -0
  15. pysif-0.1.0/include/sif/io/profiles_io.h +116 -0
  16. pysif-0.1.0/include/sif/measure/delta_distribution.h +52 -0
  17. pysif-0.1.0/include/sif/measure/delta_moments.h +50 -0
  18. pysif-0.1.0/include/sif/measure/profiles.h +246 -0
  19. pysif-0.1.0/include/sif/measure/size_function.h +74 -0
  20. pysif-0.1.0/include/sif/model/bbks.h +158 -0
  21. pysif-0.1.0/include/sif/model/delta_moments.h +161 -0
  22. pysif-0.1.0/include/sif/model/excursion_set.h +240 -0
  23. pysif-0.1.0/include/sif/model/size_function.h +115 -0
  24. pysif-0.1.0/include/sif/structures/bitmask.h +152 -0
  25. pysif-0.1.0/include/sif/structures/catalog.h +159 -0
  26. pysif-0.1.0/include/sif/structures/cell_linked_list.h +134 -0
  27. pysif-0.1.0/include/sif/structures/chain_mesh.h +204 -0
  28. pysif-0.1.0/include/sif/structures/delta_distribution.h +57 -0
  29. pysif-0.1.0/include/sif/structures/delta_moments.h +93 -0
  30. pysif-0.1.0/include/sif/structures/field.h +316 -0
  31. pysif-0.1.0/include/sif/structures/grid.h +159 -0
  32. pysif-0.1.0/include/sif/structures/octree.h +159 -0
  33. pysif-0.1.0/include/sif/structures/size_function.h +88 -0
  34. pysif-0.1.0/include/sif/structures/tessellation.h +259 -0
  35. pysif-0.1.0/include/sif/utils/align.h +89 -0
  36. pysif-0.1.0/include/sif/utils/array.h +130 -0
  37. pysif-0.1.0/include/sif/utils/crc32.h +67 -0
  38. pysif-0.1.0/include/sif/utils/logger.h +115 -0
  39. pysif-0.1.0/include/sif/utils/random.h +145 -0
  40. pysif-0.1.0/include/sif/utils/sort.h +92 -0
  41. pysif-0.1.0/include/sif/utils/str.h +88 -0
  42. pysif-0.1.0/include/sif/utils/timer.h +56 -0
  43. pysif-0.1.0/packaging/build-deps.sh +168 -0
  44. pysif-0.1.0/packaging/test_wheel.py +66 -0
  45. pysif-0.1.0/pyproject.toml +103 -0
  46. pysif-0.1.0/python/CMakeLists.txt +112 -0
  47. pysif-0.1.0/python/environment.yml +19 -0
  48. pysif-0.1.0/python/src/finders/py_finders.c +382 -0
  49. pysif-0.1.0/python/src/finders/py_finders.h +23 -0
  50. pysif-0.1.0/python/src/finders_module.c +168 -0
  51. pysif-0.1.0/python/src/io/py_hdf5.c +345 -0
  52. pysif-0.1.0/python/src/io/py_io.c +452 -0
  53. pysif-0.1.0/python/src/io/py_io.h +47 -0
  54. pysif-0.1.0/python/src/io_module.c +316 -0
  55. pysif-0.1.0/python/src/measure/py_delta.c +151 -0
  56. pysif-0.1.0/python/src/measure/py_delta.h +18 -0
  57. pysif-0.1.0/python/src/measure/py_profiles.c +291 -0
  58. pysif-0.1.0/python/src/measure/py_profiles.h +28 -0
  59. pysif-0.1.0/python/src/measure/py_size_function.c +224 -0
  60. pysif-0.1.0/python/src/measure/py_size_function.h +18 -0
  61. pysif-0.1.0/python/src/measure_module.c +182 -0
  62. pysif-0.1.0/python/src/model/py_bbks.c +238 -0
  63. pysif-0.1.0/python/src/model/py_delta_moments.c +82 -0
  64. pysif-0.1.0/python/src/model/py_excursion_set.c +473 -0
  65. pysif-0.1.0/python/src/model/py_model.h +58 -0
  66. pysif-0.1.0/python/src/model/py_size_function.c +297 -0
  67. pysif-0.1.0/python/src/model_module.c +215 -0
  68. pysif-0.1.0/python/src/py_common.h +53 -0
  69. pysif-0.1.0/python/src/py_delta_common.h +107 -0
  70. pysif-0.1.0/python/src/sif_library.c +225 -0
  71. pysif-0.1.0/python/src/structures/py_bitmask.c +161 -0
  72. pysif-0.1.0/python/src/structures/py_bitmask.h +25 -0
  73. pysif-0.1.0/python/src/structures/py_catalog.c +184 -0
  74. pysif-0.1.0/python/src/structures/py_catalog.h +25 -0
  75. pysif-0.1.0/python/src/structures/py_cell_linked_list.c +220 -0
  76. pysif-0.1.0/python/src/structures/py_cell_linked_list.h +25 -0
  77. pysif-0.1.0/python/src/structures/py_chain_mesh.c +247 -0
  78. pysif-0.1.0/python/src/structures/py_chain_mesh.h +25 -0
  79. pysif-0.1.0/python/src/structures/py_delta_distribution.c +156 -0
  80. pysif-0.1.0/python/src/structures/py_delta_distribution.h +21 -0
  81. pysif-0.1.0/python/src/structures/py_delta_moments.c +249 -0
  82. pysif-0.1.0/python/src/structures/py_delta_moments.h +26 -0
  83. pysif-0.1.0/python/src/structures/py_field.c +348 -0
  84. pysif-0.1.0/python/src/structures/py_field.h +19 -0
  85. pysif-0.1.0/python/src/structures/py_grid.c +235 -0
  86. pysif-0.1.0/python/src/structures/py_grid.h +19 -0
  87. pysif-0.1.0/python/src/structures/py_octree.c +184 -0
  88. pysif-0.1.0/python/src/structures/py_octree.h +25 -0
  89. pysif-0.1.0/python/src/structures/py_size_function.c +187 -0
  90. pysif-0.1.0/python/src/structures/py_size_function.h +26 -0
  91. pysif-0.1.0/python/src/structures/py_tessellation.c +243 -0
  92. pysif-0.1.0/python/src/structures/py_tessellation.h +25 -0
  93. pysif-0.1.0/python/src/types_register.c +65 -0
  94. pysif-0.1.0/src/core/settings.c +377 -0
  95. pysif-0.1.0/src/core/system.c +270 -0
  96. pysif-0.1.0/src/core/system_internal.h +97 -0
  97. pysif-0.1.0/src/finder/exodus_finder.c +2966 -0
  98. pysif-0.1.0/src/finder/spherical_finder.c +277 -0
  99. pysif-0.1.0/src/finder/utils.c +398 -0
  100. pysif-0.1.0/src/finder/utils.h +201 -0
  101. pysif-0.1.0/src/io/catalog_io.c +178 -0
  102. pysif-0.1.0/src/io/core_io.c +102 -0
  103. pysif-0.1.0/src/io/field_io.c +577 -0
  104. pysif-0.1.0/src/io/grid_io.c +273 -0
  105. pysif-0.1.0/src/io/hdf5.c +1319 -0
  106. pysif-0.1.0/src/io/hdf5_common.c +62 -0
  107. pysif-0.1.0/src/io/hdf5_internal.h +48 -0
  108. pysif-0.1.0/src/io/hdf5_off.c +359 -0
  109. pysif-0.1.0/src/io/internal.h +90 -0
  110. pysif-0.1.0/src/io/profiles_io.c +350 -0
  111. pysif-0.1.0/src/math/fft.c +1042 -0
  112. pysif-0.1.0/src/math/fft.h +382 -0
  113. pysif-0.1.0/src/math/nn.c +192 -0
  114. pysif-0.1.0/src/math/nn.h +110 -0
  115. pysif-0.1.0/src/measure/delta_common.c +125 -0
  116. pysif-0.1.0/src/measure/delta_common.h +72 -0
  117. pysif-0.1.0/src/measure/delta_distribution.c +174 -0
  118. pysif-0.1.0/src/measure/delta_moments.c +142 -0
  119. pysif-0.1.0/src/measure/profiles.c +667 -0
  120. pysif-0.1.0/src/measure/profiles_internal.h +38 -0
  121. pysif-0.1.0/src/measure/size_function.c +377 -0
  122. pysif-0.1.0/src/model/bbks.c +622 -0
  123. pysif-0.1.0/src/model/delta_moments.c +620 -0
  124. pysif-0.1.0/src/model/ep_emu.c +445 -0
  125. pysif-0.1.0/src/model/ep_emu_weights.h +231 -0
  126. pysif-0.1.0/src/model/ep_internal.h +187 -0
  127. pysif-0.1.0/src/model/ep_upcrossing.c +436 -0
  128. pysif-0.1.0/src/model/excursion_set.c +584 -0
  129. pysif-0.1.0/src/model/size_function.c +349 -0
  130. pysif-0.1.0/src/structures/bitmask.c +94 -0
  131. pysif-0.1.0/src/structures/catalog.c +298 -0
  132. pysif-0.1.0/src/structures/cell_linked_list.c +208 -0
  133. pysif-0.1.0/src/structures/chain_mesh.c +1076 -0
  134. pysif-0.1.0/src/structures/chain_mesh_internal.h +46 -0
  135. pysif-0.1.0/src/structures/delta_distribution.c +72 -0
  136. pysif-0.1.0/src/structures/delta_moments.c +91 -0
  137. pysif-0.1.0/src/structures/field.c +761 -0
  138. pysif-0.1.0/src/structures/grid.c +883 -0
  139. pysif-0.1.0/src/structures/octree.c +558 -0
  140. pysif-0.1.0/src/structures/results_internal.h +51 -0
  141. pysif-0.1.0/src/structures/size_function.c +93 -0
  142. pysif-0.1.0/src/structures/tessellation.c +366 -0
  143. pysif-0.1.0/src/utils/align.c +110 -0
  144. pysif-0.1.0/src/utils/array.c +311 -0
  145. pysif-0.1.0/src/utils/crc32.c +73 -0
  146. pysif-0.1.0/src/utils/logger.c +97 -0
  147. pysif-0.1.0/src/utils/str.c +108 -0
  148. pysif-0.1.0/src/utils/timer.c +49 -0
  149. pysif-0.1.0/tests/CMakeLists.txt +76 -0
  150. pysif-0.1.0/tests/ep_emu_cases.h +552 -0
  151. pysif-0.1.0/tests/test_delta_stats.c +1685 -0
  152. pysif-0.1.0/tests/test_ep.c +1768 -0
  153. pysif-0.1.0/tests/test_ep_emu.c +454 -0
  154. pysif-0.1.0/tests/test_fft.c +425 -0
  155. pysif-0.1.0/tests/test_field_grid.c +696 -0
  156. pysif-0.1.0/tests/test_finders.c +428 -0
  157. pysif-0.1.0/tests/test_hdf5.c +572 -0
  158. pysif-0.1.0/tests/test_io.c +664 -0
  159. pysif-0.1.0/tests/test_octree.c +181 -0
  160. pysif-0.1.0/tests/test_profiles.c +433 -0
  161. pysif-0.1.0/tests/test_structures.c +586 -0
  162. pysif-0.1.0/tests/test_survey.c +554 -0
  163. pysif-0.1.0/tests/test_tessellation.c +554 -0
  164. pysif-0.1.0/tests/test_util.h +39 -0
  165. pysif-0.1.0/tests/test_utils.c +538 -0
  166. pysif-0.1.0/tests/test_vsf.c +180 -0
  167. pysif-0.1.0/tests/test_vsf_models.c +448 -0
  168. pysif-0.1.0/vendor/predicates/predicates.c +4325 -0
  169. pysif-0.1.0/vendor/predicates/predicates.h +32 -0
pysif-0.1.0/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ build/
2
+ .DS_Store
3
+ .vscode/
4
+ venv/
5
+ env/
6
+ data/
7
+ __pycache__/
8
+ runs/
9
+ tools/plots/
10
+ tools/ep_spectra.npz
11
+ tools/ep_validation_mc.npz
12
+ public/
13
+ docs/_build/
14
+ _err.txt
15
+ ideas.txt
16
+ .cache/
17
+ __cmake_systeminformation/
18
+ .claude/settings.local.json
@@ -0,0 +1,410 @@
1
+ # Copyright (C) 2026 Luca Palmieri
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ #
4
+ # This file is part of sif. See COPYING for the full license text.
5
+
6
+ cmake_minimum_required(VERSION 3.15)
7
+ project(sif VERSION 0.1.0 LANGUAGES C)
8
+
9
+ # Configuration
10
+ set(CMAKE_C_STANDARD 99)
11
+ set(CMAKE_C_STANDARD_REQUIRED ON)
12
+ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
13
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
14
+
15
+ include(GNUInstallDirs)
16
+
17
+ # Set build type
18
+ if(NOT CMAKE_BUILD_TYPE)
19
+ set(CMAKE_BUILD_TYPE Release)
20
+ endif()
21
+
22
+ # Set compile flags
23
+ #
24
+ # -ffast-math, less one of the promises it makes: -ffinite-math-only tells the
25
+ # compiler no value is ever NaN or infinite, which entitles it to delete every
26
+ # check that asks. sif validates its inputs with exactly those checks --
27
+ # `!(x >= 0 && x < box)` rejects a NaN coordinate because the comparison is
28
+ # false for it -- and GCC does delete them: a NaN coordinate then passes the
29
+ # chain mesh's validation and becomes a cell index. Keeping NaN semantics costs
30
+ # nothing measurable in the hot loops, which never meet one.
31
+ #
32
+ # A compile option rather than part of the flags below, which also reach the
33
+ # link line, where a compiler-only flag draws an "unused argument" warning per
34
+ # executable. Compile options follow CMAKE_C_FLAGS_RELEASE on the command line,
35
+ # so it lands after -ffast-math and takes the one promise back.
36
+ set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math")
37
+ add_compile_options($<$<CONFIG:Release>:-fno-finite-math-only>)
38
+ set(CMAKE_C_FLAGS_DEBUG "-g -O2 -Wall -Wextra -fno-omit-frame-pointer")
39
+
40
+ # Tuning for the CPU of the machine doing the build. Right for a build that
41
+ # runs where it was compiled; wrong for one that runs elsewhere, where the
42
+ # first instruction the other CPU lacks kills the process with SIGILL. Turn it
43
+ # off for a binary meant to be shipped (a Python wheel), and on a cluster
44
+ # whose login nodes differ from its compute nodes -- there, name the target
45
+ # instead: -DSIF_NATIVE_ARCH=OFF -DCMAKE_C_FLAGS="-march=znver3".
46
+ option(SIF_NATIVE_ARCH "Optimize for the build machine's CPU (-march=native)" ON)
47
+ if(SIF_NATIVE_ARCH)
48
+ string(APPEND CMAKE_C_FLAGS_RELEASE " -march=native")
49
+ message(STATUS "CPU tuning: native (SIF_NATIVE_ARCH=ON)")
50
+ else()
51
+ message(STATUS "CPU tuning: generic, plus whatever CMAKE_C_FLAGS names")
52
+ endif()
53
+
54
+ option(SIF_VECTORIZATION_REPORT "Enable compiler vectorization reports" OFF)
55
+
56
+ # Build the tests when sif is the project being built, but not when it is
57
+ # pulled in as a subdirectory, nor when pip is building the Python extension.
58
+ # SKBUILD is set by scikit-build-core, the build backend in pyproject.toml.
59
+ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT SKBUILD)
60
+ set(SIF_TESTS_DEFAULT ON)
61
+ else()
62
+ set(SIF_TESTS_DEFAULT OFF)
63
+ endif()
64
+ option(SIF_BUILD_TESTS "Build the sif test suite" ${SIF_TESTS_DEFAULT})
65
+
66
+ # Debug-only invariant checks (bounds asserts in the hot accessors). Not tied
67
+ # to NDEBUG, which the release preset never defines.
68
+ option(SIF_DEBUG_CHECKS "Enable internal assertions" OFF)
69
+
70
+ # The Python extension, pysif. On whenever pip builds the project; a plain
71
+ # CMake build can ask for it too, to work on the bindings without pip.
72
+ if(SKBUILD)
73
+ set(SIF_PYTHON_DEFAULT ON)
74
+ else()
75
+ set(SIF_PYTHON_DEFAULT OFF)
76
+ endif()
77
+ option(SIF_BUILD_PYTHON "Build the Python extension (pysif)" ${SIF_PYTHON_DEFAULT})
78
+
79
+ # Offline data-generation programs. Not part of the library and not built by
80
+ # default: they exist to produce emulator training sets on a cluster.
81
+ option(SIF_BUILD_TOOLS "Build the offline tools in tools/" OFF)
82
+
83
+ # OpenMP
84
+ #
85
+ # 4.5 or newer. The measured histograms reduce into array sections
86
+ # (`reduction(+ : counts[ : n_bins])`), which is a 4.5 feature; GCC has had it
87
+ # since 6.1 and Clang since 9, so the floor costs nothing in practice. Stated
88
+ # here rather than discovered as a compile error in one file.
89
+ find_package(OpenMP REQUIRED)
90
+
91
+ if(OpenMP_C_FOUND AND OpenMP_C_VERSION VERSION_LESS 4.5)
92
+ message(FATAL_ERROR
93
+ "sif needs OpenMP 4.5 or newer for array-section reductions; "
94
+ "the compiler reports ${OpenMP_C_VERSION}")
95
+ endif()
96
+
97
+ # fftw3
98
+
99
+ # this might need to be modified depending on the destination system
100
+ set(FFTW_HINTS $ENV{FFTW3_ROOT} $ENV{FFTW_HOME})
101
+
102
+ # FFTW's threading backend.
103
+ #
104
+ # omp - shares the OpenMP runtime with sif, so FFTW and the rest of the
105
+ # library do not oversubscribe the machine. Correct ONLY when FFTW
106
+ # was built against the same OpenMP runtime as this project.
107
+ # threads - FFTW's pthreads backend. Always safe, at the cost of FFTW keeping
108
+ # its own thread pool.
109
+ #
110
+ # Mixing two OpenMP runtimes in one process aborts at startup with
111
+ # "OMP: Error #15: Initializing libomp.dylib, but found libomp.dylib already
112
+ # initialized". That happens on a stock Homebrew FFTW built against a different
113
+ # compiler than the one used here; switch to `threads` in that case.
114
+ set(SIF_FFTW_THREADING "omp" CACHE STRING "FFTW threading backend (omp|threads)")
115
+ set_property(CACHE SIF_FFTW_THREADING PROPERTY STRINGS omp threads)
116
+
117
+ if(NOT SIF_FFTW_THREADING MATCHES "^(omp|threads)$")
118
+ message(FATAL_ERROR "SIF_FFTW_THREADING must be 'omp' or 'threads'")
119
+ endif()
120
+
121
+ find_library(FFTW3_LIB NAMES fftw3 HINTS ${FFTW_HINTS} PATH_SUFFIXES lib lib64 REQUIRED)
122
+ find_library(FFTW3F_LIB NAMES fftw3f HINTS ${FFTW_HINTS} PATH_SUFFIXES lib lib64 REQUIRED)
123
+ find_library(FFTW3_THREAD_LIB
124
+ NAMES fftw3_${SIF_FFTW_THREADING} HINTS ${FFTW_HINTS} PATH_SUFFIXES lib lib64 REQUIRED)
125
+ find_library(FFTW3F_THREAD_LIB
126
+ NAMES fftw3f_${SIF_FFTW_THREADING} HINTS ${FFTW_HINTS} PATH_SUFFIXES lib lib64 REQUIRED)
127
+ find_path(FFTW3_INCLUDE NAMES fftw3.h HINTS ${FFTW_HINTS} PATH_SUFFIXES include REQUIRED)
128
+
129
+ message(STATUS "FFTW threading backend: ${SIF_FFTW_THREADING}")
130
+
131
+ # HDF5
132
+ #
133
+ # Optional: the HDF5 readers and writers are an interchange format on top of
134
+ # the native .xfield and the ASCII paths, not something the library needs.
135
+ #
136
+ # ON - required; configuring fails without a usable HDF5.
137
+ # OFF - never looked for. Nothing in sif references HDF5, so a project that
138
+ # embeds sif and has no use for it sets this and never sees it:
139
+ # set(SIF_HDF5_SUPPORT OFF CACHE STRING "" FORCE)
140
+ # add_subdirectory(sif)
141
+ # AUTO - used when found, skipped otherwise. Convenient, and exactly as
142
+ # dependent on the machine as it sounds: a cluster build where the
143
+ # HDF5 module was not loaded comes out without it. The status line
144
+ # below says which, and sif_init() logs it again at run time.
145
+ #
146
+ # Only a serial HDF5 is accepted. A parallel build needs MPI headers and the
147
+ # MPI compiler wrappers everywhere HDF5's own headers are seen, and sif is not
148
+ # an MPI code. Asked for it with ON, that is an error; under AUTO it is
149
+ # skipped as if absent.
150
+ set(SIF_HDF5_SUPPORT "AUTO" CACHE STRING "HDF5 I/O support (ON|OFF|AUTO)")
151
+ set_property(CACHE SIF_HDF5_SUPPORT PROPERTY STRINGS ON OFF AUTO)
152
+
153
+ string(TOUPPER "${SIF_HDF5_SUPPORT}" _sif_hdf5_mode)
154
+ if(NOT _sif_hdf5_mode MATCHES "^(ON|OFF|AUTO)$")
155
+ message(FATAL_ERROR
156
+ "SIF_HDF5_SUPPORT must be ON, OFF or AUTO, not '${SIF_HDF5_SUPPORT}'")
157
+ endif()
158
+
159
+ set(SIF_WITH_HDF5 OFF)
160
+ set(_sif_hdf5_why "disabled (SIF_HDF5_SUPPORT=OFF)")
161
+
162
+ if(NOT _sif_hdf5_mode STREQUAL "OFF")
163
+ if(_sif_hdf5_mode STREQUAL "ON")
164
+ find_package(HDF5 REQUIRED COMPONENTS C)
165
+ else()
166
+ find_package(HDF5 QUIET COMPONENTS C)
167
+ endif()
168
+
169
+ if(HDF5_FOUND)
170
+ # Asked of HDF5's own configuration header rather than of the variables
171
+ # find_package() leaves behind: which of those exist depends on whether
172
+ # HDF5 was found through its CMake package or through the h5cc wrapper,
173
+ # and on the CMake version. H5_HAVE_PARALLEL is the one answer every
174
+ # HDF5 install gives the same way.
175
+ include(CheckSymbolExists)
176
+ set(CMAKE_REQUIRED_INCLUDES ${HDF5_C_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS})
177
+ set(CMAKE_REQUIRED_QUIET ON)
178
+ check_symbol_exists(H5_HAVE_PARALLEL "H5pubconf.h" SIF_HDF5_IS_PARALLEL)
179
+ unset(CMAKE_REQUIRED_INCLUDES)
180
+ unset(CMAKE_REQUIRED_QUIET)
181
+
182
+ if(SIF_HDF5_IS_PARALLEL)
183
+ if(_sif_hdf5_mode STREQUAL "ON")
184
+ message(FATAL_ERROR
185
+ "the HDF5 found (${HDF5_VERSION}) is a parallel (MPI) build, which "
186
+ "sif does not support. Point CMake at a serial HDF5 "
187
+ "(-DHDF5_ROOT=...), or set SIF_HDF5_SUPPORT=OFF")
188
+ endif()
189
+ set(_sif_hdf5_why
190
+ "skipped: the HDF5 found (${HDF5_VERSION}) is a parallel build")
191
+ else()
192
+ set(SIF_WITH_HDF5 ON)
193
+ set(_sif_hdf5_why "HDF5 ${HDF5_VERSION}")
194
+ endif()
195
+ else()
196
+ set(_sif_hdf5_why
197
+ "not found (SIF_HDF5_SUPPORT=AUTO; set it to ON to require HDF5)")
198
+ endif()
199
+ endif()
200
+
201
+ message(STATUS "HDF5 I/O: ${_sif_hdf5_why}")
202
+
203
+ # Readable from a project that adds sif as a subdirectory, which cannot see
204
+ # this directory's variables otherwise.
205
+ set(SIF_WITH_HDF5 ${SIF_WITH_HDF5} CACHE INTERNAL "sif was built with HDF5")
206
+
207
+ # Source files
208
+ set(SOURCES
209
+ # data structures
210
+ src/structures/grid.c
211
+ src/structures/catalog.c
212
+ src/structures/chain_mesh.c
213
+ src/structures/tessellation.c
214
+ src/structures/cell_linked_list.c
215
+ src/structures/field.c
216
+ src/structures/octree.c
217
+ src/structures/bitmask.c
218
+ src/structures/delta_distribution.c
219
+ src/structures/delta_moments.c
220
+ src/structures/size_function.c
221
+
222
+ # finder
223
+ src/finder/spherical_finder.c
224
+ src/finder/exodus_finder.c
225
+ src/finder/utils.c
226
+
227
+ # measure
228
+ src/measure/profiles.c
229
+ src/measure/size_function.c
230
+ src/measure/delta_common.c
231
+ src/measure/delta_distribution.c
232
+ src/measure/delta_moments.c
233
+
234
+ # model
235
+ src/model/delta_moments.c
236
+ src/model/bbks.c
237
+ src/model/size_function.c
238
+ src/model/excursion_set.c
239
+ src/model/ep_upcrossing.c
240
+ src/model/ep_emu.c
241
+
242
+ # io -- the HDF5 half is added below, one file or the other
243
+ src/io/core_io.c
244
+ src/io/catalog_io.c
245
+ src/io/profiles_io.c
246
+ src/io/field_io.c
247
+ src/io/grid_io.c
248
+
249
+ # math
250
+ src/math/fft.c
251
+ src/math/nn.c
252
+
253
+ # utils
254
+ src/utils/timer.c
255
+ src/utils/logger.c
256
+ src/utils/str.c
257
+ src/utils/align.c
258
+ src/utils/array.c
259
+ src/utils/crc32.c
260
+
261
+ # library
262
+ src/core/system.c
263
+ src/core/settings.c
264
+
265
+ # vendor
266
+ vendor/predicates/predicates.c
267
+ )
268
+
269
+ # Disable fast math for exact arithmetic
270
+ set(PREDICATES_FLAGS "-fno-fast-math -ffp-contract=off")
271
+
272
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
273
+ string(APPEND PREDICATES_FLAGS " -mno-fma")
274
+ endif()
275
+
276
+ set_source_files_properties(vendor/predicates/predicates.c
277
+ PROPERTIES COMPILE_FLAGS "${PREDICATES_FLAGS}"
278
+ )
279
+
280
+
281
+ # The HDF5 entry points always exist; which file implements them decides
282
+ # whether they do the work or report that this build cannot.
283
+ if(SIF_WITH_HDF5)
284
+ list(APPEND SOURCES src/io/hdf5.c)
285
+ else()
286
+ list(APPEND SOURCES src/io/hdf5_off.c)
287
+ endif()
288
+ list(APPEND SOURCES src/io/hdf5_common.c)
289
+
290
+ # Create library
291
+ add_library(sif STATIC ${SOURCES})
292
+
293
+ # The project version, for the library to stamp into the files it writes.
294
+ # PRIVATE: it is the build's own idea of itself, not something a caller
295
+ # compiles against.
296
+ target_compile_definitions(sif PRIVATE SIF_VERSION_STRING="${PROJECT_VERSION}")
297
+
298
+ # Internal assertions. PUBLIC because the guarded macros live in headers that
299
+ # callers (and the tests) include, so both sides must agree.
300
+ if(SIF_DEBUG_CHECKS)
301
+ target_compile_definitions(sif PUBLIC SIF_DEBUG_CHECKS)
302
+ endif()
303
+
304
+ # Include directories
305
+ target_include_directories(sif
306
+ PUBLIC
307
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
308
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
309
+ PRIVATE
310
+ ${FFTW3_INCLUDE}
311
+ src
312
+ vendor
313
+ )
314
+
315
+ # HDF5 is private to the sources that use it: no public sif header includes
316
+ # hdf5.h, so nothing compiled against sif needs HDF5's headers, and a build
317
+ # without it has no trace of it at all.
318
+ if(SIF_WITH_HDF5)
319
+ target_include_directories(sif PRIVATE
320
+ ${HDF5_C_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS})
321
+ target_compile_definitions(sif PRIVATE
322
+ SIF_HAVE_HDF5 ${HDF5_C_DEFINITIONS} ${HDF5_DEFINITIONS})
323
+ target_link_libraries(sif PRIVATE ${HDF5_C_LIBRARIES})
324
+ endif()
325
+
326
+ # Linking
327
+ target_link_libraries(sif PRIVATE
328
+ ${FFTW3_LIB}
329
+ ${FFTW3F_LIB}
330
+ ${FFTW3_THREAD_LIB}
331
+ ${FFTW3F_THREAD_LIB}
332
+ m
333
+ $<$<BOOL:${OpenMP_C_FOUND}>:OpenMP::OpenMP_C>
334
+ )
335
+
336
+ if(SIF_VECTORIZATION_REPORT)
337
+ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
338
+ target_compile_options(sif PRIVATE -Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize)
339
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
340
+ target_compile_options(sif PRIVATE -fopt-info-vec-optimized -fopt-info-vec-missed)
341
+ endif()
342
+ endif()
343
+
344
+ # tests
345
+
346
+ if(SIF_BUILD_TESTS)
347
+ enable_testing()
348
+ add_subdirectory(tests)
349
+ endif()
350
+
351
+ if(SIF_BUILD_TOOLS)
352
+ foreach(_tool ep_gen_case ep_validate)
353
+ add_executable(${_tool} tools/${_tool}.c)
354
+ target_link_libraries(${_tool} PRIVATE sif m)
355
+ set_target_properties(${_tool} PROPERTIES
356
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tools)
357
+ endforeach()
358
+ endif()
359
+
360
+ if(SIF_BUILD_PYTHON)
361
+ add_subdirectory(python)
362
+ endif()
363
+
364
+ # installation
365
+ #
366
+ # Not under pip: a wheel carries the extension alone, which has sif linked in,
367
+ # and has no place for a static library, headers and CMake files.
368
+
369
+ if(SKBUILD)
370
+ return()
371
+ endif()
372
+
373
+ install(TARGETS sif
374
+ EXPORT sifTargets
375
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
376
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
377
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
378
+ )
379
+
380
+ install(DIRECTORY include/
381
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
382
+ FILES_MATCHING PATTERN "*.h"
383
+ )
384
+
385
+ install(EXPORT sifTargets
386
+ FILE sifTargets.cmake
387
+ NAMESPACE sif::
388
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sif
389
+ )
390
+
391
+ # A static library carries its private dependencies into whatever links it,
392
+ # and HDF5 can arrive as an imported target rather than a path -- so a sif
393
+ # built with HDF5 has to find it again on the consumer's side. Built without,
394
+ # the consumer never hears of it.
395
+ if(SIF_WITH_HDF5)
396
+ set(_sif_config_hdf5 "find_dependency(HDF5 COMPONENTS C)\n")
397
+ else()
398
+ set(_sif_config_hdf5 "")
399
+ endif()
400
+
401
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/sifConfig.cmake
402
+ "include(CMakeFindDependencyMacro)\n"
403
+ "find_dependency(OpenMP)\n"
404
+ "${_sif_config_hdf5}"
405
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/sifTargets.cmake\")\n"
406
+ )
407
+
408
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sifConfig.cmake
409
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sif
410
+ )