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