Unified Coulomb/Exchange Gradient#

group JKGrad

Functions

cuestStatus_t cuestDFSymmetricDerivativeCompute(
cuestHandle_t handle,
cuestDFIntPlan_t plan,
const cuestDFSymmetricDerivativeComputeParameters_t parameters,
const cuestWorkspaceDescriptor_t *variableBufferSize,
cuestWorkspace_t *temporaryWorkspace,
double densityScale,
const double *densityMatrix,
double coefficientScale,
uint64_t numCoefficientMatrices,
const uint64_t *numOccupied,
const double *coefficientMatrices,
double *outGradient
)#

Compute the nuclear gradient of the symmetric DF J/K matrices contracted with a density matrix and multiple coefficient matrices.

This routine evaluates the nuclear derivatives (gradients) of the Coulomb (J) and exchange (K) matrices in density fitting approximation, where the J matrix is contracted with a single density matrix and the K matrices are contracted with multiple occupied orbital coefficient matrices. The result overwrites the output gradient buffer (size: natom × 3).

All required temporary workspace must be sized using the corresponding workspace query function. A variableBufferSize descriptor must also be provided to constrain the memory usage.

Kernel and precision selection. This routine can use JIT-compiled kernels and/or reduced-precision “ffloat” compute, selected through the compute parameters:

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_PARAMETERS_JIT_USAGE_MODE (cuestJITUsageMode_t): CUEST_JIT_USAGE_MODE_ON uses JIT-compiled kernels, CUEST_JIT_USAGE_MODE_OFF uses AOT-compiled kernels. JIT-compiled kernels are only available in the cuEST CUDA 13 package; the default is CUEST_JIT_USAGE_MODE_ON in the cuEST CUDA 13 package and CUEST_JIT_USAGE_MODE_OFF in the cuEST CUDA 12 package. Requesting CUEST_JIT_USAGE_MODE_ON with the cuEST CUDA 12 package returns CUEST_STATUS_INVALID_ARGUMENT.

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_PARAMETERS_FFLOAT_USAGE_MODE (cuestFfloatUsageMode_t) selects the compute precision: CUEST_FFLOAT_USAGE_MODE_ON requests ffloat compute, CUEST_FFLOAT_USAGE_MODE_OFF requests fp64 compute, and CUEST_FFLOAT_USAGE_MODE_DEFAULT requests ffloat compute when it is expected to provide a performance advantage on the present GPU architecture.

  • ffloat compute is only compatible with JIT-compiled kernels. Requesting ffloat compute while JIT is disabled (CUEST_FFLOAT_USAGE_MODE_ON together with CUEST_JIT_USAGE_MODE_OFF) is not supported and returns CUEST_STATUS_INVALID_ARGUMENT.

The bare Coulomb and exchange energies are given as:

\[ E_{J} = \sum_{\mu\nu\lambda\sigma} D_{\mu\nu} (\mu\nu|\lambda\sigma) D_{\lambda\sigma} \]
\[ E_{K}^{N} = \sum_{\mu\nu\lambda\sigma} \sum_{ij} \left[ f_{\rm HF} (\mu\lambda|\frac{1}{r}|\nu\sigma) + f_{\rm LRC} (\mu\lambda|\frac{{\rm erf}(\omega r)}{r}|\nu\sigma) \right] C_{i\mu}^{N} C_{i\nu}^{N} C_{j\lambda}^{N} C_{j\sigma}^{N} \]

An effective J/K energy can be written as:

\[ E_{JK} = s_D * E_{J} + \sum_{N} s_C * E_{K}^{N} \]

where

  • \( s_D \) is a density scaling factor densityScale,

  • \( s_C \) is a coefficient scaling factor coefficientScale,

  • \( f_{\rm HF} \) is the fraction of Hartree-Fock exchange to add, CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION

  • \( f_{\rm LRC} \) is the fraction of long-range range-separated exchange to add, CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION

  • \( \omega \) is the range-separation parameter to use, CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_OMEGA

This function computes: \(dE_{JK}/dR\), where R represents the basis function centers of the electron repulsion integrals.

CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION, CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION, and CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_OMEGA are set when the cuestDFIntPlan_t is constructed and is intended to describe the exchange parameterization in hybrid and range-separated hybrid functionals.

The densityScale and coefficientScale parameters are intended to account for the spin summations needed to obtain the correct two-electron energy.

For example, in a B3LYP RKS computation the intended usage would be:

  • CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION = 0.2

  • CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION = 0.0

  • CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_OMEGA unused

  • densityScale = 2.0

  • coefficientScale = -1.0

  • numCoefficientMatrices = 1

  • \( D_{mn} = \sum_{i} C_{im} C_{in} \)

  • \( I_{ij} = \sum_{mn} C_{im} S_{mn} C_{jn} \)

For a PBE0 UKS computation the intended usage would be:

  • CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION = 0.25

  • CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION = 0.0

  • CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_OMEGA unused

  • densityScale = 0.5

  • coefficientScale = -0.5

  • numCoefficientMatrices = 2

  • \(D_{mn} = \sum_{i} C_{im}^{\alpha} C_{in}^{\alpha} + \sum_{i} C_{im}^{\beta} C_{in}^{\beta} \)

  • \(I_{ij} = \sum_{mn} C_{im}^{\alpha} S_{mn} C_{jn}^{\alpha} \)

  • \(I_{ij} = \sum_{mn} C_{im}^{\beta} S_{mn} C_{jn}^{\beta} \)

For pure functionals, where coefficientScale = 0.0 (CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION and CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION are zero), the coefficient matrices do not need to be provided (if they are, they will not be used). For the pure functional case, the numCoefficientMatrices can be 0. The numOccupied array can be NULL (or contain zeros). The coefficientMatrices array can be NULL.

The following memory usage considerations apply only to cases where the fraction of Hartree-Fock exchange is non-zero.

The memory usage during the gradient evaluation can be changed at a high level by CUEST_DFSYMMETRICDERIVATIVECOMPUTE_PARAMETERS_MEMORY_POLICY.

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_MEMORY_POLICY_DEVICECACHE: Default. This will provide good performance, but may try to allocate a large amount of GPU memory.

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_MEMORY_POLICY_HOSTCACHE: Provides similar performance, but will allocate that memory on the CPU, incurring a bit of overhead transferring memory to/from the CPU.

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_MEMORY_POLICY_OVERWRITE: Preferred, where possible. This memory policy avoids any additional large allocations and/or host/device memory transfers by overwriting some of the temporary data in the cuestDFIntPlan_t. This corrupts the cuestDFIntPlan_t and should be destroyed following this call. If the gradient evaluation is the final function call using the cuestDFIntPlan_t, then this is optimal (this is often the case in usual HF/DFT gradient calculations). If the cuestDFIntPlan_t will be needed again, then this option is not suitable.

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_MEMORY_POLICY_RECOMPUTE: This memory policy does not require any additional allocations or memory transfers. It corrupts the data in the cuestDFIntPlan_t during the gradient calculation. However, following the gradient call, it returns the cuestDFIntPlan_t to a usable state by recomputing (and replacing) any corrupted data. This may add significantly to the cost of the gradient evaluation.

Note that variableBufferSize only applies to the formation of certain intermediates during the cuestDFSymmetricDerivativeCompute and will not limit overall memory usage. We recommend a buffer size of at least 2 GB with modest performance improvements possible if larger buffers can be provided.

Parameters:
  • handle[in] cuEST handle. Must not be NULL.

  • plan[in] DF integral computation plan (opaque handle). Must not be NULL.

  • parameters[in] Compute parameters (cuestDFSymmetricDerivativeComputeParameters_t). Must not be NULL

  • variableBufferSize[in] The variableBufferSize determines the size of an internal scratch buffer used for certain transformations. A buffer of 2GB is a reasonable default value. Host memory is currently unused. Note that the variableBufferSize does not limit total memory usage. The value of the variableBufferSize must not change between WorkspaceQuery and Compute calls.

  • temporaryWorkspace[in] Temporary workspace buffers (preallocated for this operation using the query function). Must not be NULL.

  • densityScale[in] Scaling factor for the J (Coulomb) contribution.

  • densityMatrix[in] Input density matrix (size: nao × nao) on GPU. Must not be NULL.

  • coefficientScale[in] Scaling factor for each K (exchange) contribution.

  • numCoefficientMatrices[in] Number of coefficient matrices. Must be > 0 when exchange is active; may be 0 for pure functionals.

  • numOccupied[in] Array of occupied orbital counts for each coefficient matrix (size: numCoefficientMatrices) on CPU. Each entry must be > 0 when exchange is active; for pure functionals the array may be NULL or contain zeros.

  • coefficientMatrices[in] Concatenated coefficient matrices. Each matrix has shape [numOccupied[i], nao] on GPU. Total size: sum(numOccupied[i]) × nao. Must not be NULL when exchange is active; may be NULL for pure functionals (if provided, it is ignored).

  • outGradient[out] Output nuclear gradient (size: natom × 3) on GPU. Gradient results overwrite this buffer. Must not be NULL.

Returns:

  • CUEST_STATUS_SUCCESS on success;

  • CUEST_STATUS_INVALID_HANDLE if the cuEST handle is NULL;

  • CUEST_STATUS_NULL_POINTER if any required pointer is NULL;

  • CUEST_STATUS_INVALID_TYPE if opaque handles are not the correct type;

  • CUEST_STATUS_INVALID_PLAN if the cuestDFIntPlan_t is not correctly configured or in a dirty state;

  • CUEST_STATUS_INVALID_ARGUMENT if coefficientScale != 0.0 and if numCoefficientMatrices == 0 or any numOccupied[i] == 0; or if CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION or CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION != 0.0 and if numCoefficientMatrices == 0 or any numOccupied[i] == 0;

  • CUEST_STATUS_INVALID_ARGUMENT if a parameter value is invalid, if JIT-compiled kernels are requested with the cuEST CUDA 12 package, or if ffloat compute is requested while JIT is disabled (incompatible JIT/ffloat combination);

  • CUEST_STATUS_EXCEPTION or CUEST_STATUS_UNKNOWN_ERROR otherwise.

cuestStatus_t cuestDFSymmetricDerivativeComputeWorkspaceQuery(
cuestHandle_t handle,
cuestDFIntPlan_t plan,
const cuestDFSymmetricDerivativeComputeParameters_t parameters,
const cuestWorkspaceDescriptor_t *variableBufferSize,
cuestWorkspaceDescriptor_t *temporaryWorkspaceDescriptor,
double densityScale,
const double *densityMatrix,
double coefficientScale,
uint64_t numCoefficientMatrices,
const uint64_t *numOccupied,
const double *coefficientMatrices,
double *outGradient
)#

Query the temporary workspace required for a DF J/K nuclear gradient computation.

This function determines the workspace required for a symmetric DF J/K gradient evaluation with the given plan, density matrix, coefficient matrices, and maximum workspace constraint. The output descriptor is filled on success and can be used to allocate host and device workspace buffers prior to calling cuestDFSymmetricDerivativeCompute.

Some input pointers (densityMatrix, coefficientMatrices, outGradient) are optional and may be NULL.

Kernel and precision selection. This routine can use JIT-compiled kernels and/or reduced-precision “ffloat” compute, selected through the compute parameters:

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_PARAMETERS_JIT_USAGE_MODE (cuestJITUsageMode_t): CUEST_JIT_USAGE_MODE_ON uses JIT-compiled kernels, CUEST_JIT_USAGE_MODE_OFF uses AOT-compiled kernels. JIT-compiled kernels are only available in the cuEST CUDA 13 package; the default is CUEST_JIT_USAGE_MODE_ON in the cuEST CUDA 13 package and CUEST_JIT_USAGE_MODE_OFF in the cuEST CUDA 12 package. Requesting CUEST_JIT_USAGE_MODE_ON with the cuEST CUDA 12 package returns CUEST_STATUS_INVALID_ARGUMENT.

  • CUEST_DFSYMMETRICDERIVATIVECOMPUTE_PARAMETERS_FFLOAT_USAGE_MODE (cuestFfloatUsageMode_t) selects the compute precision: CUEST_FFLOAT_USAGE_MODE_ON requests ffloat compute, CUEST_FFLOAT_USAGE_MODE_OFF requests fp64 compute, and CUEST_FFLOAT_USAGE_MODE_DEFAULT requests ffloat compute when it is expected to provide a performance advantage on the present GPU architecture.

  • ffloat compute is only compatible with JIT-compiled kernels. Requesting ffloat compute while JIT is disabled (CUEST_FFLOAT_USAGE_MODE_ON together with CUEST_JIT_USAGE_MODE_OFF) is not supported and returns CUEST_STATUS_INVALID_ARGUMENT.

Parameters:
  • handle[in] cuEST handle. Must not be NULL.

  • plan[in] DF integral computation plan (opaque handle). Must not be NULL.

  • parameters[in] Compute parameters (cuestDFSymmetricDerivativeComputeParameters_t). Must not be NULL

  • variableBufferSize[in] The variableBufferSize determines the size of an internal scratch buffer used for certain transformations. A buffer of 2GB is a reasonable default value. Host memory is currently unused. Note that the variableBufferSize does not limit total memory usage. The value of the variableBufferSize must not change between WorkspaceQuery and Compute calls.

  • temporaryWorkspaceDescriptor[out] Output descriptor for required temporary workspace sizes (host and device). Must not be NULL.

  • densityScale[in] Scaling factor for the J (Coulomb) contribution.

  • densityMatrix – Optional density matrix. May be NULL.

  • coefficientScale[in] Scaling factor for each K (exchange) contribution.

  • numCoefficientMatrices[in] Number of coefficient matrices. Must be > 0 when exchange is active; may be 0 for pure functionals.

  • numOccupied[in] Array of occupied orbital counts for each coefficient matrix (size: numCoefficientMatrices) on CPU. Each entry must be > 0 when exchange is active; for pure functionals the array may be NULL or contain zeros.

  • coefficientMatrices – Optional concatenated coefficient matrices. May be NULL.

  • outGradient – Optional output gradient buffer. May be NULL.

Returns:

  • CUEST_STATUS_SUCCESS on success;

  • CUEST_STATUS_INVALID_HANDLE if the cuEST handle is NULL;

  • CUEST_STATUS_NULL_POINTER if any required pointer is NULL;

  • CUEST_STATUS_INVALID_TYPE if opaque handles are not the correct type;

  • CUEST_STATUS_INVALID_PLAN if the cuestDFIntPlan_t is not correctly configured or in a dirty state;

  • CUEST_STATUS_INVALID_ARGUMENT if coefficientScale != 0.0 and if numCoefficientMatrices == 0 or any numOccupied[i] == 0; or if CUEST_DFINTPLAN_PARAMETERS_EXCHANGE_FRACTION or CUEST_DFINTPLAN_PARAMETERS_LRC_EXCHANGE_FRACTION != 0.0 and if numCoefficientMatrices == 0 or any numOccupied[i] == 0;

  • CUEST_STATUS_INVALID_ARGUMENT if a parameter value is invalid, if JIT-compiled kernels are requested with the cuEST CUDA 12 package, or if ffloat compute is requested while JIT is disabled (incompatible JIT/ffloat combination);

  • CUEST_STATUS_EXCEPTION or CUEST_STATUS_UNKNOWN_ERROR otherwise.