Actual source code: lmvm.h

      1: #pragma once
      2: #include <petscksp.h>
      3: #include <petsc/private/matimpl.h>
      4: #include <petsc/private/vecimpl.h>
      5: #include "lmbasis.h"
      6: #include "lmproducts.h"

      8: PETSC_INTERN PetscLogEvent MATLMVM_Update;

     10: /*
     11:   MATLMVM format - a base matrix-type that represents Limited-Memory
     12:   Variable Metric (LMVM) approximations of a Jacobian.

     14:   LMVM approximations can be symmetric, symmetric positive-definite,
     15:   rectangular, or otherwise square with no determinable properties.
     16:   Each derived LMVM type should automatically set its matrix properties
     17:   if its construction can guarantee symmetry (MAT_SYMMETRIC) or symmetric
     18:   positive-definiteness (MAT_SPD).
     19: */

     21: /* MatLMVMReset(Mat, PetscBool) has a simple boolean for destructive/nondestructive reset,
     22:    but internally it is helpful to have more control
     23:  */
     24: enum {
     25:   MAT_LMVM_RESET_HISTORY = 0x0,
     26:   MAT_LMVM_RESET_BASES   = 0x1,
     27:   MAT_LMVM_RESET_J0      = 0x2,
     28:   MAT_LMVM_RESET_VECS    = 0x4,
     29:   MAT_LMVM_RESET_ALL     = 0xf,
     30: };

     32: typedef PetscInt MatLMVMResetMode;

     34: #define MatLMVMResetClearsBases(mode) ((mode) & MAT_LMVM_RESET_BASES)
     35: #define MatLMVMResetClearsJ0(mode)    ((mode) & MAT_LMVM_RESET_J0)
     36: #define MatLMVMResetClearsVecs(mode)  ((mode) & MAT_LMVM_RESET_VECS)
     37: #define MatLMVMResetClearsAll(mode)   ((mode) == MAT_LMVM_RESET_ALL)

     39: typedef struct _MatOps_LMVM *MatOps_LMVM;
     40: struct _MatOps_LMVM {
     41:   PetscErrorCode (*update)(Mat, Vec, Vec);
     42:   PetscErrorCode (*reset)(Mat, MatLMVMResetMode);
     43:   PetscErrorCode (*mult)(Mat, Vec, Vec);
     44:   PetscErrorCode (*multht)(Mat, Vec, Vec);
     45:   PetscErrorCode (*solve)(Mat, Vec, Vec);
     46:   PetscErrorCode (*solveht)(Mat, Vec, Vec);
     47:   PetscErrorCode (*copy)(Mat, Mat, MatStructure);
     48:   PetscErrorCode (*setmultalgorithm)(Mat);
     49: };

     51: /* Identifies vector bases used internally.

     53:    - bases are listed in "dual pairs": e.g. if an algorithm for MatMult() uses basis X somewhere, then the dual
     54:      algorithm for MatSolve will use the dual basis X' in the same place

     56:    - bases are stored in the `basis[]` array in Mat_LMVM, rather than as struct members with names, to enable "modal"
     57:      access: code of the form `basis[LMVMModeMap(LMBASIS_S, mode)]` can be used for
     58:      the primal algorithm (`mode == MATLMVM_MODE_PRIMAL`) and the dual algorithm (`mode == MATLMMV_MODE_DUAL`).
     59:  */
     60: enum {
     61:   LMBASIS_S           = 0, // differences between solutions, S_i = (X_{i+1} - X_i)
     62:   LMBASIS_Y           = 1, // differences in function values, Y_i = (F_{i+1} - F_i)
     63:   LMBASIS_H0Y         = 2, // H_0 = J_0^{-1}
     64:   LMBASIS_B0S         = 3, // B_0 is the symbol used instead of J_0 in many textbooks and papers, we use it internally
     65:   LMBASIS_S_MINUS_H0Y = 4,
     66:   LMBASIS_Y_MINUS_B0S = 5,
     67:   LMBASIS_END
     68: };

     70: typedef PetscInt MatLMVMBasisType;

     72: typedef enum {
     73:   MATLMVM_MODE_PRIMAL = 0,
     74:   MATLMVM_MODE_DUAL   = 1,
     75: } MatLMVMMode;

     77: #define LMVMModeMap(a, mode)                       ((a) ^ (PetscInt)(mode))
     78: #define MatLMVMApplyJ0Mode(mode)                   ((mode) == MATLMVM_MODE_PRIMAL ? MatLMVMApplyJ0Fwd : MatLMVMApplyJ0Inv)
     79: #define MatLMVMApplyJ0HermitianTransposeMode(mode) ((mode) == MATLMVM_MODE_PRIMAL ? MatLMVMApplyJ0HermitianTranspose : MatLMVMApplyJ0InvHermitianTranspose)
     80: #define MatLMVMBasisSizeOf(type)                   ((type) & LMBASIS_Y)

     82: typedef struct {
     83:   /* Core data structures for stored updates */
     84:   struct _MatOps_LMVM ops[1];
     85:   PetscBool           prev_set;
     86:   PetscInt            m, k, nupdates, nrejects, nresets;
     87:   LMBasis             basis[LMBASIS_END];
     88:   LMProducts          products[LMBLOCK_END][LMBASIS_END][LMBASIS_END];
     89:   Vec                 Xprev, Fprev;

     91:   /* User-defined initial Jacobian tools */
     92:   PetscScalar shift;
     93:   Mat         J0;
     94:   KSP         J0ksp;
     95:   PetscBool   disable_ksp_viewers;
     96:   PetscBool   created_J0;
     97:   PetscBool   created_J0ksp;
     98:   PetscBool   do_not_cache_J0_products;
     99:   PetscBool   cache_gradient_products;

    101:   /* Miscellenous parameters */
    102:   PetscReal            eps; /* (default: PetscPowReal(PETSC_MACHINE_EPSILON, 2.0/3.0)) */
    103:   MatLMVMMultAlgorithm mult_alg;
    104:   void                *ctx; /* implementation specific context */
    105:   PetscBool            debug;
    106: } Mat_LMVM;

    108: /* Shared internal functions for LMVM matrices */
    109: PETSC_INTERN PetscErrorCode MatUpdateKernel_LMVM(Mat, Vec, Vec);
    110: PETSC_INTERN PetscErrorCode MatUpdate_LMVM(Mat, Vec, Vec);
    111: PETSC_INTERN PetscErrorCode MatAllocate_LMVM(Mat, Vec, Vec);
    112: PETSC_INTERN PetscErrorCode MatLMVMAllocateBases(Mat);
    113: PETSC_INTERN PetscErrorCode MatLMVMAllocateVecs(Mat);
    114: PETSC_INTERN PetscErrorCode MatLMVMReset_Internal(Mat, MatLMVMResetMode);
    115: PETSC_INTERN PetscErrorCode MatReset_LMVM(Mat, MatLMVMResetMode);

    117: /* LMVM implementations of core Mat functionality */
    118: PETSC_INTERN PetscErrorCode MatSetFromOptions_LMVM(Mat, PetscOptionItems PetscOptionsObject);
    119: PETSC_INTERN PetscErrorCode MatSetUp_LMVM(Mat);
    120: PETSC_INTERN PetscErrorCode MatView_LMVM(Mat, PetscViewer);
    121: PETSC_INTERN PetscErrorCode MatDestroy_LMVM(Mat);
    122: PETSC_INTERN PetscErrorCode MatCreate_LMVM(Mat);

    124: /* Create functions for derived LMVM types */
    125: PETSC_EXTERN PetscErrorCode MatCreate_LMVMDFP(Mat);
    126: PETSC_EXTERN PetscErrorCode MatCreate_LMVMDDFP(Mat);
    127: PETSC_EXTERN PetscErrorCode MatCreate_LMVMBFGS(Mat);
    128: PETSC_EXTERN PetscErrorCode MatCreate_LMVMDBFGS(Mat);
    129: PETSC_EXTERN PetscErrorCode MatCreate_LMVMDQN(Mat);
    130: PETSC_EXTERN PetscErrorCode MatCreate_LMVMSR1(Mat);
    131: PETSC_EXTERN PetscErrorCode MatCreate_LMVMBrdn(Mat);
    132: PETSC_EXTERN PetscErrorCode MatCreate_LMVMBadBrdn(Mat);
    133: PETSC_EXTERN PetscErrorCode MatCreate_LMVMSymBrdn(Mat);
    134: PETSC_EXTERN PetscErrorCode MatCreate_LMVMSymBadBrdn(Mat);
    135: PETSC_EXTERN PetscErrorCode MatCreate_LMVMDiagBrdn(Mat);

    137: PETSC_INTERN PetscErrorCode MatLMVMGetJ0InvDiag(Mat, Vec *);
    138: PETSC_INTERN PetscErrorCode MatLMVMRestoreJ0InvDiag(Mat, Vec *);

    140: PETSC_INTERN PetscErrorCode MatLMVMGetRange(Mat, PetscInt *, PetscInt *);

    142: PETSC_INTERN PetscErrorCode MatLMVMApplyJ0HermitianTranspose(Mat, Vec, Vec);
    143: PETSC_INTERN PetscErrorCode MatLMVMApplyJ0InvHermitianTranspose(Mat, Vec, Vec);

    145: PETSC_INTERN PetscErrorCode MatLMVMGetJ0Scalar(Mat, PetscBool *, PetscScalar *);
    146: PETSC_INTERN PetscErrorCode MatLMVMJ0KSPIsExact(Mat, PetscBool *);

    148: PETSC_INTERN PetscErrorCode MatLMVMUseVecLayoutsIfCompatible(Mat, Vec, Vec);

    150: PETSC_INTERN PetscErrorCode MatLMVMGetUpdatedBasis(Mat, MatLMVMBasisType, LMBasis *, MatLMVMBasisType *, PetscScalar *);
    151: PETSC_INTERN PetscErrorCode MatLMVMGetWorkRow(Mat, Vec *);
    152: PETSC_INTERN PetscErrorCode MatLMVMRestoreWorkRow(Mat, Vec *);
    153: PETSC_INTERN PetscErrorCode MatLMVMBasisGetVecRead(Mat, MatLMVMBasisType, PetscInt, Vec *, PetscScalar *);
    154: PETSC_INTERN PetscErrorCode MatLMVMBasisRestoreVecRead(Mat, MatLMVMBasisType, PetscInt, Vec *, PetscScalar *);
    155: PETSC_INTERN PetscErrorCode MatLMVMBasisGEMVH(Mat, MatLMVMBasisType, PetscInt, PetscInt, PetscScalar, Vec, PetscScalar, Vec);
    156: PETSC_INTERN PetscErrorCode MatLMVMBasisGEMV(Mat, MatLMVMBasisType, PetscInt, PetscInt, PetscScalar, Vec, PetscScalar, Vec);

    158: PETSC_INTERN PetscErrorCode MatLMVMCreateProducts(Mat, LMBlockType, LMProducts *);
    159: PETSC_INTERN PetscErrorCode MatLMVMGetUpdatedProducts(Mat, MatLMVMBasisType, MatLMVMBasisType, LMBlockType, LMProducts *);
    160: PETSC_INTERN PetscErrorCode MatLMVMProductsInsertDiagonalValue(Mat, MatLMVMBasisType, MatLMVMBasisType, PetscInt, PetscScalar);
    161: PETSC_INTERN PetscErrorCode MatLMVMProductsGetDiagonalValue(Mat, MatLMVMBasisType, MatLMVMBasisType, PetscInt, PetscScalar *);

    163: PETSC_INTERN PetscBool  ByrdNocedalSchnabelCite;
    164: PETSC_INTERN const char ByrdNocedalSchnabelCitation[];