Variadic CHKERRQ()
What this MR does:
-
Make
CHKERRQ()
and derivatives wrap all function calls chkerrconvert.py- ierr = Foo(...);CHKERRQ(ierr); + CHKERRQ(Foo(...));
-
Remove dangling
PetscErrorCode
declarations processpaths.py -
Wrap both
PetscInitialize()
andPetscFinalize()
:- ierr = PetscInitialize(...);if (ierr) return ierr; + CHKERRQ(PetscInitialize()); - ierr = PetscFinalize(); - return ierr; + CHKERRQ(PetscFinalize()); + return 0;
-
Rename the following findreplace.py:
-
CHKERRQ()
->PetscCall()
-
CHKERRV()
->PetscCallVoid()
-
CHKERRMPI()
->PetscCallMPI()
-
CHKERRABORT()
->PetscCallAbort()
-
CHKERRCONTINUE()
->PetscCallContinue()
-
CHKERRXX()
->PetscCallThrow()
-
CHKERRCXX()
->PetscCallCXX()
-
CHKERRCUDA()
->PetscCallCUDA()
-
CHKERRCUBLAS()
->PetscCallCUBLAS()
-
CHKERRCUSPARSE()
->PetscCallCUSPARSE()
-
CHKERRCUSOLVER()
->PetscCallCUSOLVER()
-
CHKERRCUFFT()
->PetscCallCUFFT()
-
CHKERRCURAND()
->PetscCallCURAND()
-
CHKERRHIP()
->PetscCallHIP()
-
CHKERRHIPBLAS()
->PetscCallHIPBLAS()
-
CHKERRHIPSOLVER()
->PetscCallHIPSOLVER()
-
CHKERRQ_CEED()
->PetscCallCEED()
-
CHKERR_FORTRAN_VOID_FUNCTION()
->PetscCallFortranVoidFunction()
-
-
PETSc error handling now "works" whether or not
PetscInitialize()
has been called (PetscError()
now checksPetscErrorHandlingInitialized
) -
Roughly 1500
PetscCheckFalse()
->PetscCheck()
conversions -
Fix the clang linters'
PetscValidXXXPointer()
recommendation system (cc @joseroman). Previously it would only check the arguments index into the parent-functions argument was correct. It now also recommends more specificPetscValidXXXPointer()
if applicable:
ERROR 18: /Users/jacobfaibussowitsch/soft/petsc/src/sys/tests/linter/testValidPointers.c:31:21
'b' of derived type 'char *', canonical type 'char'
29: /* incorrect */
30: PetscValidCharPointer(a,2);
> 31: PetscValidPointer(b,3);
^
32: PetscValidPointer(c,4);
33: PetscValidPointer(d,5);
Incorrect use of PetscValidPointer(), use PetscValidCharPointer() instead
Misc:
Elisp helper to wrap a line or region with CHKERRQ()
(defun jf--insert-chkerr-func (begin end &optional chkerr_func)
"Wrap a region in CHKERR_FUNC()"
;; make sure we are at the start of region
(goto-char begin)
(unless chkerr_func
;; if chkerr_func isn't set, try and determine which one we want
(setq chkerr_func
(pcase (buffer-substring-no-properties begin end)
((rx bos "MPI" ) "PetscCallMPI" )
((rx bos "cuda" ) "PetscCallCUDA" )
((rx bos "cublas" ) "PetscCallCUBLAS" )
((rx bos "cusolver" ) "PetscCallCUSOLVER" )
((rx bos "hipblas" ) "PetscCallHIPBLAS" )
((rx bos "hipsolver" ) "PetscCallHIPSOLVER" )
((rx bos "hip" ) "PetscCallHIP" )
((rx bos "cupmblas" ) "PetscCallCUPMBLAS" )
((rx bos "cupmsolver") "PetscCallCUPMSOLVER")
((rx bos "cupm" ) "PetscCallCUPM" )
;; default
(_ "PetscCall" ))))
(unless (string-equal (thing-at-point 'symbol) chkerr_func)
(insert-before-markers chkerr_func ?\()
(goto-char (+ end 1 (length chkerr_func)))
(insert-char ?\))
(unless (char-equal (following-char) ?\;)
(insert-char ?\;))))
(defun jf/insert-chkerr-func (&optional chkerr_func)
"Intelligently wrap current line in CHKERR_FUNC()"
(interactive)
(save-excursion
(let ((using-region (use-region-p)))
(unless using-region
;; go to start of indented line
(back-to-indentation)
(let ((eol (line-end-position)))
;; skip any chars that:
;; ^ - NOT
;; w - word constituent (including numbers)
;; _ - symbol constituent
(skip-syntax-forward "^w_" eol)
;; special handling of keywords
(while (looking-at-p "\\(for\\|while\\|switch\\|do\\|if\\|else\\|case\\)\s+")
;; special handling here, forward-list would skip to EOL for these
(if (looking-at-p "\\(do\\|else\\|case\\)\s+")
(forward-word)
(forward-list))
(skip-syntax-forward "^w_" eol)))
;; set start of region
(push-mark nil t t)
;; skip to end of symbol
(forward-list))
(with-demoted-errors "ERROR wrapping line in CHKERR_FUNC: %s"
(jf--insert-chkerr-func (region-beginning) (region-end) chkerr_func))
(unless using-region (pop-mark)))
(indent-according-to-mode)))
;; bind it
(global-set-key (kbd "C-c c") 'jf/insert-chkerr-func)
;; for those living in the 21st century
(bind-key "C-c c" 'jf/insert-chkerr-func)
With the point anywhere on a given line it will "do the right" thing for
Foo(asdasdasdasd)
// becomes
PetscCall(Foo(asdasdasdasd));
Foo(asdasdasdasd); // note semi-colon
// becomes
PetscCall(Foo(asdasdasdasd));
PetscCall(Foo(asdasdasdasd));
// becomes
PetscCall(Foo(asdasdasdasd)); // note no change
if (asdasdasd) { for (asdasdasd;ada;sda) { while (xasdads) { Foo(asdasdad); } }}
// becomes
if (asdasdasd) { for (asdasdasd;ada;sda) { while (xasdads) { PetscCall(Foo(asdasdad)); } } }
} else {Foo(asdasdasd);}
// becomes
} else {PetscCall(Foo(asdasdasd));}
// if some insertion fails, then it will do the insertion on a region (shown with "[]") too
F[ooBarBaz(asdas]dasd)
// becomes
FPetscCall(ooBarBaz(asdas);dasd)
// it auto-detect which PetscCall() to insert:
MPI_Comm_size(..);
// becomes
PetscCallMPI(MPI_Comm_size(...));
// and so on...