Skip to content

Add native cube generator backed by GauXC OrbitalEvaluator - #461

Merged
Conrad Johnston (ConradJohnston) merged 36 commits into
mainfrom
feature/cojoh/native-cubegen-v2
Aug 19, 2026
Merged

Add native cube generator backed by GauXC OrbitalEvaluator#461
Conrad Johnston (ConradJohnston) merged 36 commits into
mainfrom
feature/cojoh/native-cubegen-v2

Conversation

@ConradJohnston

@ConradJohnston Conrad Johnston (ConradJohnston) commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Why

generate_cubefiles_from_orbitals went through PySCF. PySCF is pinned
sys_platform != 'win32' in python/pyproject.toml, and utils/cubegen.py
imported pyscf.tools.cubegen at module scope, so the module was unimportable
on Windows and cube generation was simply unavailable there. It also meant
orbital visualization pulled in a third-party quantum chemistry package for
something the library can evaluate itself.

How

Adds a native CubeGenerator in qdk::chemistry::utils that evaluates orbitals
and densities on a CubeGrid using GauXC's OrbitalEvaluator, writes Gaussian
cube files through GauXC::write_cube, and is exposed to Python. It is now the
default backend for generate_cubefiles_from_orbitals, which gives Windows cube
generation for the first time. backend="pyscf" still works wherever PySCF is
installed.

The switch is behavior preserving: both backends place grid points identically,
with the origin at the nuclear bounding box corner minus the margin and the step
equal to the padded extent divided by n - 1 along each axis, and both use the
same atomic orbital ordering.

GauXC's cube-generation support is now upstream, so the dependency moves off the
temporary fork and pins wavefunction91/GauXC at merge commit
162e4562552323a871af17ae4acd73b71071bd24.

Two dependency patches were needed to build across platforms:

  • A vcpkg overlay for the existing libaec 1.1.6, retargeting the archive from
    the intermittently failing GitLab URL to libaec's canonical GitHub mirror.
    Recipe and version are unchanged.
  • A clang-cl-only, idempotent patch for GauXC's vendored Gau2Grid helper, which
    calls exit() without including <stdlib.h> on that preprocessor path.

Neither affects cube-generation behavior or adds a runtime dependency.

API

CubeGenerator gen(basis_set);
auto field = gen.orbital(mo_coeff, "orbital.cube", grid);
auto rho = gen.density(D, "density.cube", grid);

@github-actions

github-actions Bot commented Apr 28, 2026

Copy link
Copy Markdown

📊 Coverage Summary

Component Coverage
C++ Library 77%
Python Package 86%
Pybind11 Bindings 87%

Detailed Coverage Reports

C++ Coverage Details
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: cpp
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
include/qdk/chemistry/algorithms/active_space.hpp
                                               5       5   100%
include/qdk/chemistry/algorithms/algorithm.hpp
                                              70      55    78%   117,119-121,124,126-128,130-131,219,241,243-244,302
include/qdk/chemistry/algorithms/dynamical_correlation_calculator.hpp
                                               7       6    85%   115
include/qdk/chemistry/algorithms/hamiltonian.hpp
                                               5       5   100%
include/qdk/chemistry/algorithms/localization.hpp
                                               5       5   100%
include/qdk/chemistry/algorithms/mc.hpp       22      22   100%
include/qdk/chemistry/algorithms/mcscf.hpp
                                              13      13   100%
include/qdk/chemistry/algorithms/pmc.hpp       8       6    75%   41,186
include/qdk/chemistry/algorithms/scf.hpp      13      12    92%   23
include/qdk/chemistry/algorithms/stability.hpp
                                               5       4    80%   131
include/qdk/chemistry/cube/cube_generator.hpp
                                               2       0     0%   43,63
include/qdk/chemistry/data/ansatz.hpp          3       3   100%
include/qdk/chemistry/data/basis_set.hpp      35      30    85%   108-109,112,114,319
include/qdk/chemistry/data/configuration.hpp
                                              32      30    93%   71,119
include/qdk/chemistry/data/configuration_set.hpp
                                               3       2    66%   35
include/qdk/chemistry/data/data_class.hpp
                                               4       4   100%
include/qdk/chemistry/data/element_data.hpp
                                              18      18   100%
include/qdk/chemistry/data/hamiltonian.hpp
                                              12      12   100%
include/qdk/chemistry/data/hamiltonian_containers/canonical_four_center.hpp
                                               1       1   100%
include/qdk/chemistry/data/hamiltonian_containers/cholesky.hpp
                                               1       1   100%
include/qdk/chemistry/data/hamiltonian_containers/sparse.hpp
                                               1       1   100%
include/qdk/chemistry/data/lattice_graph.hpp
                                               3       1    33%   324-325
include/qdk/chemistry/data/orbitals.hpp        6       6   100%
include/qdk/chemistry/data/pauli_operator.hpp
                                              88      83    94%   1203,1227,1262,1274,1288
include/qdk/chemistry/data/settings.hpp       93      68    73%   76,79,82,305-306,441,483,618,987,994,996,1011-1012,1016-1018,1022-1023,1025-1027,1029-1030,1119,1123
include/qdk/chemistry/data/stability_result.hpp
                                              38      38   100%
include/qdk/chemistry/data/structure.hpp       9       8    88%   142
include/qdk/chemistry/data/wavefunction.hpp
                                              25      19    76%   496,502,510-512,673
include/qdk/chemistry/data/wavefunction_containers/cas.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/cc.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/mp2.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/sci.hpp
                                               1       1   100%
include/qdk/chemistry/data/wavefunction_containers/sd.hpp
                                               1       1   100%
include/qdk/chemistry/utils/hash.hpp           4       4   100%
include/qdk/chemistry/utils/logger.hpp        41      35    85%   223-224,226,233-234,236
include/qdk/chemistry/utils/model_hamiltonians.hpp
                                             128     122    95%   59-60,89-90,137,141
include/qdk/chemistry/utils/string_utils.hpp
                                              11      10    90%   41
src/qdk/chemistry/algorithms/active_space.cpp
                                             232     142    61%   35-36,40-41,45-46,116-118,143-145,147,151-154,156-159,162-163,165-168,173-174,176-179,182-184,187-189,191,194-196,218,220,224,226-229,231-232,236-239,241,243,246-249,251,253,255-256,277-278,307,310,342,347-348,350-353,355-357,359-360,363,367,369-371,413,415,417
src/qdk/chemistry/algorithms/algorithm_defaults.cpp
                                              15       9    60%   41-45,49
src/qdk/chemistry/algorithms/dynamical_correlation_calculator.cpp
                                               8       8   100%
src/qdk/chemistry/algorithms/hamiltonian.cpp
                                              14      14   100%
src/qdk/chemistry/algorithms/localization.cpp
                                              15      15   100%
src/qdk/chemistry/algorithms/mc.cpp           11      11   100%
src/qdk/chemistry/algorithms/microsoft/active_space/autocas_active_space.cpp
                                              80      78    97%   103,133
src/qdk/chemistry/algorithms/microsoft/active_space/autocas_active_space.hpp
                                              16      16   100%
src/qdk/chemistry/algorithms/microsoft/active_space/entropy_active_space.cpp
                                              45      45   100%
src/qdk/chemistry/algorithms/microsoft/active_space/entropy_active_space.hpp
                                              10      10   100%
src/qdk/chemistry/algorithms/microsoft/active_space/occupation_active_space.cpp
                                              60      54    90%   46,48,81,83,101-102
src/qdk/chemistry/algorithms/microsoft/active_space/occupation_active_space.hpp
                                               6       6   100%
src/qdk/chemistry/algorithms/microsoft/active_space/valence_active_space.cpp
                                              75      63    84%   34,36,68-69,76-77,104-105,120-121,124-125
src/qdk/chemistry/algorithms/microsoft/active_space/valence_active_space.hpp
                                               9       9   100%
src/qdk/chemistry/algorithms/microsoft/cholesky_hamiltonian.cpp
                                             457     407    89%   98,102,420,439,442-443,462,473,476-477,507-508,557-558,564-566,573-574,581-582,613,616-617,632,640,642-644,679-683,774,776,788,794,807,813,875-876,878-879,882,987-988,990-991,994
src/qdk/chemistry/algorithms/microsoft/cholesky_hamiltonian.hpp
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/hamiltonian.cpp
                                             252     230    91%   46-47,53-55,62-63,105-106,164-165,182-186,300,302,313,325,387,495
src/qdk/chemistry/algorithms/microsoft/hamiltonian.hpp
                                              10      10   100%
src/qdk/chemistry/algorithms/microsoft/localization/iterative_localizer_base.cpp
                                               5       5   100%
src/qdk/chemistry/algorithms/microsoft/localization/iterative_localizer_base.hpp
                                               8       8   100%
src/qdk/chemistry/algorithms/microsoft/localization/mp2_natural_orbitals.cpp
                                              79      74    93%   44,81,83,104,106
src/qdk/chemistry/algorithms/microsoft/localization/mp2_natural_orbitals.hpp
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/localization/pipek_mezey.cpp
                                             169     160    94%   26,34,41,43,47,49,246,329,332
src/qdk/chemistry/algorithms/microsoft/localization/pipek_mezey.hpp
                                               6       6   100%
src/qdk/chemistry/algorithms/microsoft/localization/vvhv.cpp
                                             646     575    89%   336,338-339,452-453,476,534,695,739,741,746,762-765,768,778-781,784,819-821,827-831,859-862,865,887,889-891,968-972,1018-1022,1040-1043,1047-1050,1052-1054,1057,1131,1194-1196,1267,1286,1289,1293,1295,1300-1301
src/qdk/chemistry/algorithms/microsoft/localization/vvhv.hpp
                                               6       6   100%
src/qdk/chemistry/algorithms/microsoft/macis_asci.cpp
                                              69      66    95%   51,167,169
src/qdk/chemistry/algorithms/microsoft/macis_asci.hpp
                                              73      73   100%
src/qdk/chemistry/algorithms/microsoft/macis_base.cpp
                                              70      56    80%   29-31,91-92,95,99-100,103-105,112-114
src/qdk/chemistry/algorithms/microsoft/macis_base.hpp
                                              99      77    77%   84,86,88,90,92,94,205-207,209,212,214,217-219,221-223,225-227,229
src/qdk/chemistry/algorithms/microsoft/macis_cas.cpp
                                              59      56    94%   48,132,134
src/qdk/chemistry/algorithms/microsoft/macis_cas.hpp
                                               5       5   100%
src/qdk/chemistry/algorithms/microsoft/macis_pmc.cpp
                                              78      76    97%   110,149
src/qdk/chemistry/algorithms/microsoft/macis_pmc.hpp
                                               5       5   100%
src/qdk/chemistry/algorithms/microsoft/mp2.cpp
                                             202     184    91%   33,78,82-83,93-94,97,101-102,149-150,153-154,164-165,168,172-173
src/qdk/chemistry/algorithms/microsoft/mp2.hpp
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf.cpp
                                             271     254    93%   101-102,132-133,141,143,197,244,315,347,352,354,380-382,401,472
src/qdk/chemistry/algorithms/microsoft/scf.hpp
                                              19      19   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/basis_set.h
                                               9       8    88%   134
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/enums.h
                                              16       0     0%   38-39,48-49,54-59,70-75
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/eri.h
                                              15      12    80%   46-47,49
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/exc.h
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/moeri.h
                                               3       3   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/core/molecule.h
                                               1       1   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/eri/eri_multiplexer.h
                                               6       3    50%   126-127,135
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/cache.h
                                              27      26    96%   44
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/class_registry.h
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/gauxc_registry.h
                                               6       5    83%   39
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/gauxc_util.h
                                              21      21   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/int1e.h
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf/include/qdk/chemistry/scf/util/singleton.h
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/core/basis_set.cpp
                                             361     279    77%   33-34,92-93,97-98,146,150-154,157-161,172,183-184,188,190-191,197-198,201-206,210,212-215,217,219,223,225-226,228-229,231,248,257,265-266,313-314,335,337,342-343,345-346,348,401,406-407,415,436,458,460-461,463-465,478,480,482-485,487,490,493-494,542,544,548-549
src/qdk/chemistry/algorithms/microsoft/scf/src/core/scf.cpp
                                               7       7   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri.cpp
                                              36      29    80%   58-60,65-66,89-90
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri_df_base.cpp
                                              34      32    94%   29-30
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri_df_base.h
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/eri_multiplexer.cpp
                                              61      37    60%   16-17,26-29,40,46-49,52-55,79,81,83-85,87-88,91,93
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/INCORE/incore.cpp
                                              42      29    69%   40,42,44,66,68,70-72,74-75,77-79
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/INCORE/incore_impl.cpp
                                              96      88    91%   44,136,138,235,237,239,287,289
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/INCORE/incore_impl_df.cpp
                                             102      60    58%   86-87,89,203,205,207-214,216-221,224,227-233,236,253,256,263-264,286,291,305-306,309,320-321,323-324,326
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/LIBINT2_DIRECT/libint2_direct.cpp
                                             182     169    92%   268,606,608,610,908,910-913,916,918-920
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/moeri.cpp
                                              36      34    94%   32-33
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/schwarz.cpp
                                              33      13    39%   80-81,83-88,90-93,95-98,101-102,104,106
src/qdk/chemistry/algorithms/microsoft/scf/src/eri/SNK/snk.cpp
                                              66       0     0%   36,58-60,62-65,67,69-70,72,98,100,102-104,107-110,114-116,119-121,124-127,146,148,150,167-168,170,187,191,193-194,200-201,203,205-207,209,212,214,216-218,221,223,225-227,230,232,234-235,239-240,242-243
src/qdk/chemistry/algorithms/microsoft/scf/src/exc/exc.cpp
                                              16      14    87%   42-43
src/qdk/chemistry/algorithms/microsoft/scf/src/exc/GauXC/gauxc.cpp
                                              34      25    73%   42,46-47,50-52,54,56,67
src/qdk/chemistry/algorithms/microsoft/scf/src/exc/GauXC/gauxc_impl.cpp
                                             229     163    71%   79,119,160-161,249-258,260,262-270,352-353,360-364,366,368-377,380-381,383-384,387-389,396,398-399,405-409,411,413-417,419-420,426
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/cpscf.cpp
                                             234     232    99%   232,237
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/guess.cpp
                                              63      63   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/ks_impl.cpp
                                              81      63    77%   73,75-82,140,155-158,160-161,171-172
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/scf_impl.cpp
                                             547     414    75%   73,101,116,122,168-169,185-186,329-330,339-342,467,471,551,588,607-609,676,715-716,720-721,730-735,745,749-752,754-761,774-778,780-783,785-786,793-794,796-801,803-808,810,818-821,831-832,843-845,859-864,867-870,873,876,878,977-979,982,984,988-989,991-995,997-1000,1002-1003,1007,1009,1011-1019,1022-1025,1028-1030,1032,1034,1053,1055
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/scf_impl.h
                                              21      16    76%   98-100,113,161
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/scf_solver.cpp
                                              82      54    65%   35,37,51,55-59,66,68,90,92-93,101-103,111-113,126-128,131-133,141-143
src/qdk/chemistry/algorithms/microsoft/scf/src/scf/soad.cpp
                                              15       0     0%   189,192-204,208
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/asahf.cpp
                                             286     275    96%   49,51,68-69,101,271,464-465,506,530-531
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/diis.cpp
                                             278     259    93%   147,149,158-159,228,234,241,246,268-269,286,486-489,511,520,528,536
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/diis_gdm.cpp
                                              36      36   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/gdm.cpp
                                             401     366    91%   226,249,272,443-446,449-452,478-482,487,518-522,664,667-673,805,809,899,903,905
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/line_search.h
                                              63      62    98%   60
src/qdk/chemistry/algorithms/microsoft/scf/src/scf_algorithm/scf_algorithm.cpp
                                             143     130    90%   63,71-73,75,85-88,175-176,205,264
src/qdk/chemistry/algorithms/microsoft/scf/src/util/gauxc_util.cpp
                                              85      20    23%   26-31,34-43,48-49,52-59,63-66,68,70,72-74,81-88,92-99,106-111,115-118,122-123,134-135
src/qdk/chemistry/algorithms/microsoft/scf/src/util/int1e.cpp
                                             336     226    67%   206-209,211,243,288,290-296,298-303,305-311,314-315,326,328-329,569,592,622,699,702-703,705,713,755,757-758,762-771,780,782-783,787-796,805,807-808,812-824,826-829,838,941-942,946-954,956-962,964-967,976
src/qdk/chemistry/algorithms/microsoft/scf/src/util/libint2_util.cpp
                                             181      91    50%   39,42-45,47,49-51,53-54,58-60,64-66,72,74,76-79,81-82,85-91,94-95,97-102,104-107,109-119,125-126,477,483-490,492-495,497,499,503-504,506,560,562,566-569,571-573,576,580-582,584,627
src/qdk/chemistry/algorithms/microsoft/scf/src/util/matrix_exp.cpp
                                              53      53   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/mpi_vars.h
                                               2       2   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/opt/gmresxx/arnoldi/arnoldi.h
                                              12      12   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/opt/gmresxx/arnoldi/arnoldi_gmres.h
                                             202     168    83%   53-55,176,183,185-188,190-194,196,198,202,205,209,212,217-218,221,223,290,293-294,298,481-482,493,522-523,589
src/qdk/chemistry/algorithms/microsoft/scf/src/util/opt/gmresxx/linalg.h
                                              40      40   100%
src/qdk/chemistry/algorithms/microsoft/scf/src/util/timer.h
                                              29      29   100%
src/qdk/chemistry/algorithms/microsoft/stability.cpp
                                             317     294    92%   191-192,321-323,411,413,430,433-442,446,448,452,454,493
src/qdk/chemistry/algorithms/microsoft/stability.hpp
                                              13      13   100%
src/qdk/chemistry/algorithms/microsoft/utils.cpp
                                             248     171    69%   45-46,52,54,111-112,123-124,126-127,133,135,138-139,141,143-147,150-151,182,184,186,190-191,195,198-205,207-209,211,214-218,220-225,227-229,231,234-235,237,240-245,251,253-255,258-262,387-388,427,429
src/qdk/chemistry/algorithms/pmc.cpp           8       8   100%
src/qdk/chemistry/algorithms/scf.cpp           7       7   100%
src/qdk/chemistry/algorithms/stability.cpp
                                               6       6   100%
src/qdk/chemistry/cube/cube_generator.cpp
                                             163       0     0%   32,35-38,40-43,46-48,50-59,73-80,92-94,96-99,101-103,105-114,116-117,119-123,127-132,135-136,140-154,158,167,175-177,182-186,188,191-194,197-200,202-203,205-207,209,213-218,221-223,228-230,232,251-252,255-256,258,262-266,269-271,273-275,277,302-303,306-307,309,313-315,317-319,321-328,330,332-339
src/qdk/chemistry/cube/cube_writer.cpp       115       0     0%   42,44-46,48-50,52-53,57-60,64-67,74,76-77,79,81-84,86-91,97-100,104-108,123-136,138-150,156,159-162,165-167,171-175,179,182-186,188-194,198-199,203,205,207-208,211-214,227-233,235,237,259,261-262
src/qdk/chemistry/data/ansatz.cpp            553     380    68%   26,36,39,46-48,50-51,53,55-56,58-60,62,69,84,99,104-105,107-108,115,120,122,148,150,207,209,280,295,297,302-303,336-340,345,347,357,359,362,364,374,376,379,381,394,396,401,403-404,410,412,417,419-420,434,436,441,443-444,449,451,456,458-459,461-462,464,468-469,471-472,474-475,477-478,480-484,486-487,489,492,495-500,502-503,506-508,510,513,515-516,549,559,569,579,601,608,612,626,630-631,641,651-652,659,668,684-687,690-691,694-696,698-699,701-703,719,727,744-747,782-783,792-793,804,812-813,824,835-836,843,852,869-872,875-876,879-881,883-884,886-888,894-895,906-907,931-934
src/qdk/chemistry/data/basis_set.cpp        1438    1250    86%   31,38,70,91-92,221,225,259-260,276-277,326-327,341,361,387,402,433,460,493,506-507,513-514,529-530,545-546,565,568-569,615,618-620,648,651-653,719,761,785,814,845,881,914,936,966,1006,1023,1032,1050,1067,1079,1090,1180-1181,1235,1249,1262,1276,1291,1298,1308,1310,1317,1331-1332,1465,1522-1523,1537-1539,1541-1542,1548-1551,1560-1561,1727,1791-1792,1805-1806,1906,1914,1926,1962-1966,1968-1970,1973-1977,2010,2024-2028,2031-2040,2042-2045,2047-2051,2053-2055,2058-2061,2065-2066,2068,2070-2074,2077-2078,2082-2086,2090-2092,2098-2101,2103-2105,2108,2110,2112,2132-2133,2142-2143,2151-2153,2160-2161,2181-2182,2184,2201-2203,2268-2269,2271-2276,2282,2390
src/qdk/chemistry/data/configuration.cpp     279     171    61%   67,167,170,172-173,176-177,179-180,183-184,186,190,194-195,204,210,236-238,266-268,271-272,274-283,285,287,289-292,294-295,297,299-300,302-304,307-308,310-311,313,315-316,318-325,327,329,331-334,336-337,341-342,344-348,351-352,354-355,358-359,361-368,370-371,373-381,421-422,432,434
src/qdk/chemistry/data/configuration_set.cpp
                                             328     209    63%   33-34,85-87,90-92,234,247,272-277,287-288,331-333,350-354,356,376-377,400-402,421,425,427,429,431-434,436-437,439,441-442,444-447,450-451,453-455,458-463,465-466,468-478,480,482,484-487,489-490,494-495,497-501,503,506-508,510-514,517-524,526-527,529-540
src/qdk/chemistry/data/filename_utils.hpp
                                              44      26    59%   30-33,35-36,51-53,72-75,77-78,93-95
src/qdk/chemistry/data/hamiltonian.cpp       554     400    72%   41,46-47,68,73-74,82,95,97-99,102-104,108-115,132,140,160-162,194-195,213-217,232-236,241,243,249,251,269,271-274,311,322,324,328,331,409-422,424,427-428,431-434,436-439,442-445,447-450,454-457,459-462,465-469,471-474,476-479,481-484,487-488,494,508,517-518,536,539-540,572,585,597,610,623,636,643,662,680,687,694,701-703,709,720-721,741-742,758-759,767-768,793-797,826,828-829,892-894
src/qdk/chemistry/data/hamiltonian_containers/canonical_four_center.cpp
                                             420     360    85%   38-39,67-68,98,110,128-129,156,163,169-171,204-205,213,276,309,349,353,361,373,385,391-392,423,432,437-438,443-444,462,470,477-484,487-494,514-516,597-598,607-608,634,656,721-722
src/qdk/chemistry/data/hamiltonian_containers/cholesky.cpp
                                             474     303    63%   44-45,72-73,86-90,103,162-165,167-168,172-174,177,179,181-182,185-187,190-191,194-195,198-207,209-210,227,234,240-242,265-270,279-280,328-331,333,335-338,340,364-367,369,371-374,377,382,384-387,389,391-393,396-400,402,404-408,417,432,440,452,468-469,487-488,490,499,504,506,510-511,516-517,519,521,530-531,534-537,543,550-557,560-567,585,588,592-594,642-643,651-652,658-662,673,677-678,687-688,714,736,753,764-766,772-773,779-780,786-787,798,801,805-806
src/qdk/chemistry/data/hamiltonian_containers/sparse.cpp
                                             396     347    87%   89,103,153-155,212,232-235,260-263,364-366,398,435-441,443,471-479,481,484,487-488,494-497,506-507,512,600,609,625
src/qdk/chemistry/data/hdf5_error_handling.hpp
                                              10       3    30%   20-21,23,25-26,28-29
src/qdk/chemistry/data/hdf5_serialization.cpp
                                             240     119    49%   13,15-22,24,26-32,34,36-44,46,48-56,65-67,69-71,73-74,77-79,82-85,95,98,106-109,111-113,115-116,119-121,124-127,138,141,143-150,153-160,238-240,249-251,253-255,258-260,277-280,282-286,288-289,308-310,312-316,318-319
src/qdk/chemistry/data/json_serialization.cpp
                                             177      86    48%   29,38,45-47,57,64-68,70-71,83,90-92,94-98,100,102-103,105,114,120-121,128-129,131,133-134,136-139,141,143-146,148-149,152-153,155,163-164,173,178-179,188-189,196,201,210,212,214,216-217,219-222,225-229,231-236,246-249,252-256,260-264
src/qdk/chemistry/data/lattice_graph.cpp     408     191    46%   33-36,47-50,68,70-71,73-76,78,80-81,83-86,135,161,164,167,209,212,215,267,270,273,318,321,324,394-395,397-404,406,408,410-413,415-416,418,420-421,424-428,432-437,439-440,442-444,446-448,450,452-453,455-456,459-461,464-467,470-472,474-482,486-493,495-496,498-505,507,509,511-514,516-517,521-522,524-528,530-533,535-536,538-539,541-542,544-545,548-549,551-560,562,564-569,571-572,574-579,581-582,584-592,594-596,599-601,603-605,607-610,612-613,615,617-628,630,633-638
src/qdk/chemistry/data/orbitals.cpp         1177     913    77%   106-107,128,144-145,151-152,156-157,178,180,220-221,237,251,292,307,321,363,373,377,400,403,405-406,409-413,416-417,421-424,426-427,429,431,433-434,437-440,443,447,449,453,455,457-458,461-467,470-471,474-475,477-478,480,482,484-485,488-492,495,498,500,563-567,570-571,573-574,576-577,580-581,584,586,589-590,592-593,595-596,599-601,604,606,609-610,612-613,615-616,619-620,623,625,665,668,691,759,770,776,781,808,818,862-866,904,917,929,942,962,980,989,1065-1068,1083-1084,1109-1113,1121-1122,1157,1181-1182,1191-1192,1198-1199,1205-1206,1208-1209,1212-1213,1215-1216,1229,1231-1232,1236-1237,1243,1285-1286,1314,1320,1364-1368,1396-1397,1399-1403,1406,1409,1411,1414,1416,1419,1421-1423,1425-1427,1430-1432,1434-1436,1438-1441,1460-1462,1465-1467,1470-1472,1534-1535,1564-1566,1581-1583,1617-1618,1630-1631,1789-1793,1806-1807,1810,1813-1814,1817-1819,1821,1860,1897,1912-1914,1963-1964,1999-2000,2006-2007,2013-2014,2016-2017,2020-2021,2023-2024,2031,2047-2048
src/qdk/chemistry/data/pauli_operator.cpp
                                             756     683    90%   60,63,87-88,190,202-203,224,397,407,421-423,517,555-557,559-561,577-579,581-583,606,609,721,806,818,820-821,855,860-862,877,882-884,912,938-942,944,946,951,956,996,1014-1016,1029,1036-1037,1039-1044,1062,1073-1076,1202,1222,1300,1343
src/qdk/chemistry/data/settings.cpp         1236     598    48%   40-43,68-70,81,85,95-101,126-134,136-140,158-163,166-169,171-175,177-181,183,185-188,190-195,197-201,203-213,217-226,239,243,280,292-295,297-299,302-306,308-309,311-313,315-316,318-319,362-363,366,381,412-413,416-418,420-425,427,429-434,437,457-461,464-465,468,470,476,478,480,484,486,488,492,536-537,539,541,543-544,546-549,553-554,556-558,561-562,566-568,571-573,577,579,582-587,592-596,598-608,610-613,615-619,621-625,628,632-635,639-643,647-650,653-657,659-660,662,664-667,669-671,673-674,676-678,680,682-684,686-690,693-697,699,701-703,705-707,709-713,716-720,722,724-726,729-731,733,736-738,741-742,745-752,754-755,757-758,761-762,764-770,773-779,783,786-787,790-791,794-795,798-799,802-806,808,810,812-813,815-818,820-821,823-824,826-829,831-832,834,836-839,842,844-847,851-856,860-861,863,865-868,872,875-876,889,895,898,905,908,916,920,937,941-942,959-962,971,974,982-983,999-1004,1006,1008-1009,1052-1055,1057-1059,1071-1072,1084,1086,1231,1235-1238,1240-1241,1244,1246-1248,1250-1253,1255-1259,1264,1266-1269,1272,1274-1275,1281-1282,1285-1290,1292,1296,1298,1301,1308,1312-1314,1320,1324,1327-1328,1333,1335-1337,1341,1386,1393,1411,1462-1464,1494,1500-1503,1525-1526,1561-1562,1564,1593-1595,1614-1619,1645-1647,1649,1651-1652,1655-1657,1659-1661,1667,1688-1695,1698-1701,1757,1785,1800-1802,1808-1816,1818,1821-1824,1826-1835,1837-1846,1849-1856,1858-1860,1863-1873,1875-1880,1882-1884,1886-1892,1894-1896,1898,1900,1902-1906,1908-1912,1914-1916,1918-1919,1921-1928,1930-1939,1941-1943,1945-1947,1963
src/qdk/chemistry/data/stability_result.cpp
                                             317     292    92%   25,32,42,176,213,218,271,281,299,315,344,346,350,356,379,419,421,425,451,458,503-507
src/qdk/chemistry/data/structure.cpp         761     703    92%   86,101,115-116,127,140,159,176-177,204,245-246,295,479,492,512,530,649,665,802,816,964-966,974-975,985,995-996,1018-1019,1027,1055-1057,1063,1076,1122-1123,1126,1132-1135,1138-1147,1151-1153,1156
src/qdk/chemistry/data/wavefunction.cpp     1319    1137    86%   45,65,175,178,186-188,269-270,286,307-310,312-315,318,336-341,344,386,417,454,467,488,493,509-510,531,548,551,574,577,580-589,620-626,628-630,732-741,838-842,937-939,984,998,1011,1013,1018,1020,1042-1043,1102,1104-1105,1119,1121,1124-1125,1146-1149,1151,1186,1188-1189,1214,1231,1357,1456-1459,1487,1494,1500,1507,1523,1529-1531,1537,1548,1578-1579,1594-1595,1602-1603,1623,1628-1629,1635,1646,1682,1792-1793,1803-1804,1831,1857-1858,1888-1889,1961,1963,1966-1967,1975-1977,1995-1997,1999-2000,2006-2009,2012-2022,2024-2025,2027-2030,2033-2036,2038-2040,2042-2043,2045-2046
src/qdk/chemistry/data/wavefunction_containers/cas.cpp
                                             252     199    79%   76-77,79-82,84-85,87-88,90,92-93,95-96,98-99,101,116,161-162,166,168,172,174,178-179,191-193,199,201-204,207-210,227-228,231-232,337-339,359,377-378,387,398,421-422
src/qdk/chemistry/data/wavefunction_containers/cc.cpp
                                             878     525    59%   48,52,57,59,62,66,71-72,74-77,79,87-88,122-127,153-160,169-175,203-204,206-220,222-224,226-228,231,233-234,250,258-259,261,267,277,287,299,319,324,326-328,331-334,337,339-340,343,345-349,351-352,354-355,358-359,381-383,385-387,389-391,393-395,397-399,425,432,463-466,528-529,595-596,599,601,603,606-607,609-610,612,615,617-620,622-624,627-628,630,633,637,639-640,643,687,696-697,699,705-706,708-709,716,728,737-738,747-748,754,790,800,810,820,830,841,940-950,952-956,969-979,981,983-985,1058-1069,1071-1083,1085-1091,1093-1100,1115-1126,1128-1140,1142-1148,1150-1156,1171-1181,1183-1195,1197-1200,1202,1204-1207,1223-1232,1234-1246,1248-1251,1253-1257,1322-1324,1326-1327,1330,1332-1333,1335,1337-1338,1342-1344
src/qdk/chemistry/data/wavefunction_containers/mp2.cpp
                                             626     433    69%   32,36,40-41,45-47,60-62,78,85,110,139,150-151,178-179,227-228,243,313,318,320-322,325-327,330-333,336-341,343-349,351-353,374,437-438,468-469,477,490-492,494,498-500,502,535,544-545,547,553-554,556-557,564,576,585-586,606,623-624,627-628,631,633-639,641-644,646,648,650,652-658,660-663,665,667,669,671-677,679-682,684,688-697,703-712,718-727,734-736,738-739,743,745-746,748-750,754-757,759,925,931,933,964-965,968-969,973,975,1006,1023,1057,1081,1083,1088,1092-1102
src/qdk/chemistry/data/wavefunction_containers/sci.cpp
                                             213     176    82%   78-79,81-84,86-87,89-90,92,94-95,97-98,100-101,103,117,151,153,155-156,166-167,170-171,260-262,282,300-301,310,321,344-345
src/qdk/chemistry/data/wavefunction_containers/sd.cpp
                                             399     336    84%   17,42-46,54,56-60,111,113,118,120,136-137,140,143-144,156,158,161-162,200,202,205-206,275,277,280-282,309,311,314,316,369,371,467,497-498,501,511-512,515,562,571,577,591,599-602,646-647,664-665,683-684,694-695
src/qdk/chemistry/utils/logger.cpp           120     115    95%   201-203,237,281
src/qdk/chemistry/utils/orbital_rotation.cpp
                                              93      56    60%   60-62,140-142,145,149-150,152,154-155,176,178,180,182,185-186,188,192-193,196-197,200,202-203,205,208-211,214,218-219,221,223-224
src/qdk/chemistry/utils/valence_space.cpp
                                              43      37    86%   60-63,79,83
------------------------------------------------------------------------------
TOTAL                                      22968   17733    77%
------------------------------------------------------------------------------
Python Coverage Details
src/qdk_chemistry/data/time_evolution/base.py                                                       40     12    70%
src/qdk_chemistry/data/time_evolution/containers/__init__.py                                         0      0   100%
src/qdk_chemistry/data/time_evolution/containers/base.py                                            26      0   100%
src/qdk_chemistry/data/time_evolution/containers/pauli_product_formula.py                           93      4    96%
src/qdk_chemistry/data/time_evolution/controlled_time_evolution.py                                  46      8    83%
src/qdk_chemistry/definitions.py                                                                     8      0   100%
src/qdk_chemistry/plugins/__init__.py                                                                0      0   100%
src/qdk_chemistry/plugins/openfermion/__init__.py                                                   19      0   100%
src/qdk_chemistry/plugins/openfermion/conversion.py                                                 78     22    72%
src/qdk_chemistry/plugins/openfermion/qubit_mapper.py                                               63      1    98%
src/qdk_chemistry/plugins/pyscf/__init__.py                                                         18      0   100%
src/qdk_chemistry/plugins/pyscf/active_space_avas.py                                                80      7    91%
src/qdk_chemistry/plugins/pyscf/conversion.py                                                      264     16    94%
src/qdk_chemistry/plugins/pyscf/coupled_cluster.py                                                 101     27    73%
src/qdk_chemistry/plugins/pyscf/localization.py                                                     72      8    89%
src/qdk_chemistry/plugins/pyscf/mcscf.py                                                           125     15    88%
src/qdk_chemistry/plugins/pyscf/scf_solver.py                                                      102      5    95%
src/qdk_chemistry/plugins/pyscf/stability.py                                                       154      2    99%
src/qdk_chemistry/plugins/qiskit/__init__.py                                                        43      0   100%
src/qdk_chemistry/plugins/qiskit/_interop/__init__.py                                                0      0   100%
src/qdk_chemistry/plugins/qiskit/_interop/circuit.py                                               130      0   100%
src/qdk_chemistry/plugins/qiskit/_interop/noise_model.py                                            26      4    85%
src/qdk_chemistry/plugins/qiskit/_interop/qir.py                                                    87     25    71%
src/qdk_chemistry/plugins/qiskit/_interop/transpiler.py                                            139      6    96%
src/qdk_chemistry/plugins/qiskit/circuit_executor.py                                                38      0   100%
src/qdk_chemistry/plugins/qiskit/conversion.py                                                      31      0   100%
src/qdk_chemistry/plugins/qiskit/qubit_mapper.py                                                    36      1    97%
src/qdk_chemistry/plugins/qiskit/regular_isometry.py                                                40      0   100%
src/qdk_chemistry/plugins/qiskit/standard_phase_estimation.py                                       67      4    94%
src/qdk_chemistry/utils/__init__.py                                                                  4      0   100%
src/qdk_chemistry/utils/cubegen.py                                                                  90     90     0%
src/qdk_chemistry/utils/enum.py                                                                     23      3    87%
src/qdk_chemistry/utils/model_hamiltonians.py                                                       43      1    98%
src/qdk_chemistry/utils/pauli_commutation.py                                                        97      3    97%
src/qdk_chemistry/utils/pauli_matrix.py                                                             74      0   100%
src/qdk_chemistry/utils/phase.py                                                                    39      1    97%
src/qdk_chemistry/utils/qsharp/__init__.py                                                          17      0   100%
src/qdk_chemistry/utils/telemetry.py                                                               142     87    39%
src/qdk_chemistry/utils/telemetry_events.py                                                         59     48    19%
src/qdk_chemistry/utils/wavefunction.py                                                             57     57     0%
--------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                             5428    743    86%
Coverage HTML written to dir ../coverage-reports/python_coverage_html
Coverage XML written to file ../coverage-reports/python_coverage.xml
=========================== short test summary info ============================
SKIPPED [3] tests/test_docs_examples.py:186: Skipping slow test. Set QDK_CHEMISTRY_RUN_SLOW_TESTS=1 to enable.
SKIPPED [1] tests/test_sample_workflow.py:219: Skipping slow test. Set QDK_CHEMISTRY_RUN_SLOW_TESTS=1 to enable.
SKIPPED [1] tests/test_sample_workflow.py:236: Skipping slow test. Set QDK_CHEMISTRY_RUN_SLOW_TESTS=1 to enable.
SKIPPED [1] tests/test_sample_workflow_rdkit.py:30: Skipping: RDKit not installed
=========== 1449 passed, 6 skipped, 1 warning in 1337.38s (0:22:17) ============
Pybind11 Coverage Details
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines     Exec  Cover   Missing
------------------------------------------------------------------------------
src/pybind11/algorithms/active_space.cpp      38       38   100%
src/pybind11/algorithms/davidson_solver.cpp
                                              35       34    97%   28
src/pybind11/algorithms/dynamical_correlation_calculator.cpp
                                              31       31   100%
src/pybind11/algorithms/factory_bindings.hpp
                                             288      239    83%   32,32,32,32,32,32,32,32-33,33,33,33,33,33,33,33-34,34,34,34,34,34,34,34-35,35,35,35,35,35,35,35-36,36,36,36,36,36,36,36,249,249,249,249,249,249,249,249,249
src/pybind11/algorithms/hamiltonian.cpp       36       36   100%
src/pybind11/algorithms/localizer.cpp         38       38   100%
src/pybind11/algorithms/mc.cpp                37       37   100%
src/pybind11/algorithms/mcscf.cpp             34       34   100%
src/pybind11/algorithms/pmc.cpp               36       35    97%   178
src/pybind11/algorithms/scf.cpp               35       35   100%
src/pybind11/algorithms/stability.cpp         34       34   100%
src/pybind11/algorithms/syev_solver.cpp       19       18    94%   43
src/pybind11/constants.cpp                    89       89   100%
src/pybind11/data/ansatz.cpp                  69       69   100%
src/pybind11/data/basis_set.cpp              204      204   100%
src/pybind11/data/configuration.cpp           30       29    96%   200
src/pybind11/data/configuration_set.cpp       84       84   100%
src/pybind11/data/data_class.cpp             109       27    24%   19-20,23-24,27,29,32,34-37,39-44,46,48-49,52,54,57-59,64,67,71-72,75,78-79,81-82,90,92,94-96,98,101,104-105,107,110,113-115,117-120,124,126,128-129,131,133,135-137,139,141,143-145,150-151,153,156-157,159,162-163,165,168-169,171,174,176,178,249
src/pybind11/data/element_data.cpp           123      123   100%
src/pybind11/data/hamiltonian.cpp            247      238    96%   62,65,67,458,477,650,670,855,876
src/pybind11/data/lattice_graph.cpp          101       82    81%   20,23,25,27,29-30,51,53-54,423-425,429,448,459,562,564,566,568
src/pybind11/data/orbitals.cpp               138      137    99%   940
src/pybind11/data/path_utils.hpp              19       11    57%   37,39,42-47
src/pybind11/data/pauli_operator.cpp         274      254    92%   146,257,322,398,403,409,415,427,467,473,505,511,517,529,604,636,641,655,659,667
src/pybind11/data/property_binding_helpers.hpp
                                             312      312   100%
src/pybind11/data/serialization.cpp            5        5   100%
src/pybind11/data/settings.cpp               834      570    68%   40-41,57-58,110-111,117-118,123-124,129,131,136,138,164-168,177-179,182-185,190-194,198-200,210-213,217-221,230-233,237-242,246-249,259-262,266-270,273-277,281-291,293-311,313-327,333,335,337-338,342,345-347,400,450,452-453,536,544-546,548,552,571-577,633-636,643-649,651,654,656,658-661,668,670,713,784,1444,1452,1458,1461,1580,1614,1692,1755,1780,1805,1831,1895,1983-1984,1986-1990,2024-2028,2030-2035,2086,2140,2166-2167,2169,2172-2175,2201,2243-2244,2246-2247,2278-2279,2281,2284-2287,2314-2316,2337-2339,2341-2342,2361-2367,2387-2389,2391-2392,2414-2418,2420-2425,2456-2457,2475-2481,2503-2504,2522-2528,2658
src/pybind11/data/stability_result.cpp       112      112   100%
src/pybind11/data/structure.cpp              199      184    92%   69,72,75-78,82-84,87,90-91,969,977,999
src/pybind11/data/wavefunction.cpp           365      347    95%   39,98,100,264-265,268,272,278,473-477,479,1016,1018,1064,1067
src/pybind11/module.cpp                       47       47   100%
src/pybind11/qdk_scf_config.cpp               12       12   100%
src/pybind11/utils/cube.cpp                   59       33    55%   27,29-35,115-121,142-148,168-171
src/pybind11/utils/logger.cpp                191      177    92%   27,54,68-69,92,97-99,105-106,262-263,476,480
src/pybind11/utils/model_hamiltonians.cpp
                                              62       62   100%
src/pybind11/utils/orbital_rotation.cpp        7        7   100%
src/pybind11/utils/valence_space.cpp           5        5   100%
------------------------------------------------------------------------------
TOTAL                                       4358     3829    87%
------------------------------------------------------------------------------

@ConradJohnston Conrad Johnston (ConradJohnston) changed the title Add native cube generation support Add native cube generator backed by GauXC OrbitalEvaluator Apr 29, 2026
@ConradJohnston
Conrad Johnston (ConradJohnston) force-pushed the feature/cojoh/native-cubegen-v2 branch 3 times, most recently from fb6328d to 6ac7498 Compare April 29, 2026 22:31
Replace PySCF cubegen with a native C++ implementation that uses
GauXC's OrbitalEvaluator for MO and density evaluation on cube grids,
and GauXC's write_cube for file output.

This eliminates:
- The vendored gauxc-private/ header (no longer needed — OrbitalEvaluator
  is the public API for point-set evaluation)
- 600+ lines of hand-rolled collocation batching, GEMM, and text
  formatting code (all now in GauXC upstream)

GauXC pin bumped to ConradJohnston/GauXC@10f59a8 which includes
OrbitalEvaluator with shell screening, pipelined collocation+GEMM,
CubeGrid-native overloads, and parallel cube writer.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a native C++ Gaussian cube-field generator backed by GauXC’s OrbitalEvaluator, updates the GauXC dependency to the specified upstream commit, and adds focused regression tests plus a clang-cl compatibility patch for Gau2Grid.

Changes:

  • Added CubeGrid / CubeGenerator to evaluate orbitals and density on 3D grids and optionally write cube files via GauXC::write_cube.
  • Updated GauXC pin to commit 162e4562… and added a clang-cl patch hook for Gau2Grid’s generated helper.
  • Added C++ regression tests for grid construction, orbital/density evaluation, and input validation; added a vcpkg overlay port for libaec.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cpp/include/qdk/chemistry/cube/cube_generator.hpp Declares CubeGrid, CubeGenerator, and generate_orbital_cubes API.
cpp/src/qdk/chemistry/cube/cube_generator.cpp Implements GauXC-backed orbital/density evaluation and cube writing.
cpp/src/qdk/chemistry/cube/CMakeLists.txt Adds cube generator sources to the chemistry target.
cpp/CMakeLists.txt Wires the new cube subdirectory into the C++ build.
cpp/tests/test_cube_generator.cpp Adds regression tests for grid sizing, evaluation correctness, and error cases.
cpp/cmake/third_party.cmake Updates GauXC commit pin and applies a clang-cl patch during FetchContent.
cpp/cmake/patches/gauxc-clang-cl-gau2grid-stdlib.cmake Implements Gau2Grid helper patching for clang-cl builds.
.pipelines/install-scripts/install-cpp-deps-windows.ps1 Applies the same GauXC clang-cl patch in the Windows dependency install script.
cpp/manifest/qdk-chemistry/cgmanifest.json Updates the recorded GauXC commit hash to the new pin.
vcpkg-overlay/ports/libaec/vcpkg.json Adds an overlay port definition for libaec.
vcpkg-overlay/ports/libaec/portfile.cmake Builds/installs libaec and fixes up exported targets for vcpkg usage.
vcpkg-overlay/ports/libaec/usage Documents CMake usage for the overlay libaec port.
Suppressed comments (1)

cpp/tests/test_cube_generator.cpp:110

  • This test uses std::numbers::pi (C++20). Since the tests are built as C++17, compute π via std::acos(-1.0) instead.
  const double r_squared = grid.origin.squaredNorm();
  const double normalization = 2.0 * std::pow(2.0 / std::numbers::pi, 0.75);
  const double radial = normalization * std::exp(-r_squared);

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cpp/tests/test_cube_generator.cpp Outdated
Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp Outdated
Comment thread cpp/cmake/patches/gauxc-clang-cl-gau2grid-stdlib.cmake
Copilot AI review requested due to automatic review settings August 11, 2026 19:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

Suppressed comments (3)

cpp/cmake/patches/gauxc-clang-cl-gau2grid-stdlib.cmake:10

  • This patch script assumes the helper file always exists and only checks for a very specific include ordering. If GauXC changes the path or if <stdlib.h> is already included elsewhere, the script can fail the configure step (missing file) or inject a duplicate include.
set(_helper "external/gau2grid/generated_source/gau2grid_helper.c")
file(READ "${_helper}" _content)

if(NOT _content MATCHES "#include <stdlib.h>\n#include <math.h>")
  string(REPLACE "#include <math.h>"
                 "#include <stdlib.h>\n#include <math.h>"
                 _content "${_content}")

cpp/src/qdk/chemistry/utils/cube_generator.cpp:57

  • Error message capitalization is inconsistent ("gauXC") and likely meant to reference GauXC. This makes logs harder to search and is inconsistent with other GauXC references in this PR.
  constexpr auto max =
      static_cast<std::size_t>(std::numeric_limits<int64_t>::max());
  if (nx > max / ny || nx * ny > max / nz)
    throw std::overflow_error("CubeGrid: point count exceeds gauXC's limit.");
  return nx * ny * nz;

cpp/src/qdk/chemistry/utils/cube_generator.cpp:186

  • generate_orbital_cubes calls std::filesystem::create_directories(output_dir) without validating output_dir. Passing an empty string can throw a filesystem_error (platform-dependent) instead of a clear invalid_argument, which is a surprising API contract for a utility function.
  CubeGenerator gen(wfn.get_orbitals()->get_basis_set());
  const auto& C_a = wfn.get_orbitals()->coefficients()->block(
      {data::axes::alpha(), data::axes::alpha()});
  std::filesystem::create_directories(output_dir);

Validate grid dimensions and unsupported basis shells, migrate orbital access to the current API, and add focused cube generator regression tests.
Keep preinstalled CI dependencies aligned with the CMake pin so the upstream cube-generation headers are available on every platform.
Avoid the unnecessarily strict 1e-12 shell tolerance so cube evaluation benefits from gauXC's performance-oriented default while retaining conservative accuracy.
Override the vcpkg libaec source archive with its canonical GitHub mirror to avoid repeated GitLab rate-limit failures in Windows dependency installation.
Include stdlib.h in GauXC's generated Gau2Grid helper when preparing clang-cl dependencies so exit() is declared under C99 rules.
The class docstring listed origin and spacing under Attributes: while both
were also exposed as read/write properties. With undoc-members enabled,
Sphinx documented each of them twice and the autosummary build fails on any
warning. Move the descriptions onto the properties themselves.
Copilot AI review requested due to automatic review settings August 17, 2026 14:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

The bounds check ran on the already-narrowed value, so a shell with more than
INT32_MAX primitives would truncate to a small count and slip past it, building
a silently wrong shell. Compare the original size instead.
Copilot AI review requested due to automatic review settings August 17, 2026 16:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.

Suppressed comments (5)

python/src/pybind11/utils/cube_generator.cpp:204

  • The generate_orbital_cubes Python docstring says output_dir must already exist, but the C++ implementation creates it (std::filesystem::create_directories). This mismatch can mislead users; update the docstring to match the actual behavior.
Args:
    orbitals: Orbitals supplying the basis set and coefficients.
    indices: Zero-based orbital indices to write.
    output_dir: Existing directory to write the cube files into.
    grid: Grid to evaluate on.
    label_prefix: Prefix of the generated file names.

python/src/qdk_chemistry/utils/cubegen.py:68

  • The docstring documents only ValueError for invalid backend, but the backend="pyscf" branch imports pyscf lazily and will raise ImportError when PySCF isn't installed (e.g., Windows). Document this explicitly so callers know what exception to expect.
    Raises:
        ValueError: If ``backend`` is not ``"native"`` or ``"pyscf"``.

cpp/src/qdk/chemistry/utils/cube_generator.cpp:277

  • For restricted orbitals, the generated filename has no spin suffix, but the cube comment line currently labels the orbital as "(alpha)". That’s misleading for restricted wavefunctions (there is only a spatial orbital). Consider dropping the spin qualifier in this branch.
    // Restricted: a single spatial cube with no spin suffix. Unrestricted:
    // separate alpha (`_a`) and beta (`_b`) cubes, mirroring `cubegen.py`.
    if (restricted) {
      emit(C_a.col(p), stem + ".cube",
           "Orbital " + std::to_string(p) + " (alpha)");

python/tests/test_utils_cube_generator.py:80

  • Most tests in this file (including all CubeGenerator and generate_orbital_cubes coverage) are skipped when PySCF is unavailable. Since one of the main goals of the native backend is to enable Windows usage without PySCF, this leaves the Python bindings largely untested on that target. Consider adding at least a small PySCF-free smoke test (e.g., build a BasisSet via BasisSet.from_basis_name, create identity Orbitals, and assert CubeGenerator.orbital/generate_orbital_cubes run and write files) and only skipping the strict PySCF equivalence tests.
@pytest.mark.skipif(not PYSCF_AVAILABLE, reason="PySCF not available")
class TestCubeGenerator:
    """Tests for orbital and density evaluation."""

python/tests/test_utils_cubegen.py:126

  • This module is globally skipped when PySCF is not available (pytestmark = skipif(...)), but the new default backend is native specifically to work without PySCF (notably on Windows). As-is, there’s no test that exercises generate_cubefiles_from_orbitals(..., backend="native") in an environment where PySCF truly cannot be imported. Consider moving the global skip down onto only the PySCF-dependent tests and adding a small smoke test that asserts importing qdk_chemistry.utils.cubegen and calling the native backend does not import PySCF (e.g., via an import hook).
    def test_native_backend_matches_pyscf_backend(self):
        """Both backends must place the grid identically and agree on every field value.

        This is the guard on making the native backend the default: switching
        it must not move a single grid point or change a single value beyond
        the precision the cube format itself can represent.
        """
        orbitals = _o2_orbitals()
        kwargs = {"indices": [0, 3], "grid_size": (8, 8, 8)}
        native = generate_cubefiles_from_orbitals(orbitals, backend="native", **kwargs)
        reference = generate_cubefiles_from_orbitals(orbitals, backend="pyscf", **kwargs)

The single hydrogen atom at the origin is already provided by
testing::create_hydrogen_structure in ut_common.hpp, and
EvaluatesHydrogenOrbitalAndDensity was rebuilding the grid that
single_point_grid already returns.
Copilot AI review requested due to automatic review settings August 17, 2026 17:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.

Suppressed comments (1)

python/src/pybind11/utils/cube_generator.cpp:204

  • The generate_orbital_cubes Python docstring says output_dir must be an existing directory, but the C++ implementation explicitly calls std::filesystem::create_directories(output_dir) (so it will create it). This is user-facing API documentation and should match actual behavior.
    orbitals: Orbitals supplying the basis set and coefficients.
    indices: Zero-based orbital indices to write.
    output_dir: Existing directory to write the cube files into.
    grid: Grid to evaluate on.
    label_prefix: Prefix of the generated file names.

Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp
Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp
Comment thread python/src/qdk_chemistry/utils/cubegen.py
Comment thread cpp/cmake/third_party.cmake
Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp
Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 243329d9-adbf-472d-ad3d-136741e7e8cf

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Suppressed comments (2)

python/tests/test_utils_cube_generator.py:105

  • TestCubeGenerator (which contains the main behavioral coverage for CubeGenerator) is entirely skipped when PySCF isn't installed. That leaves the new native cube backend effectively untested on Windows (the primary motivation for this PR), even though CubeGenerator itself doesn't depend on PySCF.

Add at least one smoke test that constructs a minimal spherical BasisSet directly (no PySCF) and verifies CubeGenerator.orbital(...) returns the expected shape and can write a cube file.

@pytest.mark.skipif(not PYSCF_AVAILABLE, reason="PySCF not available")
class TestCubeGenerator:
    """Tests for orbital and density evaluation."""

cpp/cmake/modules/DependencyManager.cmake:88

  • REQUIRED_HEADER validation uses check_include_file_cxx, but only sets CMAKE_REQUIRED_LIBRARIES to ${ARG_INSTALL_TARGET}. That does not reliably propagate the target's include directories into the check, so this can produce false negatives (especially when dependency fetching is disabled and the dependency is only available via find_package).

Populate CMAKE_REQUIRED_INCLUDES from the discovered target's INTERFACE_INCLUDE_DIRECTORIES (when the install target is a CMake target) before calling check_include_file_cxx.

        set(_saved_cmake_required_libraries "${CMAKE_REQUIRED_LIBRARIES}")
        set(CMAKE_REQUIRED_LIBRARIES "${ARG_INSTALL_TARGET}")
        check_include_file_cxx("${ARG_REQUIRED_HEADER}"
                               ${_required_header_check})
        set(CMAKE_REQUIRED_LIBRARIES "${_saved_cmake_required_libraries}")

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Suppressed comments (3)

python/src/qdk_chemistry/utils/cubegen.py:71

  • The docstring notes that the PySCF backend raises ImportError when PySCF isn’t installed, but the formal Raises: section only lists ValueError. This makes the documented exception contract incomplete for callers doing exception handling.
    Raises:
        ValueError: If ``backend`` is not ``"native"`` or ``"pyscf"``, or if
            ``backend="pyscf"`` is requested for a Cartesian basis.

python/src/qdk_chemistry/utils/cubegen.py:122

  • For the native backend, cube files are written with an empty comment line (no comment= is passed to CubeGenerator.orbital). That makes returned cube text / written cubes less self-describing than the PySCF backend and than generate_orbital_cubes (which embeds an orbital label in the comment). Consider passing a stable label (e.g. derived from the output filename) so the cube header identifies what was generated.
        else:
            outfile_name = output_folder / label
        _write_cube(coeff, outfile_name)

python/tests/test_utils_cube_generator.py:102

  • Most of the Python binding tests for CubeGenerator/generate_orbital_cubes are skipped when PySCF isn’t installed. Since this PR’s key goal is enabling cube generation on Windows (where PySCF is typically unavailable), it would be good to add at least one smoke test that exercises the native backend end-to-end without requiring PySCF (construct a minimal BasisSet/Orbitals, write a cube into tmp_path, and assert it exists).
@pytest.mark.skipif(not PYSCF_AVAILABLE, reason="PySCF not available")
class TestCubeGenerator:
    """Tests for orbital and density evaluation."""

Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 243329d9-adbf-472d-ad3d-136741e7e8cf

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

python/tests/test_utils_cube_generator.py:99

  • The native backend is meant to enable cube generation when PySCF is not installed (notably on Windows), but this test module only exercises native evaluation under PYSCF_AVAILABLE skips. Adding a small, non-PySCF test that calls generate_cubefiles_from_orbitals(..., backend="native") would ensure the new default path is exercised on platforms without PySCF and that the bindings work end-to-end.
def test_pyscf_backend_rejects_cartesian_basis_before_import(tmp_path):
    """PySCF cannot consume the Cartesian AO coefficient layout."""
    structure = Structure(["O"], np.zeros((1, 3)))
    shell = Shell(0, OrbitalType.D, np.array([1.0]), np.array([1.0]))
    basis_set = BasisSet("cartesian-d", [shell], structure, AOType.Cartesian)
    nbf = basis_set.get_num_atomic_orbitals()
    orbitals = Orbitals(np.eye(nbf), None, None, basis_set)

    with pytest.raises(ValueError, match="does not support Cartesian"):
        generate_cubefiles_from_orbitals(
            orbitals,
            output_folder=tmp_path,
            indices=[0],
            grid_size=(2, 2, 2),
            backend="pyscf",
        )
    assert list(tmp_path.iterdir()) == []

cpp/src/qdk/chemistry/utils/cube_generator.cpp:32

  • CubeGrid::from_basis_set rejects negative margins but will accept NaN/Inf margins (since margin < 0.0 is false for NaN). That can propagate NaNs into origin/spacing and then into GauXC evaluation/writing. Since this is a public API (also bound to Python), it should reject non-finite margins explicitly.
  if (nx == 0 || ny == 0 || nz == 0)
    throw std::invalid_argument("CubeGrid: dimensions must be positive.");
  if (margin < 0.0)
    throw std::invalid_argument("CubeGrid: margin cannot be negative.");

Comment thread vcpkg-overlay/ports/libaec/portfile.cmake
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 243329d9-adbf-472d-ad3d-136741e7e8cf

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

python/src/pybind11/utils/cube_generator.cpp:203

  • The generate_orbital_cubes binding docstring says output_dir must be an existing directory, but the C++ implementation calls std::filesystem::create_directories(output_dir) and will create it if missing. This mismatch can mislead callers and test expectations.
Args:
    orbitals: Orbitals supplying the basis set and coefficients.
    indices: Zero-based orbital indices to write.
    output_dir: Existing directory to write the cube files into.
    grid: Grid to evaluate on.

Comment thread cpp/src/qdk/chemistry/utils/cube_generator.cpp Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 243329d9-adbf-472d-ad3d-136741e7e8cf

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Suppressed comments (2)

python/src/qdk_chemistry/utils/cubegen.py:70

  • The docstring says the PySCF backend raises ImportError when PySCF is unavailable, but the "Raises:" section currently documents only ValueError. This makes the API contract incomplete for users relying on the raised-exceptions list.
    Raises:
        ValueError: If ``backend`` is not ``"native"`` or ``"pyscf"``, or if
            ``backend="pyscf"`` is requested for a Cartesian basis.

python/tests/test_utils_cube_generator.py:99

  • This test module has a non-skipped test that exercises only the PySCF backend's early rejection path. Since the PR's main goal is to make cube generation work without PySCF (e.g., on Windows), it would be valuable to add at least one unskipped test that calls generate_cubefiles_from_orbitals with backend="native" and asserts it writes a valid cube (or returns cube text) without requiring PySCF.
def test_pyscf_backend_rejects_cartesian_basis_before_import(tmp_path):
    """PySCF cannot consume the Cartesian AO coefficient layout."""
    structure = Structure(["O"], np.zeros((1, 3)))
    shell = Shell(0, OrbitalType.D, np.array([1.0]), np.array([1.0]))
    basis_set = BasisSet("cartesian-d", [shell], structure, AOType.Cartesian)
    nbf = basis_set.get_num_atomic_orbitals()
    orbitals = Orbitals(np.eye(nbf), None, None, basis_set)

    with pytest.raises(ValueError, match="does not support Cartesian"):
        generate_cubefiles_from_orbitals(
            orbitals,
            output_folder=tmp_path,
            indices=[0],
            grid_size=(2, 2, 2),
            backend="pyscf",
        )
    assert list(tmp_path.iterdir()) == []

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants