> On Dec 17, 2025, at 12:50 PM, David Knezevic via petsc-users > <[email protected]> wrote: > > Hi all, > > I have a question about this error: >> Vector 'Vec_0x84000005_0' (argument #2) was locked for read-only access in >> unknown_function() at unknown file:0 (line numbers only accurate to function >> begin) > > I'm encountering this error in an FE solve where there is an error > encountered during the residual/jacobian assembly, and what we normally do in > that situation is shrink the load step and continue, starting from the "last > converged solution". However, in this case I'm running on 32 processes, and 5 > of the processes report the error above about a "locked vector".
It is very surprising that the vector is only locked on a subset of processes; this not normally expected behavior and likely indicates memory corruption or a logic error in the code. So the first thing to do is determine where the locking took place. You can build another instance of the PETSc libraries with debugging turned on by setting PETSC_ARCH to a new value and using the same ./configure options you used before but with --with-debugging=1 (instead of --with-debugging=0). If you are using a prebuilt PETSc from a package manager I don't know if there is an easy way to get a version with debugging turned on; I would hope so but some package managers may not provide it, in that case you need to build PETSc yourself from source.) Then run your code again and it should give detailed information (a stack trace) about where the locking took place. Why does PETSc lock vectors? During a nonlinear solver, for example, the solver algorithm will request your function to be evaluated using the function you pass to SNESSetFunction(). To ensure user code does not corrupt the solution process the input vector (often called u in the documentation and code) is locked. It is locked because if the user code changes the values of the input vector it will "break" the iterative solver code (that is incorrect answers could be produced) During a standard Newton solver the user never needs to "adjust" the Newton proposed solutions, that is all handled by the PETSc solver code (and line search etc). But for some difficult problems, the user may want to have custom code that "messes around" directly with the proposed Newton steps. SNES provides "hooks" where the user can provide such custom code (the "messing around" should never take place with the SNESSetFunction() callback, only within the "hooks"). For SNES Newton's method with line search (the default) one can provide hook functions using `SNESLineSearchSetPostCheck()`, `SNESLineSearchSetPreCheck()`, where the linesearch object is obtained with SNESGetLineSearch(). The Newton trust region methods have their own set of hooks. Based on your mention of "shrink the load step" I am speculating that for your code standard Newton's method may not converge so you are adding additional code to help get Newton to converge and this is triggering the error you are seeing. But it is possible my guess is incorrect and their is some other cause for the error; in either case running with the debug version will help indicate where the locking issues is occurring. Barry > > We clear the SNES object (via SNESDestroy) before we reset the solution to > the "last converged solution", and then we make a new SNES object > subsequently. But it seems to me that somehow the solution vector is still > marked as "locked" on 5 of the processes when we modify the solution vector, > which leads to the error above. > > I was wondering if someone could advise on what the best way to handle this > would be? I thought one option could be to add an MPI barrier call prior to > updating the solution vector to "last converged solution", to make sure that > the SNES object is destroyed on all procs (and hence the locks cleared) > before editing the solution vector, but I'm unsure if that would make a > difference. Any help would be most appreciated! > > Thanks, > David
