Adding Add-Ons¶
How to use an Add-On’s name in directory structure, build, and distribution¶
- Select a name. May be mixed case with numerals and underscores (e.g., CheMPS2, libefp, PCMSolver, v2rdm_casscf). Shouldn’t start with a numeral. Needn’t start with “lib”, even if a library.
- GitHub repository name should be
AddOn_nameorAddOn_name.lower()(hereafter,addon_name. For example: CheMPS2, libefp, pcmsolver, v2rdm_casscf. - CMake project name should be
AddOn_name. For example:project(libefp),project(CheMPS2),project(PCMSolver),project(v2rdm_casscf). Namespacing in the directory structure used to detect the addon should have this name (e.g.,share/cmake/CheMPS2). - Restricted by the CMake project name, add-ons return CMake variables
and compile definitions of
FOUND_AddOn_nameandUSING_AddOn_name. For example:FOUND_libefp,USING_CheMPS2,PCMSolver_LIBRARIES,USING_v2rdm_casscf. - The CMake target(s) formed use the full add-on name as the namespace,
AddOn_name::lib_name_without_lib.lower(). For example:libefp::efp,CheMPS2::chemps2,PCMSolver::pcm,v2rdm_casscf::v2rdm_casscf. - Following the CMake project name (though not restricted to it –
PSI4 managment could change the pattern), the user flag to enable
an add-on is
ENABLE_AddOn_name. Note that runtime-only add-ons don’t go through this enabling process. - Internally, the ExternalProject_Add and dummy libraries as well as any
tests/ and external/ subdirectories should all be lowercase,
addon_name. - The conda package and internal to
PSI4 (that is, the ExternalProject_Add, dummy libraries, and any
tests/ and external/ subdirectories) should all be lowercase,
addon_name. - Alternatively, you can do everything mentioned here lowercase and just have a different capitalization for an advertising name. After all, that’s what PSI4 does.
How to integrate an Add-On into build, testing, and docs¶
- In all cases, put Add-Ons in alphabetic order, ignoring any “lib” in the name.
- psi4/CMakeLists.txt
- Add the
ENABLE_AddOn_nameline - Add the
external_addon_namedependency to thepsi4-coreexternal project - Add the
AddOn_name_DIRvariable passing to thepsi4-coreexternal project
- Add the
- psi4/psi4/CMakeLists.txt
- Add a block imitating Libint if Add-On required or CheMPS2 if not required
- If there are shared resources to the external that need
to be found by PSI4 in PSIDATADIR, follow the
efpfragpattern of libefp to symlink them in.
- psi4/psi4/src/CMakeLists.txt
- No changes should be required unless both (1) code in export_*
or core.cc needs the
USING_AddOn_namedefinition or AddOn header includes and (2) no binary PSI4 module (as opposed to library PSI4 module with the AddOn target linked is itself a direct dependency of targetcore. Basically, try to leave this file alone, but if there are compile errors, add the definitions/headers as needed.
- No changes should be required unless both (1) code in export_*
or core.cc needs the
- psi4/psi4/src/psi4/
- If a module is needed to interface the AddOn to PSI4, try to
put “interface” in the name. Follow the pattern of CheMPS2 or gdma.
If non-required, be sure to conditionalize it with
if(TARGET AddOn::addon)in CMake files or#ifdef USING_AddOnin source files. - If a separate module is not required, follow the patter of dkh or simint with respect to libmints. Again, conditionalize as in preceding bullet.
- If a module is needed to interface the AddOn to PSI4, try to
put “interface” in the name. Follow the pattern of CheMPS2 or gdma.
If non-required, be sure to conditionalize it with
- psi4/psi4/external/upstream/
- Add a CMakeLists.txt that imitates another AddOn of similar
language and dependencies. Try to keep the format, messaging,
and variables passed as similar as possible so that differences
mean something. If BLAS/LAPACK or other common dependencies in
psi4/psi4/common/ are needed, be sure to add them to the
DEPENDSargument. - The usual practice to to get everything cohesive between
the CMake for the AddOn repository and PSI4 and then as a
last step, mint a tag in the former and add it to two places in
psi4/external/upstream/addon_name/CMakeLists.txtand one place in psi4/psi4/CMakeLists.txt so that only that version and later are acceptable to PSI4 for detecting pre-built.
- Add a CMakeLists.txt that imitates another AddOn of similar
language and dependencies. Try to keep the format, messaging,
and variables passed as similar as possible so that differences
mean something. If BLAS/LAPACK or other common dependencies in
psi4/psi4/common/ are needed, be sure to add them to the
- psi4/tests/
- In psi4/tests/CMakeLists.txt, add a block adding a tests subdirectory if Add-On enabled
- Create new subdirectory
tests/addon_namewith a CMakeLists.txt. In that add a few tests. Imitate the pattern in other subdirs of including the addon prefix to the test name in the CMakeLists but not in the test dir name. Make sure the tests get the addon CTest label and that at least one of them gets the smoke label.
- psi4/doc/sphinxman/
- Create a new .rst page, copying one of the Add-Ons with similar language and dependency requirements. Edit it as appropriate. Add this page to the list in psi4/doc/sphinxman/source/interfacing.rst.
- Add a bullet to psi4/doc/sphinxman/source/build_planning.rst
- Add the new page to the long list in psi4/doc/sphinxman/CMakeLists.txt. If there are any files or images referred to, add them to the file, too, following precedent.
else¶
- Build conda packages
- PSI4 and Add-On Projects Working Together
- Obligations of the External Project owners are to:
- allow us to contribute some CMake files to your build system so that compile flags and dependencies (e.g., BLAS/LAPACK) can be consistent with the PSI4 build and so the installed project can be readily detected by PSI4 or any interested party (through a CMake imported target).
- provide us a tag at a tested commit/version number so their development may be ongoing.
- communicate with us when they’ve made improvements and minted a new tag.
- In return, for Add-Ons the PSI4 project will:
- leave control of their code under your purview.
- maintain any interfacing code needed.
- regularly run integration tests between PSI4 and your code.
- build a mostly statically linked conda package so that any
of your users can obtain a pre-built binary distribution through
conda install addon --channel psi4. - provide a development sandbox for your code through PSI4 plugins.
- provide conda download counts independent of PSI4.
- Obligations of the External Project owners are to:
How to name keywords in psi4/src/read_options.cc¶
A few guidelines for standardizing option names among modules.
TRIPLES(not trip),TRIPLETS(not trip),SINGLES(not sing),SINGLETS(not sing)CONVERGENCE(not conv, not converge) andTOLERANCE(not tol)- Convergence of a method should be governed by an
E_CONVERGENCEfor energy and either aD_CONVERGENCEfor density or aR_CONVERGENCEfor residual/amplitudes. All of these should be doubles- let the input parser handle the flexible input format. - Diis should have a boolean
DIIS(not do_diis, not use_diis) to turn on/off diis extrapolation, aDIIS_MIN_VECSandDIIS_MAX_VECSfor minimum and maximum number of diis vectors to use, and aDIIS_STARTwhich is the iteration at which to start saving vectors for diis. Not all modules conform to all these at present, but they’re as standardized as they can be without changing code. AMPS(not amplitude, not amp) for amplitudesNUM_(not n) for number (e.g.,NUM_AMPS_PRINT,MAX_NUM_VECS,NUM_THREADS)- Some names that could be split into multiple words are staying as one.
Use
MAXITER,CACHELEVEL,PUREAM,DERTYPE. INTS(not integrals), alsoOEI(not oe_integrals) for one-electron integrals andTEI(not te_integrals) for two-electron integralsPERTURB(not pert) for perturbation- Use
PRINToptions to indicate printing to output file. UseWRITEoptions to indicate printing to another file. This probably isn’t entirely valid now but should be observed in future. The complement toWRITEisREAD.PRINT,READ, andWRITEwill usually be the last words in an option name. - Use
FOLLOW_ROOTfor the state to be followed in geometry optimizations WFN(not wavefunction)- You’re welcome to use
WFNandDERTYPEas internal options, but plan to have these set by the python driver and mark them as!expertoptions. Really avoid usingJOBTYPE. - You’re not welcome to add
CHARGEorMULTPoptions. Plan to get these quantities from the molecule object. Since we frequently use subsets of systems (with their own charge and multiplicity), this is safer. - Conform. Just grep
'add' psi4/src/read_options.ccto get a list of all the option names in PSI4 and try to match any conventions you find. - If you have a quantity you’d like to call a cutoff, a threshold, a
tolerance, or a convergence, consider the following guidelines in naming
it.
- If its value is typically greater than ~0.001, give it a name with
CUTOFF. - If its value is typically less than ~0.001 and quantities being tested
against the option are more valuable with larger values (e.g.,
integrals, occupations, eigenvectors), give it a name with
TOLERANCE. - If its value is typically less than ~0.001 and quantities being tested
against the option are more valuable with smaller values (e.g., energy
changes, residual errors, gradients), give it a name with
CONVERGENCE.
- If its value is typically greater than ~0.001, give it a name with
- In deciding how to arrange words in an option name, place the context
first (e.g.,
MP2_AMPS_PRINT,TRIPLES_DIIS). This meansPRINTwill generally be at the end of an option name. - Use
INTS_TOLERANCE(not schwarz_cutoff) Hin an option name is reserved for Hamiltonian (or hydrogen). Hessian should beHESS.- All option names should be all caps and separated by underscores.
- If you have an option that instructs your module to do something not too
computationally intensive and then quit, append
_EXITto the option name. - Scaling terms (like for scs) should follow the pattern
MP2_SS_SCALEandSAPT_OS_SCALE. FRAGfor fragment.AVGfor average.- For level-shifting, let’s try to have it governed by (double)
LEVEL_SHIFTonly and not a boolean/double combo since the procedure can be turned on (role of boolean) if the value (role of double) has changed. - For Tikhonow regularization, use
TIKONOW_OMEGA, not regularizer. SYMfor symmetry.OCCfor occupied/occupation (e.g.,DOCC,LOCK_OCC,OCC_TOLERANCE).CONDfor condition andCONDITIONERfor conditioner.LOCAL(not localize).- Use
AOandMOfor atomic and molecular orbitals. When ‘O’ for orbitals is too obsure or would make for too short a keyword, as in “bool NO” for “Do use natural orbitals”, useORBSfor orbitals. So natural orbitals areNAT_ORBSand Brueckner orbitals areBRUECKNER_ORBS. LEVEL(notLVL, notLEV).EXfor excitation.VALfor valence.GEOM(not geo, not geometry).SYM(not symm, not symmetry).FILE(unless truly multiple FILES).WRITE/READfor info transfer across jobs.SAVE/RESTARTfor same in context of restart.- Damping should interface through option (double)
DAMPING_PERCENTAGE, where a value of 0.0 indicates no damping. - Try to avoid
COMPUTEorCALCin an option name. If it’s a boolean like “opdm_compute” for “Do compute the one-particle density matrix”, just useOPDM. - Properties should be governed by a
PROPERTIESarray for the root of interest or by aPROPERTIES_ALLarray for all roots in a multi-root calc. Since no module conforms to this right now, usePROPERTYalone andPROPin multi-part option asPROP_ROOT,PROP_ALL,PROP_SYMto conform. - Use
DF(not ri) for density-fitting and resolution-of-the-identity option names. Only the basis sets are staying as -RI since that’s what EMSL uses.