diff --git a/config/BuildSystem/config/compilerFlags.py b/config/BuildSystem/config/compilerFlags.py index b8aced4187b..776328b9c2a 100644 --- a/config/BuildSystem/config/compilerFlags.py +++ b/config/BuildSystem/config/compilerFlags.py @@ -155,8 +155,10 @@ def outputCompilerMacros(self): if out.find('__AVX2__') > -1 and out.find('__FMA__') > -1: self.text = self.text + 'Intel instruction sets utilizable by compiler:\n' self.text = self.text + ' AVX2\n' - if out.find('__AVX512__') > -1: - self.text = self.text + ' AVX512\n' + if out.find('__AVX512') > -1: + self.text = self.text + ' AVX512: ' + self.text = self.text + ' '.join([i for i in out.split('__') if i.startswith('AVX512')]) + self.text = self.text + '\n' except: pass for filename in [self.compilerDefines, self.compilerFixes, self.compilerSource, self.compilerObj]: @@ -176,15 +178,14 @@ def checkIntelHardwareSupport(self): try: (out, err, ret) = Configure.executeShellCommand('lscpu', log = self.log) except: - try: - (out, err, ret) = Configure.executeShellCommand('sysctl -a', log = self.log) - if out.find('hw.optional.avx2_0: 1') > -1 and out.find('hw.optional.fma: 1') > -1: - self.text = self.text + 'Intel instruction sets found on CPU:\n' - self.text = self.text + ' AVX2\n' - if out.find('hw.optional.avx512f: 1') > -1: - self.text = self.text + ' AVX512\n' - except: - pass + out = '' + if out.find(' avx2 ') > -1 and out.find(' fma ') > -1: + self.text = self.text + 'Intel instruction sets found on CPU:\n' + self.text = self.text + ' AVX2\n' + if out.find(' avx512') > -1: + self.text = self.text + ' AVX512: ' + self.text = self.text + ' '.join([i for i in out.split(' ') if i.startswith('avx512')]) + self.text = self.text + '\n' return def configure(self): diff --git a/config/BuildSystem/config/compilerOptions.py b/config/BuildSystem/config/compilerOptions.py index d8bc088a3c8..8d717901b5c 100644 --- a/config/BuildSystem/config/compilerOptions.py +++ b/config/BuildSystem/config/compilerOptions.py @@ -12,7 +12,7 @@ def getCFlags(self, compiler, bopt, language): import config.setCompilers if language == 'C': - if [s for s in ['mpicc','mpiicc'] if os.path.basename(compiler).find(s)>=0]: + if [s for s in ['mpicc','mpiicc','mpiicx'] if os.path.basename(compiler).find(s)>=0]: try: output = self.executeShellCommand(compiler + ' -show', log = self.log)[0] self.framework.addMakeMacro('MPICC_SHOW',output.strip().replace('\n','\\\\n').replace('"','\\"')) @@ -126,7 +126,7 @@ def getCFlags(self, compiler, bopt, language): def getCxxFlags(self, compiler, bopt, language): import config.setCompilers - if [s for s in ['mpiCC','mpic++','mpicxx','mpiicxx','mpiicpc'] if os.path.basename(compiler).find(s)>=0]: + if [s for s in ['mpiCC','mpic++','mpicxx','mpiicxx','mpiicpc','mpiicpx'] if os.path.basename(compiler).find(s)>=0]: try: output = self.executeShellCommand(compiler+' -show', log = self.log)[0] self.framework.addMakeMacro('MPICXX_SHOW',output.strip().replace('\n','\\\\n')) @@ -240,8 +240,7 @@ def getCxxFlags(self, compiler, bopt, language): return flags def getFortranFlags(self, compiler, bopt): - - if [s for s in ['mpif77','mpif90','mpifort','mpiifort'] if os.path.basename(compiler).find(s)>=0]: + if [s for s in ['mpif77','mpif90','mpifort','mpiifort','mpiifx'] if os.path.basename(compiler).find(s)>=0]: try: output = self.executeShellCommand(compiler+' -show', log = self.log)[0] self.framework.addMakeMacro('MPIFC_SHOW',output.strip().replace('\n','\\\\n')) diff --git a/config/BuildSystem/config/packages/hpddm.py b/config/BuildSystem/config/packages/hpddm.py index a8cf3cc2aeb..5e6ff1d1787 100644 --- a/config/BuildSystem/config/packages/hpddm.py +++ b/config/BuildSystem/config/packages/hpddm.py @@ -4,7 +4,7 @@ class Configure(config.package.Package): def __init__(self,framework): config.package.Package.__init__(self,framework) self.version = '2.3.1' - self.gitcommit = 'v'+self.version # main sep-25-2024 + self.gitcommit = '1813156fce13718da3ced5aeb2ebbb736a2227bd' # main oct-26-2024 self.download = ['git://https://github.com/hpddm/hpddm','https://github.com/hpddm/hpddm/archive/'+self.gitcommit+'.tar.gz'] self.minversion = '2.2.1' self.versionname = 'HPDDM_VERSION' diff --git a/config/BuildSystem/config/packages/parmmg.py b/config/BuildSystem/config/packages/parmmg.py index aad6c8328e5..12583ee2744 100644 --- a/config/BuildSystem/config/packages/parmmg.py +++ b/config/BuildSystem/config/packages/parmmg.py @@ -11,6 +11,7 @@ def __init__(self, framework): self.liblist = [['libparmmg.a']] self.functions = ['PMMG_Free_all_var'] self.precisions = ['double'] + self.requires32bitint = 1 return def setupDependencies(self, framework): diff --git a/config/BuildSystem/config/packages/petsc4py.py b/config/BuildSystem/config/packages/petsc4py.py index 8831db1e5b5..5df2c8ddd42 100644 --- a/config/BuildSystem/config/packages/petsc4py.py +++ b/config/BuildSystem/config/packages/petsc4py.py @@ -123,7 +123,9 @@ def Install(self): def configureLibrary(self): import sys if not self.sharedLibraries.useShared and not self.setCompilers.isCygwin(self.log): - raise RuntimeError('petsc4py requires PETSc be built with shared libraries; rerun with --with-shared-libraries') + raise RuntimeError('petsc4py requires PETSc be built with shared libraries; rerun with --with-shared-libraries') + if sys.version_info < (3, 7): + raise RuntimeError('petsc4py requires Python 3.7 at least') chkpkgs = ['numpy'] if sys.version_info >= (3, 12): chkpkgs.append('setuptools') @@ -131,7 +133,7 @@ def configureLibrary(self): for pkg in chkpkgs: if not getattr(self.python,pkg): npkgs.append(pkg) if npkgs: - raise RuntimeError('PETSc4py requires Python with "%s" module(s) installed!\n' + raise RuntimeError('petsc4py requires Python with "%s" module(s) installed!\n' 'Please install using package managers - for ex: "apt" or "dnf" (on linux),\n' 'or with "pip" using: %s -m pip install %s' % (" ".join(npkgs), self.python.pyexe, " ".join(npkgs))) self.getInstallDir() diff --git a/config/BuildSystem/config/setCompilers.py b/config/BuildSystem/config/setCompilers.py index 86a7a29ade8..5d2fbe98f63 100644 --- a/config/BuildSystem/config/setCompilers.py +++ b/config/BuildSystem/config/setCompilers.py @@ -1491,7 +1491,7 @@ def checkCCompiler(self): return def generateCPreprocessorGuesses(self): - '''Determines the C preprocessor from CPP, then --with-cpp, then the C compiler''' + '''Determines the C preprocessor from --with-cpp, then CPP, then the C compiler''' if 'with-cpp' in self.argDB: yield self.argDB['with-cpp'] elif 'CPP' in self.argDB: diff --git a/config/install.py b/config/install.py index c5fa62c459e..e438f8fcd81 100755 --- a/config/install.py +++ b/config/install.py @@ -508,12 +508,13 @@ def copyLib(self, src, dst): return shutil.copy2(src, dst) if self.setCompilers.getCompiler().find('win32fe') < 0 and os.path.splitext(dst)[1] == '.'+self.arLibSuffix: - self.executeShellCommand(self.ranlib+' '+dst) - if os.path.splitext(dst)[1] == '.dylib' and os.path.isfile('/usr/bin/install_name_tool'): - [output,err,flg] = self.executeShellCommand("otool -D "+src) + import shlex + self.executeShellCommand(shlex.split(self.ranlib) + [dst]) + if os.path.splitext(dst)[1] == '.dylib' and shutil.which('otool') and shutil.which('install_name_tool'): + [output,err,flg] = self.executeShellCommand(['otool', '-D', src]) oldname = output[output.find("\n")+1:] installName = oldname.replace(os.path.realpath(self.archDir), self.installDir) - self.executeShellCommand('/usr/bin/install_name_tool -id ' + installName + ' ' + dst) + self.executeShellCommand(['install_name_tool', '-id', installName, dst]) # preserve the original timestamps - so that the .a vs .so time order is preserved shutil.copystat(src,dst) return diff --git a/doc/community/index.rst b/doc/community/index.rst index 9e1b4b57b54..3c17a4acab4 100644 --- a/doc/community/index.rst +++ b/doc/community/index.rst @@ -4,6 +4,8 @@ Community ********* +`Follow PETSc on BlueSky `__. + PETSc is associated with `NumFOCUS `__, a 501(c)(3) nonprofit supporting open code and reproducible science, through which you can help support PETSc. .. image:: /images/community/numfocus.png diff --git a/doc/community/meetings/2024/index.rst b/doc/community/meetings/2024/index.rst index 6ca0cc4bbf2..1439b413e39 100644 --- a/doc/community/meetings/2024/index.rst +++ b/doc/community/meetings/2024/index.rst @@ -15,21 +15,23 @@ Cologne, Germany; May 23-24, 2024 :alt: PETSc User Meeting 2024 group photo Scientific committee: + - Dr. Pierre Jolivet Sorbonne Université, CNRS -- Prof. Dr. Axel Klawonn University of Cologne +- Prof. Dr. Axel Klawonn University of Cologne -- Prof. Dr. Matthew Knepley University at Buffalo +- Prof. Dr. Matthew Knepley University at Buffalo - Dr. Martin Lanser University of Cologne -- Prof. Dr. Oliver Rheinbach TU Bergakademie Freiberg +- Prof. Dr. Oliver Rheinbach TU Bergakademie Freiberg - Dr. Janine Weber University of Cologne - Dr. Stefano Zampini King Abdullah University of Science and Technology Local Organizing Committee + - Prof. Dr. Axel Klawonn - Dr. Jascha Knepper diff --git a/doc/community/meetings/2025/index.rst b/doc/community/meetings/2025/index.rst new file mode 100644 index 00000000000..e44cfb92da1 --- /dev/null +++ b/doc/community/meetings/2025/index.rst @@ -0,0 +1,44 @@ +:orphan: + +.. _2025_meeting: + + +2025 PETSc Annual Users Meeting and Tutorial +******************************************** + +May 20-21, 2025, University of Buffalo, New York, USA + + +Meeting times +------------- +* Monday, May 19 - Tutorial +* Tuesday, May 20 - Meeting +* Wednesday, May 21 - Meeting + + +Registration +------------ +Please `register `__ to save your seat. +Fee: $100, for breaks and lunches; free for students. + +Submit a presentation +--------------------- +`Submit an abstract `__ to be included in the schedule. +We welcome talks from all perspectives, including + +* contributions to PETSc +* use of PETSc in applications or libraries +* development of libraries and packages `called from PETSc `__ +* just curious about using PETSc in applications + +Student Travel Support +---------------------- + +We have funding to provide travel support for students attending the meeting without their own funding. To apply, check the +"Student Funding Support" ticket while registering for the meeting. Early registration will increase your chance of obtaining travel support. + +Questions and Meeting Discussion +-------------------------------- + +For questions about the meeting contact petsc2025@lists.mcs.anl.gov. +Join the discussion about the meeting on the `2025 PETSc Annual Users Meeting Discord channel `__, diff --git a/doc/community/meetings/meeting.rst b/doc/community/meetings/meeting.rst index 37d1968a504..bb50b918e64 100644 --- a/doc/community/meetings/meeting.rst +++ b/doc/community/meetings/meeting.rst @@ -28,8 +28,8 @@ simulations by scientists and engineers. Upcoming Meetings ================= -- The PETSc Annual User Meeting (PAUM) 2025 will take place in Buffalo, New York, USA on May 19-21, 2025. - - `Submit a presentation or poster `__ +- The :any:`2025 PETSc annual user meeting<2025_meeting>` will take place May 20-21, 2025 in Buffalo, New York, USA, with + tutorials on May 19th. Previous Meetings ================= diff --git a/doc/index.rst b/doc/index.rst index ba7099eb976..48c3a949a1e 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -12,6 +12,14 @@ Immediately jump in and run PETSc code :any:`handson`. PETSc is developed as :ref:`open-source `, :any:`requests ` and :any:`contributions ` are welcome. +.. admonition:: News: + + PETSc is now on `BlueSky `__. + +.. admonition:: News: + + The :any:`2025 PETSc Annual User Meeting<2025_meeting>` will take place May 20-21, 2025 in Buffalo, New York, USA, with tutorials on May 19th. + .. admonition:: News: Mrs Hong Zhang, who has been a PETSc developer for twenty-five years and mentored many students and future PETSc developers, has retired. .. image:: /images/community/HongZhangDinner.jpg diff --git a/doc/install/download.rst b/doc/install/download.rst index ae599d39087..2dd6c8c920e 100644 --- a/doc/install/download.rst +++ b/doc/install/download.rst @@ -31,16 +31,16 @@ Alternative: Obtain Release Version with Tarball Tarball which contains only the source. Documentation available `online `__. -- `petsc-3.22.1.tar.gz `__ +- `petsc-3.22.2.tar.gz `__ Tarball which includes all documentation, recommended for offline use. -- `petsc-with-docs-3.22.1.tar.gz `__ +- `petsc-with-docs-3.22.2.tar.gz `__ Tarball to enable a separate installation of petsc4py. -- `petsc4py-3.22.1.tar.gz `__ +- `petsc4py-3.22.2.tar.gz `__ To extract the sources use: @@ -117,6 +117,9 @@ PETSc does not follow **Semantic Versioning**, :cite:`semver-webpage`, rather i - MINOR version, with new functionality and likely small API changes; most changes are backward compatible with deprecation. On a 6 month cycle. - PATCH version, with bug fixes - and minor functionality updates preserving the current API. On a monthly cycle. +PETSc provides tools to allow you to stipulate what versions of PETSc it works with at configure time, compile time, or runtime of your package, see +:any:`ch_versionchecking`. + .. rubric:: References .. bibliography:: /petsc.bib diff --git a/doc/install/install.rst b/doc/install/install.rst index 63f326c3ed8..6d24090e51b 100644 --- a/doc/install/install.rst +++ b/doc/install/install.rst @@ -682,8 +682,8 @@ Note that using OpenMP within MPI code must be done carefully to prevent too man An NVIDIA GPU is **required** to use `CUDA`_-accelerated code. Check that your machine has a `CUDA`_ enabled GPU by consulting https://developer.nvidia.com/cuda-gpus. -On Linux - make sure you have compatible `NVIDIA driver -`__ installed. +On Linux - verify [#]_ that CUDA compatible `NVIDIA driver +`__ is installed. On Microsoft Windows - Use either `Cygwin`_ or `WSL`_ the latter of which is entirely untested right now. If you have experience with `WSL`_ and/or have successfully built PETSc on Microsoft Windows @@ -695,7 +695,7 @@ In most cases you need only pass the configure option ``--with-cuda``; check CUDA build of PETSc currently works on Mac OS X, Linux, Microsoft Windows with `Cygwin`_. -Examples that use CUDA have the suffix .cu; see ``$PETSC_DIR/src/snes/tutorials/ex47.cu`` +Examples that use CUDA have the suffix .cu; see ``$PETSC_DIR/src/snes/tutorials/ex47cu.cu`` .. _doc_config_accel_kokkos: @@ -790,3 +790,4 @@ systems. Also note the configuration examples in ``config/examples``. .. [#] The two packages provide slightly different (though largely overlapping) functionality which can only be fully used if both packages are installed. .. [#] Apple provides customized ``clang`` and ``clang++`` for its system. To use the unmodified LLVM project ``clang`` and ``clang++`` install them with brew. +.. [#] To verify CUDA compatible Nvidia driver on Linux - run the utility ``nvidia-smi`` - it should provide the version of the Nvidia driver currently installed, and the maximum CUDA version it supports. diff --git a/doc/manual/additional.rst b/doc/manual/additional.rst index 9638d86c44d..159ad6f92cf 100644 --- a/doc/manual/additional.rst +++ b/doc/manual/additional.rst @@ -7,6 +7,7 @@ Additional Information :maxdepth: 2 fortran + versionchecking matlab profiling performance diff --git a/doc/manual/versionchecking.rst b/doc/manual/versionchecking.rst new file mode 100644 index 00000000000..e2ba12d1f88 --- /dev/null +++ b/doc/manual/versionchecking.rst @@ -0,0 +1,72 @@ +.. _ch_versionchecking: + +Checking the PETSc version +-------------------------- +The PETSc version +is defined in ``$PETSC_DIR/include/petscversion.h`` with the three macros +``PETSC_VERSION_MAJOR``, ``PETSC_VERSION_MINOR``, and ``PETSC_VERSION_SUBMINOR``. + +The shell commands ``make getversion`` or ``$PETSC_DIR/lib/petsc/bin/petscversion`` prints out the PETSc version. +The command + + .. code-block:: console + + $ $PETSC_DIR/lib/petsc/bin/petscversion major.minor<.subminor> + +allows one to add tests to make files, CMake files, configure scripts etc, to ensure the PETSc version is compatible with your applications. For example, + + .. code-block:: console + + $ $PETSC_DIR/lib/petsc/bin/petscversion eq 3.22 + +returns 1 if the PETSc version is 3.22 (any subminor version is allowed). While + + .. code-block:: console + + $ $PETSC_DIR/lib/petsc/bin/petscversion ge 3.21 + +returns 1 if the PETSc version is 3.21 or higher. + + +Though we try to avoid making changes to the PETSc API, they are inevitable; thus we +provide tools to help manage one's application to be robust to such changes. + +During configure/make time +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The command + +.. code-block:: console + + $ $PETSC_DIR/lib/petsc/bin/petscversion eq xxx.yyy[.zzz] + +prints out 1 if the PETSc version matches ``xxx.yyy[.zzz]`` and 0 otherwise. The command works in a similar +way for ``lt``, ``le``, ``gt``, and ``ge``. This allows your application configure script, or ``makefile`` or ``CMake`` file +to check if the PETSc version is compatible with application even before beginning to compile your code. + + +During compile time +~~~~~~~~~~~~~~~~~~~ + +The CPP macros + +- ``PETSC_VERSION_EQ(MAJOR,MINOR,SUBMINOR)`` +- ``PETSC_VERSION_LT(MAJOR,MINOR,SUBMINOR)`` +- ``PETSC_VERSION_LE(MAJOR,MINOR,SUBMINOR)`` +- ``PETSC_VERSION_GT(MAJOR,MINOR,SUBMINOR)`` +- ``PETSC_VERSION_GE(MAJOR,MINOR,SUBMINOR)`` + +may be used in the source code to choose different code paths or error out depending on the PETSc version. + +At Runtime +~~~~~~~~~~ + + +The command + +.. code-block:: C + + char version(lengthofversion); + PetscErrorCode PetscGetVersion(char version[], size_t lengthofversion) + +gives access to the version at runtime. diff --git a/doc/public/_redirects b/doc/public/_redirects index b89f98f3341..a5090fa948f 100644 --- a/doc/public/_redirects +++ b/doc/public/_redirects @@ -4,3 +4,5 @@ /main/download /main/install/download 302 /release/docs/* /release/:splat 301 /main/docs/* /main/:splat 301 +/community/* /release/community/:splat 301 +/manualpages/* /release/manualpages/:splat 301 diff --git a/gmakefile.test b/gmakefile.test index 9be4d91e08a..48a34c27751 100644 --- a/gmakefile.test +++ b/gmakefile.test @@ -455,6 +455,7 @@ help-nontest: -@echo " libs - build (update) the PETSc and related libraries" -@echo " check - run a basic check that the libraries are built correctly and can be used" -@echo " " + -@echo " getversion - print the PETSc version, or $PETSC_DIR/lib/petsc/bin/petscversion" -@echo " getmpiexec - print the mpiexec to use to run PETSc programs" -@echo " getlinklibs - print the libraries that a PETSc application must link against" -@echo " getincludedirs - print the include directories that a PETSc application must be compiled against" diff --git a/include/petsc/private/viewercgnsimpl.h b/include/petsc/private/viewercgnsimpl.h index e1aeea80506..10ee625af90 100644 --- a/include/petsc/private/viewercgnsimpl.h +++ b/include/petsc/private/viewercgnsimpl.h @@ -20,8 +20,9 @@ typedef struct { PetscInt batch_size; // Solution reading information - PetscInt solution_index; // User set solution index - int solution_file_index; // CGNS file solution index for direct access + PetscInt solution_index; // User set solution index + int solution_file_index; // CGNS file solution index for direct access + int solution_file_pointer_index; // CGNS file solution index for FlowSolutionPointers (and other related arrays), index by 1 char *solution_name; } PetscViewer_CGNS; diff --git a/include/petsclog.h b/include/petsclog.h index 6257998adb9..34b6d7a2f22 100644 --- a/include/petsclog.h +++ b/include/petsclog.h @@ -322,7 +322,7 @@ PETSC_EXTERN PetscErrorCode PetscLogEventsResume(void); PETSC_EXTERN PetscErrorCode PetscLogClassGetClassId(const char[], PetscClassId *); PETSC_EXTERN PetscErrorCode PetscLogClassIdGetName(PetscClassId, const char **); -static inline PETSC_UNUSED PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm) +static inline PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm) { if (PetscLogStateEventCurrentlyActive(petsc_log_state, e)) { for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { @@ -336,7 +336,7 @@ static inline PETSC_UNUSED PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI return PETSC_SUCCESS; } -static inline PETSC_UNUSED PetscErrorCode PetscLogEventBegin_Internal(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) +static inline PetscErrorCode PetscLogEventBegin_Internal(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) { if (PetscLogStateEventCurrentlyActive(petsc_log_state, e)) { for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { @@ -351,7 +351,7 @@ static inline PETSC_UNUSED PetscErrorCode PetscLogEventBegin_Internal(PetscLogEv } #define PetscLogEventBegin(e, o1, o2, o3, o4) PetscLogEventBegin_Internal(e, (PetscObject)(o1), (PetscObject)(o2), (PetscObject)(o3), (PetscObject)(o4)) -static inline PETSC_UNUSED PetscErrorCode PetscLogEventEnd_Internal(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) +static inline PetscErrorCode PetscLogEventEnd_Internal(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) { if (PetscLogStateEventCurrentlyActive(petsc_log_state, e)) { for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { @@ -367,7 +367,7 @@ static inline PETSC_UNUSED PetscErrorCode PetscLogEventEnd_Internal(PetscLogEven #define PetscLogEventEnd(e, o1, o2, o3, o4) PetscLogEventEnd_Internal(e, (PetscObject)(o1), (PetscObject)(o2), (PetscObject)(o3), (PetscObject)(o4)) /* Object functions */ -static inline PETSC_UNUSED PetscErrorCode PetscLogObjectCreate(PetscObject o) +static inline PetscErrorCode PetscLogObjectCreate(PetscObject o) { if (petsc_log_state) { for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { @@ -381,7 +381,7 @@ static inline PETSC_UNUSED PetscErrorCode PetscLogObjectCreate(PetscObject o) return PETSC_SUCCESS; } -static inline PETSC_UNUSED PetscErrorCode PetscLogObjectDestroy(PetscObject o) +static inline PetscErrorCode PetscLogObjectDestroy(PetscObject o) { if (petsc_log_state) { for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) { diff --git a/include/petscsys.h b/include/petscsys.h index ac05dae8205..abf94c8b512 100644 --- a/include/petscsys.h +++ b/include/petscsys.h @@ -71,6 +71,7 @@ This usually happens because * either an unexpected mpi.h is in the default compiler path (i.e. in /usr/include) or * an extra include path -I/something (which contains the unexpected mpi.h) is being passed to the compiler + Note: with MPICH and OpenMPI, accept versions [x.y.z, x+1.0.0) as compatible */ #if defined(PETSC_HAVE_MPIUNI) #ifndef MPIUNI_H @@ -91,14 +92,18 @@ #elif defined(PETSC_HAVE_MPICH) #if !defined(MPICH_NUMVERSION) || defined(MVAPICH2_NUMVERSION) || defined(I_MPI_NUMVERSION) #error "PETSc was configured with MPICH but now appears to be compiling using a non-MPICH mpi.h" - #elif !PETSC_PKG_MPICH_VERSION_EQ(MPICH_NUMVERSION / 10000000, MPICH_NUMVERSION / 100000 % 100, MPICH_NUMVERSION / 1000 % 100) - #error "PETSc was configured with one MPICH mpi.h version but now appears to be compiling using a different MPICH mpi.h version" + #elif PETSC_PKG_MPICH_VERSION_GT(MPICH_NUMVERSION / 10000000, MPICH_NUMVERSION / 100000 % 100, MPICH_NUMVERSION / 1000 % 100) + #error "PETSc was configured with one MPICH mpi.h version but now appears to be compiling using an older MPICH mpi.h version" + #elif PETSC_PKG_MPICH_VERSION_LT(MPICH_NUMVERSION / 10000000, 0, 0) + #error "PETSc was configured with one MPICH mpi.h version but now appears to be compiling using a newer major MPICH mpi.h version" #endif #elif defined(PETSC_HAVE_OPENMPI) #if !defined(OMPI_MAJOR_VERSION) #error "PETSc was configured with Open MPI but now appears to be compiling using a non-Open MPI mpi.h" - #elif !PETSC_PKG_OPENMPI_VERSION_EQ(OMPI_MAJOR_VERSION, OMPI_MINOR_VERSION, OMPI_RELEASE_VERSION) - #error "PETSc was configured with one Open MPI mpi.h version but now appears to be compiling using a different Open MPI mpi.h version" + #elif PETSC_PKG_OPENMPI_VERSION_GT(OMPI_MAJOR_VERSION, OMPI_MINOR_VERSION, OMPI_RELEASE_VERSION) + #error "PETSc was configured with one Open MPI mpi.h version but now appears to be compiling using an older Open MPI mpi.h version" + #elif PETSC_PKG_OPENMPI_VERSION_LT(OMPI_MAJOR_VERSION, 0, 0) + #error "PETSc was configured with one Open MPI mpi.h version but now appears to be compiling using a newer major Open MPI mpi.h version" #endif #elif defined(PETSC_HAVE_MSMPI_VERSION) #if !defined(MSMPI_VER) diff --git a/include/petscversion.h b/include/petscversion.h index a3297273a3d..d3314037d1b 100644 --- a/include/petscversion.h +++ b/include/petscversion.h @@ -5,7 +5,7 @@ #define PETSC_VERSION_RELEASE 1 #define PETSC_VERSION_MAJOR 3 #define PETSC_VERSION_MINOR 22 -#define PETSC_VERSION_SUBMINOR 1 +#define PETSC_VERSION_SUBMINOR 2 #define PETSC_RELEASE_DATE "Sep 28, 2024" #define PETSC_VERSION_DATE "unknown" diff --git a/lib/petsc/bin/petscversion b/lib/petsc/bin/petscversion new file mode 100755 index 00000000000..6a89d379245 --- /dev/null +++ b/lib/petsc/bin/petscversion @@ -0,0 +1,98 @@ +#!/usr/bin/env sh + +# +# petscversion major.minor[.subminor]" +# returns 1 on match else 0 +# +# For example: petscversion gt 3.22.1" + +if [ "X${PETSC_DIR}" = "X" ] ; then + dir=$(dirname $0) + dir=$(dirname $dir) + dir=$(dirname $dir) + PETSC_DIR=$(dirname $dir) +fi + +file=${PETSC_DIR}/include/petscversion.h + +if [ ! -f $file ]; then + echo "Unable to find petscversion.h; ensure the environmental variable PETSC_DIR is set correctly" + exit 1 +fi + +major=`grep "#define PETSC_VERSION_MAJOR" $file | tr -s ' ' | cut -d" " -f 3` +minor=`grep "#define PETSC_VERSION_MINOR" $file | tr -s ' ' | cut -d" " -f 3` +subminor=`grep "#define PETSC_VERSION_SUBMINOR" $file | tr -s ' ' | cut -d" " -f 3` +release=`grep "#define PETSC_VERSION_RELEASE" $file | tr -s ' ' | cut -d" " -f 3` + +if [ $# -lt 1 ]; then + echo ${major}.${minor}.${subminor} + exit 0 +fi + +t=$1 +v=$2 + +vmajor=`echo $v | cut -d"." -f 1` +vminor=`echo $v | cut -d"." -f 2` +vsubminor=`echo $v | cut -d"." -f 3` + +if [ "${t}X" = "X" ] || [ "${v}X" = "X" ]; then + echo "Usage: petscversion version" + echo "For example: petscversion gt 3.22.1" + exit 1 +fi + +eq () { +# if [ $release = 0 ]; then echo 0; exit 0; fi + if [ $major != $vmajor ]; then echo 0; exit 0; fi + if [ $minor != $vminor ]; then echo 0; exit 0; fi + if [ "${vsubminor}X" = "X" ]; then echo 1; exit 0; fi + if [ $subminor != $vsubminor ]; then echo 0; exit 0; fi + echo 1 +} + +lt () { +# if [ $release = 0 ]; then echo 0; exit 0; fi + if [ $major -lt $vmajor ]; then echo 1; exit 0; fi + if [ $major -gt $vmajor ]; then echo 0; exit 0; fi + if [ $minor -lt $vminor ]; then echo 1; exit 0; fi + if [ $minor -gt $vminor ]; then echo 0; exit 0; fi + if [ "${vsubminor}X" = "X" ]; then echo 0; exit 0; fi + if [ $subminor -lt $vsubminor ]; then echo 1; exit 0; fi + echo 0 +} + +le () { +# if [ $release = 0 ]; then echo 0; exit 0; fi + if [ $major -lt $vmajor ]; then echo 1; exit 0; fi + if [ $major -gt $vmajor ]; then echo 0; exit 0; fi + if [ $minor -lt $vminor ]; then echo 1; exit 0; fi + if [ $minor -gt $vminor ]; then echo 0; exit 0; fi + if [ "${vsubminor}X" = "X" ]; then echo 0; exit 0; fi + if [ $subminor -le $vsubminor ]; then echo 1; exit 0; fi + echo 0 +} + +gt () { + if [ $major -gt $vmajor ]; then echo 1; exit 0; fi + if [ $major -lt $vmajor ]; then echo 0; exit 0; fi + if [ $minor -gt $vminor ]; then echo 1; exit 0; fi + if [ $minor -lt $vminor ]; then echo 0; exit 0; fi + if [ "${vsubminor}X" = "X" ]; then echo 1; exit 0; fi + if [ $subminor -gt $vsubminor ]; then echo 1; exit 0; fi + echo 0 +} + +ge () { + if [ $major -gt $vmajor ]; then echo 1; exit 0; fi + if [ $major -lt $vmajor ]; then echo 0; exit 0; fi + if [ $minor -gt $vminor ]; then echo 1; exit 0; fi + if [ $minor -lt $vminor ]; then echo 0; exit 0; fi + if [ "${vsubminor}X" = "X" ]; then echo 1; exit 0; fi + if [ $subminor -ge $vsubminor ]; then echo 1; exit 0; fi + echo 0 +} + +${t} + diff --git a/lib/petsc/conf/rules_util.mk b/lib/petsc/conf/rules_util.mk index cd2baf85d04..76ad256e021 100644 --- a/lib/petsc/conf/rules_util.mk +++ b/lib/petsc/conf/rules_util.mk @@ -6,6 +6,9 @@ # ********* Rules for printing PETSc library properties useful for building applications *********************************************************** +getversion: + -@${PETSC_DIR}/lib/petsc/bin/petscversion + getmpilinklibs: -@echo ${MPI_LIB} diff --git a/setup.py b/setup.py index 7d0171df801..d88f6c841c9 100755 --- a/setup.py +++ b/setup.py @@ -39,8 +39,11 @@ import shlex import shutil from setuptools import setup -from wheel.bdist_wheel import bdist_wheel as _bdist_wheel from setuptools.command.install import install as _install +try: + from setuptools.command.bdist_wheel import bdist_wheel as _bdist_wheel +except ImportError: + from wheel.bdist_wheel import bdist_wheel as _bdist_wheel from distutils import log init_py = """\ diff --git a/share/petsc/suppressions/ubsan b/share/petsc/suppressions/ubsan index b3c7de4adf0..f31f0cfac8b 100644 --- a/share/petsc/suppressions/ubsan +++ b/share/petsc/suppressions/ubsan @@ -11,6 +11,7 @@ function:MatFDColoringApply_BAIJ # Monitor callbacks using typed contexts function:DMAdaptMonitor +function:DMAdaptorMonitorError function:KSPMonitor function:SNESMonitor function:TSMonitor @@ -45,6 +46,7 @@ function:DMTSView # viewer contexts destroys function:TaoMonitorCancel function:PetscMonitorCompare +function:PetscViewerAndFormatDestroy # misc shift-base:MCJPMinColor_Private diff --git a/src/binding/petsc4py/setup.py b/src/binding/petsc4py/setup.py index 8f35fd3ec8f..278d39f6856 100755 --- a/src/binding/petsc4py/setup.py +++ b/src/binding/petsc4py/setup.py @@ -232,6 +232,7 @@ def requires(pkgname, major, minor, release=True): def run_setup(): + is_sdist = 'sdist' in sys.argv setup_args = metadata.copy() vstr = setup_args['version'].split('.')[:2] x, y = tuple(map(int, vstr)) @@ -240,13 +241,15 @@ def run_setup(): setup_args['version'] = '%d.%d.0.dev0' % (x, y + 1) if setuptools: setup_args['zip_safe'] = False - try: - import numpy - - major = int(numpy.__version__.partition('.')[0]) - numpy_pin = 'numpy>=1.19' if major >= 2 else 'numpy<2' - except ImportError: - numpy_pin = 'numpy' + numpy_pin = 'numpy' + if not is_sdist: + try: + import numpy + + major = int(numpy.__version__.partition('.')[0]) + numpy_pin = 'numpy>=1.19' if major >= 2 else 'numpy<2' + except ImportError: + pass setup_args['setup_requires'] = ['numpy'] setup_args['install_requires'] = [numpy_pin] for pkg in map(str.lower, PLIST): diff --git a/src/binding/petsc4py/src/petsc4py/PETSc/Mat.pyx b/src/binding/petsc4py/src/petsc4py/PETSc/Mat.pyx index 8fb1bcef54a..0fcb8b12a77 100644 --- a/src/binding/petsc4py/src/petsc4py/PETSc/Mat.pyx +++ b/src/binding/petsc4py/src/petsc4py/PETSc/Mat.pyx @@ -930,6 +930,29 @@ cdef class Mat(Object): Mat_AllocAIJ_CSR(self.mat, csr) return self + def preallocatorPreallocate(self, Mat A, fill: bool = True) -> None: + """Preallocate memory for a matrix using a preallocator matrix. + + Collective. + + The current matrix (``self``) must be of type `Type.PREALLOCATOR`. + + Parameters + ---------- + A + The matrix to be preallocated. + fill + Flag indicating whether or not to insert zeros into + the newly allocated matrix, defaults to `True`. + + See Also + -------- + petsc.MatPreallocatorPreallocate + + """ + cdef PetscBool cfill = asBool(fill) + CHKERR(MatPreallocatorPreallocate(self.mat, cfill, A.mat)) + def createAIJWithArrays( self, size: MatSizeSpec, diff --git a/src/binding/petsc4py/src/petsc4py/PETSc/Object.pyx b/src/binding/petsc4py/src/petsc4py/PETSc/Object.pyx index 7729d976675..4c76d987682 100644 --- a/src/binding/petsc4py/src/petsc4py/PETSc/Object.pyx +++ b/src/binding/petsc4py/src/petsc4py/PETSc/Object.pyx @@ -154,6 +154,9 @@ cdef class Object: Collective. + Classes that do not implement ``setFromOptions`` use this method + that, in turn, calls `petsc.PetscObjectSetFromOptions`. + See Also -------- petsc_options, petsc.PetscObjectSetFromOptions @@ -192,11 +195,13 @@ cdef class Object: Parameters ---------- handler - The callback function, called at the end of `setFromOptions`. + The callback function, called at the end of a ``setFromOptions`` invocation + for the given class. See Also -------- - petsc_options, setFromOptions, petsc.PetscObjectAddOptionsHandler + petsc_options, Mat.setFromOptions, KSP.setFromOptions + petsc.PetscObjectAddOptionsHandler """ if handler is not None: diff --git a/src/binding/petsc4py/src/petsc4py/PETSc/Vec.pyx b/src/binding/petsc4py/src/petsc4py/PETSc/Vec.pyx index f62c21f8ec5..b8d367ecfe9 100644 --- a/src/binding/petsc4py/src/petsc4py/PETSc/Vec.pyx +++ b/src/binding/petsc4py/src/petsc4py/PETSc/Vec.pyx @@ -3528,6 +3528,7 @@ cdef class Vec(Object): """ cdef DM dm = DM() CHKERR(VecGetDM(self.vec, &dm.dm)) + CHKERR(PetscObjectReference(dm.dm)) return dm # diff --git a/src/binding/petsc4py/src/petsc4py/PETSc/petscmat.pxi b/src/binding/petsc4py/src/petsc4py/PETSc/petscmat.pxi index 533e12b9363..90e505d31a0 100644 --- a/src/binding/petsc4py/src/petsc4py/PETSc/petscmat.pxi +++ b/src/binding/petsc4py/src/petsc4py/PETSc/petscmat.pxi @@ -511,6 +511,8 @@ cdef extern from * nogil: PetscErrorCode MatPythonSetType(PetscMat, char[]) PetscErrorCode MatPythonGetType(PetscMat, char*[]) + PetscErrorCode MatPreallocatorPreallocate(PetscMat, PetscBool, PetscMat) + cdef extern from * nogil: # custom.h PetscErrorCode MatGetCurrentMemType(PetscMat, PetscMemType*) PetscErrorCode MatIsPreallocated(PetscMat, PetscBool*) diff --git a/src/binding/petsc4py/src/petsc4py/__init__.py b/src/binding/petsc4py/src/petsc4py/__init__.py index a09febeb05f..55cddfd95d3 100644 --- a/src/binding/petsc4py/src/petsc4py/__init__.py +++ b/src/binding/petsc4py/src/petsc4py/__init__.py @@ -16,7 +16,7 @@ """ __author__ = 'Lisandro Dalcin' -__version__ = '3.22.1' +__version__ = '3.22.2' __credits__ = 'PETSc Team ' diff --git a/src/binding/petsc4py/test/test_device.py b/src/binding/petsc4py/test/test_device.py index 3c52009f592..25502567c77 100644 --- a/src/binding/petsc4py/test/test_device.py +++ b/src/binding/petsc4py/test/test_device.py @@ -7,6 +7,8 @@ class TestDevice(unittest.TestCase): def testCurrent(self): dctx = PETSc.DeviceContext().getCurrent() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 2) device = dctx.getDevice() del device @@ -26,6 +28,8 @@ def testDevice(self): def testDeviceContext(self): dctx = PETSc.DeviceContext().create() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 1) dctx.setUp() self.assertTrue(dctx.idle()) @@ -34,6 +38,8 @@ def testDeviceContext(self): def testStream(self): dctx = PETSc.DeviceContext().getCurrent() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 2) stype = dctx.getStreamType() dctx.setStreamType(stype) @@ -42,6 +48,8 @@ def testStream(self): def testSetFromOptions(self): dctx = PETSc.DeviceContext().create() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 1) dctx.setFromOptions() dctx.setUp() @@ -50,6 +58,8 @@ def testSetFromOptions(self): def testDuplicate(self): dctx = PETSc.DeviceContext().getCurrent() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 2) dctx2 = dctx.duplicate() self.assertEqual(dctx2.getRefCount(), 1) @@ -60,6 +70,8 @@ def testDuplicate(self): def testWaitFor(self): dctx = PETSc.DeviceContext().create() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 1) dctx.setUp() dctx2 = PETSc.DeviceContext().create() @@ -74,6 +86,8 @@ def testWaitFor(self): def testForkJoin(self): dctx = PETSc.DeviceContext().getCurrent() + if not dctx: + return self.assertEqual(dctx.getRefCount(), 2) jdestroy = PETSc.DeviceContext.JoinMode.DESTROY jtypes = [ diff --git a/src/dm/impls/network/network.c b/src/dm/impls/network/network.c index fe5536c358f..09f549beff4 100644 --- a/src/dm/impls/network/network.c +++ b/src/dm/impls/network/network.c @@ -955,6 +955,7 @@ PetscErrorCode DMNetworkRegisterComponent(DM dm, const char *name, size_t size, component = &network->component[network->ncomponent]; PetscCall(PetscStrncpy(component->name, name, sizeof(component->name))); + PetscCheck((size % sizeof(DMNetworkComponentGenericDataType)) == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Size of datatype must be divisible by sizeof(DMNetworkComponentGenericDataType)"); PetscCall(PetscIntCast(size / sizeof(DMNetworkComponentGenericDataType), &component->size)); *key = network->ncomponent; network->ncomponent++; diff --git a/src/ksp/ksp/tutorials/ex1.c b/src/ksp/ksp/tutorials/ex1.c index 1df1f2a2c6c..808f7b56acf 100644 --- a/src/ksp/ksp/tutorials/ex1.c +++ b/src/ksp/ksp/tutorials/ex1.c @@ -71,16 +71,18 @@ int main(int argc, char **args) col[2] = i + 1; PetscCall(MatSetValues(A, 1, &i, 3, col, value, INSERT_VALUES)); } - i = n - 1; - col[0] = n - 2; - col[1] = n - 1; - PetscCall(MatSetValues(A, 1, &i, 2, col, value, INSERT_VALUES)); + if (n > 1) { + i = n - 1; + col[0] = n - 2; + col[1] = n - 1; + PetscCall(MatSetValues(A, 1, &i, 2, col, value, INSERT_VALUES)); + } i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; - PetscCall(MatSetValues(A, 1, &i, 2, col, value, INSERT_VALUES)); + PetscCall(MatSetValues(A, 1, &i, n > 1 ? 2 : 1, col, value, INSERT_VALUES)); PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); diff --git a/src/ksp/ksp/tutorials/network/ex1.c b/src/ksp/ksp/tutorials/network/ex1.c index 063a276c0be..a3122d42552 100644 --- a/src/ksp/ksp/tutorials/network/ex1.c +++ b/src/ksp/ksp/tutorials/network/ex1.c @@ -38,13 +38,13 @@ typedef struct { PetscInt id; /* node id */ PetscScalar inj; /* current injection (A) */ PetscBool gr; /* boundary node */ -} Node; +} PETSC_ATTRIBUTEALIGNED(PetscMax(sizeof(PetscInt), sizeof(PetscScalar))) Node; typedef struct { PetscInt id; /* branch id */ PetscScalar r; /* resistance (ohms) */ PetscScalar bat; /* battery (V) */ -} Branch; +} PETSC_ATTRIBUTEALIGNED(PetscMax(sizeof(PetscInt), sizeof(PetscScalar))) Branch; /* read_data: this routine fills data structures with problem data. @@ -312,9 +312,11 @@ int main(int argc, char **argv) requires: !complex double defined(PETSC_HAVE_ATTRIBUTEALIGNED) test: + diff_args: -j args: -ksp_monitor_short test: + diff_args: -j suffix: 2 nsize: 2 args: -petscpartitioner_type simple -ksp_converged_reason diff --git a/src/ksp/pc/impls/vpbjacobi/kokkos/vpbjacobi_kok.kokkos.cxx b/src/ksp/pc/impls/vpbjacobi/kokkos/vpbjacobi_kok.kokkos.cxx index f0f39c6862f..533b0214162 100644 --- a/src/ksp/pc/impls/vpbjacobi/kokkos/vpbjacobi_kok.kokkos.cxx +++ b/src/ksp/pc/impls/vpbjacobi/kokkos/vpbjacobi_kok.kokkos.cxx @@ -184,10 +184,11 @@ PETSC_INTERN PetscErrorCode PCSetUp_VPBJacobi_Kokkos(PC pc, Mat diagVPB) const auto &bs = pckok->bs_dual.view_device(); const auto &bs2 = pckok->bs2_dual.view_device(); const auto &blkMap = pckok->blkMap_dual.view_device(); - PetscCall(PetscObjectBaseTypeCompare((PetscObject)pc->pmat, MATMPIAIJ, &ismpi)); if (diagVPB) { // If caller provided a matrix made of the diagonal blocks, use it - A = diagVPB; + PetscCall(PetscObjectBaseTypeCompare((PetscObject)diagVPB, MATMPIAIJ, &ismpi)); + A = ismpi ? static_cast(diagVPB->data)->A : diagVPB; } else { + PetscCall(PetscObjectBaseTypeCompare((PetscObject)pc->pmat, MATMPIAIJ, &ismpi)); A = ismpi ? static_cast(pc->pmat->data)->A : pc->pmat; } PetscCall(MatInvertVariableBlockDiagonal_SeqAIJKokkos(A, bs, bs2, blkMap, pckok->work, pckok->diag)); diff --git a/src/snes/interface/snes.c b/src/snes/interface/snes.c index 0dd71689b1b..5e9d8038b4f 100644 --- a/src/snes/interface/snes.c +++ b/src/snes/interface/snes.c @@ -3948,9 +3948,6 @@ PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, Pe Fortran Note: Use ``PETSC_DETERMINE_REAL` or `PETSC_UNLIMITED_REAL` - Developer Note: - Also supports the deprecated -1 to indicate no bound on the growth of the residual - .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance()` @*/ PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) diff --git a/src/sys/classes/viewer/impls/cgns/cgnsv.c b/src/sys/classes/viewer/impls/cgns/cgnsv.c index 171b71bf33f..f497ef4856a 100644 --- a/src/sys/classes/viewer/impls/cgns/cgnsv.c +++ b/src/sys/classes/viewer/impls/cgns/cgnsv.c @@ -379,15 +379,15 @@ PetscErrorCode PetscViewerCGNSGetSolutionFileIndex_Internal(PetscViewer viewer, { // Get FlowSolutionPointer name corresponding to solution_id cgsize_t size[12]; - int dim, A_index, pointer_id; + int dim, A_index; char *pointer_names, *pointer_id_name_ref; PetscCall(CGNS_Find_Array(comm, "FlowSolutionPointers", &A_index, NULL, &dim, size)); PetscCheck(cgv->solution_index == -1 || cgv->solution_index <= size[1], comm, PETSC_ERR_ARG_OUTOFRANGE, "CGNS Solution index (%" PetscInt_FMT ") not in range of FlowSolutionPointers [1, %" PRIdCGSIZE "]", cgv->solution_index, size[1]); PetscCall(PetscCalloc1(size[0] * size[1] + 1, &pointer_names)); // Need the +1 for (possibly) setting \0 for the last pointer name if it's full PetscCallCGNS(cg_array_read_as(1, CGNS_ENUMV(Character), pointer_names)); - pointer_id = cgv->solution_index == -1 ? size[1] : cgv->solution_index; - pointer_id_name_ref = &pointer_names[size[0] * (pointer_id - 1)]; + cgv->solution_file_pointer_index = cgv->solution_index == -1 ? size[1] : cgv->solution_index; + pointer_id_name_ref = &pointer_names[size[0] * (cgv->solution_file_pointer_index - 1)]; { // Set last non-whitespace character of the pointer name to \0 (CGNS pads with spaces) int str_idx; for (str_idx = size[0] - 1; str_idx > 0; str_idx--) { @@ -436,7 +436,7 @@ PetscErrorCode PetscViewerCGNSGetSolutionFileIndex_Internal(PetscViewer viewer, PetscErrorCode PetscViewerCGNSGetSolutionTime(PetscViewer viewer, PetscReal *time, PetscBool *set) { PetscViewer_CGNS *cgv = (PetscViewer_CGNS *)viewer->data; - int cgns_ier, A_index = 0; + int cgns_ier, A_index = 0, sol_id; PetscReal *times; cgsize_t size[12]; @@ -449,7 +449,8 @@ PetscErrorCode PetscViewerCGNSGetSolutionTime(PetscViewer viewer, PetscReal *tim PetscCall(CGNS_Find_Array(PetscObjectComm((PetscObject)viewer), "TimeValues", &A_index, NULL, NULL, size)); PetscCall(PetscMalloc1(size[0], ×)); PetscCallCGNS(cg_array_read_as(A_index, CGNS_ENUMV(RealDouble), times)); - *time = times[cgv->solution_index - 1]; + PetscCall(PetscViewerCGNSGetSolutionFileIndex_Internal(viewer, &sol_id)); // Call to set file pointer index + *time = times[cgv->solution_file_pointer_index - 1]; *set = PETSC_TRUE; PetscCall(PetscFree(times)); PetscFunctionReturn(PETSC_SUCCESS); diff --git a/src/sys/objects/inherit.c b/src/sys/objects/inherit.c index 7f868e7b004..24c5be1bea1 100644 --- a/src/sys/objects/inherit.c +++ b/src/sys/objects/inherit.c @@ -1073,7 +1073,7 @@ PetscErrorCode PetscObjectContainerQuery(PetscObject obj, const char *name, void Level: beginner Note: - We have no generic options at present, so this does nothing + We have no generic options at present, so this does nothing. .seealso: `PetscObjectSetOptionsPrefix()`, `PetscObjectGetOptionsPrefix()`, `PetscObject` @*/ diff --git a/src/sys/utils/server.c b/src/sys/utils/server.c index 53e6d435127..b59da5d9e35 100644 --- a/src/sys/utils/server.c +++ b/src/sys/utils/server.c @@ -4,7 +4,7 @@ #include PetscBool PCMPIServerActive = PETSC_FALSE; // PETSc is running in server mode -PetscBool PCMPIServerInSolve = PETSC_FALSE; // A parallel server solve is occuring +PetscBool PCMPIServerInSolve = PETSC_FALSE; // A parallel server solve is occurring PetscBool PCMPIServerUseShmget = PETSC_TRUE; // Use Unix shared memory for distributing objects #if defined(PETSC_HAVE_SHMGET) diff --git a/src/ts/event/tests/ex3.c b/src/ts/event/tests/ex3.c index 825427a96ee..7f4a9dbd420 100644 --- a/src/ts/event/tests/ex3.c +++ b/src/ts/event/tests/ex3.c @@ -20,8 +20,8 @@ static char help[] = "Simple linear problem with events\n" "-dtpost x : if x > 0, then on even PostEvent calls 1st-post-event-step = x is set,\n" " on odd PostEvent calls 1st-post-event-step = PETSC_DECIDE is set,\n" " if x == 0, nothing happens\n" - "-V {float}: scaling of the sin() event function; for small V this event is triggered by the function values,\n" - " for large V the event is triggered by the small step size\n" + "-v {float}: scaling of the sin() event function; for small v this event is triggered by the function values,\n" + " for large v the event is triggered by the small step size\n" "-change5 : flag to change the state vector at t=5 PostEvent\n"; #define MAX_NFUNC 100 // max event functions per rank @@ -119,7 +119,7 @@ int main(int argc, char **argv) PetscCall(PetscOptionsGetReal(NULL, NULL, "-errtol", &ctx.errtol, NULL)); // error tolerance for located events PetscCall(PetscOptionsGetBool(NULL, NULL, "-restart", &ctx.restart, NULL)); // flag for TSRestartStep() PetscCall(PetscOptionsGetReal(NULL, NULL, "-dtpost", &ctx.dtpost, NULL)); // post-event step - PetscCall(PetscOptionsGetReal(NULL, NULL, "-V", &ctx.V, NULL)); + PetscCall(PetscOptionsGetReal(NULL, NULL, "-v", &ctx.V, NULL)); PetscCall(PetscOptionsGetBool(NULL, NULL, "-change5", &ctx.change5, NULL)); // flag to change the state vector at t=5 PostEvent n = 0; // event counter @@ -262,7 +262,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea output_file: output/ex3_V.out args: -ts_type beuler args: -ts_adapt_type basic - args: -V {{1e2 1e5 1e8}} + args: -v {{1e2 1e5 1e8}} args: -ts_adapt_dt_min 1e-6 args: -change5 {{0 1}} nsize: 1 @@ -271,7 +271,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: neu1 output_file: output/ex3_neu1.out args: -dir 0 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 1 args: -dtpost 0.24 @@ -284,7 +284,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: neu2 output_file: output/ex3_neu2.out args: -dir 0 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 1 args: -dtpost 0 @@ -299,7 +299,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: neu4 output_file: output/ex3_neu4.out args: -dir 0 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart {{0 1}} args: -dtpost 0.24 @@ -314,7 +314,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: pos1 output_file: output/ex3_pos1.out args: -dir 1 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 0 args: -dtpost 0.24 @@ -326,7 +326,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: pos2 output_file: output/ex3_pos2.out args: -dir 1 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 1 args: -dtpost {{0 0.24}} @@ -340,7 +340,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: pos4 output_file: output/ex3_pos4.out args: -dir 1 - args: -V 1e9 + args: -v 1e9 args: -ts_adapt_dt_min 1e-6 args: -restart 0 args: -dtpost 0 @@ -356,7 +356,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: neg1 output_file: output/ex3_neg1.out args: -dir -1 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 1 args: -dtpost {{0 0.24}} @@ -368,7 +368,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: neg2 output_file: output/ex3_neg2.out args: -dir -1 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 0 args: -dtpost {{0 0.24}} @@ -382,7 +382,7 @@ PetscErrorCode Postevent(TS ts, PetscInt nev_zero, PetscInt evs_zero[], PetscRea suffix: neg4 output_file: output/ex3_neg4.out args: -dir -1 - args: -V 1e5 + args: -v 1e5 args: -ts_adapt_dt_min 1e-6 args: -restart 0 args: -dtpost {{0 0.24}} diff --git a/src/vec/is/is/utils/isdiff.c b/src/vec/is/is/utils/isdiff.c index 53972b374bf..29e72d40072 100644 --- a/src/vec/is/is/utils/isdiff.c +++ b/src/vec/is/is/utils/isdiff.c @@ -594,7 +594,7 @@ PetscErrorCode ISListToPair(MPI_Comm comm, PetscInt listlen, IS islist[], IS *xi Input Parameters: + xis - domain `IS` -- yis - range `IS`, the maxium value must be less than `PETSC_MPI_INT_MAX` +- yis - range `IS`, the maximum value must be less than `PETSC_MPI_INT_MAX` Output Parameters: + listlen - length of `islist` diff --git a/src/vec/vec/impls/mpi/pbvec.c b/src/vec/vec/impls/mpi/pbvec.c index 4f8527826de..25d01893a5d 100644 --- a/src/vec/vec/impls/mpi/pbvec.c +++ b/src/vec/vec/impls/mpi/pbvec.c @@ -425,11 +425,10 @@ static PetscErrorCode VecGetLocalToGlobalMapping_MPI_VecGhost(Vec X, ISLocalToGl const PetscInt *ghostidx; PetscFunctionBegin; - if (X->map->mapping) { - *ltg = X->map->mapping; - PetscFunctionReturn(PETSC_SUCCESS); - } + *ltg = X->map->mapping; + if (X->map->mapping) PetscFunctionReturn(PETSC_SUCCESS); PetscCall(VecGhostGetGhostIS(X, &ghostis)); + if (!ghostis) PetscFunctionReturn(PETSC_SUCCESS); PetscCall(ISGetLocalSize(ghostis, &nghost)); PetscCall(VecGetLocalSize(X, &n)); PetscCall(ISGetIndices(ghostis, &ghostidx)); diff --git a/src/vec/vec/impls/seq/kokkos/veckok.kokkos.cxx b/src/vec/vec/impls/seq/kokkos/veckok.kokkos.cxx index 02212a49c19..a4e13bc4d11 100644 --- a/src/vec/vec/impls/seq/kokkos/veckok.kokkos.cxx +++ b/src/vec/vec/impls/seq/kokkos/veckok.kokkos.cxx @@ -15,6 +15,31 @@ #include <../src/vec/vec/impls/dvecimpl.h> /* for VecCreate_Seq_Private */ #include <../src/vec/vec/impls/seq/kokkos/veckokkosimpl.hpp> +// Sync a Kokkos::DualView to in execution space +// If is HostSpace, fence the exec so that the data on host is immediately available. +template +static PetscErrorCode KokkosDualViewSync(Kokkos::DualView &v_dual, const Kokkos::DefaultExecutionSpace &exec) +{ + size_t bytes = v_dual.extent(0) * sizeof(Type); + + PetscFunctionBegin; + PetscCall(PetscLogGpuTimeBegin()); + if (std::is_same_v) { + if (v_dual.need_sync_host()) { + PetscCallCXX(v_dual.sync_host(exec)); + PetscCallCXX(exec.fence()); // make sure one can access the host copy immediately + PetscCall(PetscLogGpuToCpu(bytes)); + } + } else { + if (v_dual.need_sync_device()) { + PetscCallCXX(v_dual.sync_device(exec)); + PetscCall(PetscLogCpuToGpu(bytes)); + } + } + PetscCall(PetscLogGpuTimeEnd()); + PetscFunctionReturn(PETSC_SUCCESS); +} + template static PetscErrorCode VecGetKokkosView_Private(Vec v, PetscScalarKokkosViewType *kv, PetscBool overwrite) { @@ -23,15 +48,7 @@ static PetscErrorCode VecGetKokkosView_Private(Vec v, PetscScalarKokkosViewType< PetscFunctionBegin; VecErrorIfNotKokkos(v); if (!overwrite) { /* If overwrite=true, no need to sync the space, since caller will overwrite the data */ - auto &exec = PetscGetKokkosExecutionSpace(); - constexpr bool hostspace = std::is_same_v; - if (hostspace) { - if (veckok->v_dual.need_sync_host()) PetscCall(PetscLogGpuToCpu(veckok->v_dual.extent(0) * sizeof(PetscScalar))); - } else { - if (veckok->v_dual.need_sync_device()) PetscCall(PetscLogCpuToGpu(veckok->v_dual.extent(0) * sizeof(PetscScalar))); - } - veckok->v_dual.sync(exec); // async call - if (hostspace) exec.fence(); // make sure one can access the host copy immediately + PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); } *kv = veckok->v_dual.view(); PetscFunctionReturn(PETSC_SUCCESS); @@ -53,19 +70,11 @@ static PetscErrorCode VecRestoreKokkosView_Private(Vec v, PetscScalarKokkosViewT template PetscErrorCode VecGetKokkosView(Vec v, ConstPetscScalarKokkosViewType *kv) { - Vec_Kokkos *veckok = static_cast(v->spptr); - auto &exec = PetscGetKokkosExecutionSpace(); - constexpr bool hostspace = std::is_same_v; + Vec_Kokkos *veckok = static_cast(v->spptr); PetscFunctionBegin; VecErrorIfNotKokkos(v); - if (hostspace) { - if (veckok->v_dual.need_sync_host()) PetscCall(PetscLogGpuToCpu(veckok->v_dual.extent(0) * sizeof(PetscScalar))); - } else { - if (veckok->v_dual.need_sync_device()) PetscCall(PetscLogCpuToGpu(veckok->v_dual.extent(0) * sizeof(PetscScalar))); - } - veckok->v_dual.sync(exec); - if (hostspace) exec.fence(); // make sure one can access the host copy immediately + PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); *kv = veckok->v_dual.view(); PetscFunctionReturn(PETSC_SUCCESS); } @@ -425,6 +434,7 @@ static PetscErrorCode VecMultiDot_Verbose(Vec xin, PetscInt nv, const Vec yin[], lsum4 += xv(i) * PetscConj(y4(i)); lsum5 += xv(i) * PetscConj(y5(i)); lsum6 += xv(i) * PetscConj(y6(i)); lsum7 += xv(i) * PetscConj(y7(i)); }, zp[0], zp[1], zp[2], zp[3], zp[4], zp[5], zp[6], zp[7]); PetscCall(PetscLogGpuTimeEnd()); + PetscCall(PetscLogGpuToCpu(8 * sizeof(PetscScalar))); // for copying to z[] on host PetscCall(VecRestoreKokkosView(yp[0], &y0)); PetscCall(VecRestoreKokkosView(yp[1], &y1)); PetscCall(VecRestoreKokkosView(yp[2], &y2)); @@ -501,6 +511,7 @@ static PetscErrorCode VecMultiDot_Verbose(Vec xin, PetscInt nv, const Vec yin[], break; } PetscCall(PetscLogGpuTimeEnd()); + PetscCall(PetscLogGpuToCpu(rem * sizeof(PetscScalar))); // for copying to z[] on host if (rem > 0) PetscCall(VecRestoreKokkosView(yp[0], &y0)); if (rem > 1) PetscCall(VecRestoreKokkosView(yp[1], &y1)); if (rem > 2) PetscCall(VecRestoreKokkosView(yp[2], &y2)); @@ -525,7 +536,6 @@ PetscErrorCode VecMDot_SeqKokkos(Vec xin, PetscInt nv, const Vec yin[], PetscSca #else PetscCall(VecMultiDot_Verbose(xin, nv, yin, z)); #endif - PetscCall(PetscLogGpuToCpu(nv * sizeof(PetscScalar))); // for copying to z[] on host PetscCall(PetscLogGpuFlops(PetscMax(nv * (2.0 * xin->map->n - 1), 0.0))); PetscFunctionReturn(PETSC_SUCCESS); } @@ -535,7 +545,6 @@ PetscErrorCode VecMTDot_SeqKokkos(Vec xin, PetscInt nv, const Vec yin[], PetscSc { PetscFunctionBegin; PetscCall(VecMultiDot_Private(xin, nv, yin, z)); - PetscCall(PetscLogGpuToCpu(nv * sizeof(PetscScalar))); // for copying to z[] on host PetscCall(PetscLogGpuFlops(PetscMax(nv * (2.0 * xin->map->n - 1), 0.0))); PetscFunctionReturn(PETSC_SUCCESS); } @@ -592,8 +601,9 @@ static PetscErrorCode VecMultiDot_SeqKokkos_GEMV(PetscBool conjugate, Vec xin, P PetscCall(PetscLogGpuTimeBegin()); PetscCallCXX(KokkosBlas::gemv(PetscGetKokkosExecutionSpace(), trans, 1.0, Y, xv, 0.0, zv.view_device())); PetscCall(PetscLogGpuTimeEnd()); - zv.modify_device(); - zv.sync_host(); + PetscCallCXX(zv.modify_device()); + PetscCallCXX(zv.sync_host()); + PetscCall(PetscLogGpuToCpu(zv.extent(0) * sizeof(PetscScalar))); PetscCall(PetscLogGpuFlops(PetscMax(m * (2.0 * n - 1), 0.0))); } else { // we only allow falling back on VecDot once, to avoid doing VecMultiDot via individual VecDots @@ -616,7 +626,6 @@ PetscErrorCode VecMDot_SeqKokkos_GEMV(Vec xin, PetscInt nv, const Vec yin[], Pet { PetscFunctionBegin; PetscCall(VecMultiDot_SeqKokkos_GEMV(PETSC_TRUE, xin, nv, yin, z)); // conjugate - PetscCall(PetscLogGpuToCpu(nv * sizeof(PetscScalar))); // for copying to z[] on host PetscFunctionReturn(PETSC_SUCCESS); } @@ -624,7 +633,6 @@ PetscErrorCode VecMTDot_SeqKokkos_GEMV(Vec xin, PetscInt nv, const Vec yin[], Pe { PetscFunctionBegin; PetscCall(VecMultiDot_SeqKokkos_GEMV(PETSC_FALSE, xin, nv, yin, z)); // transpose - PetscCall(PetscLogGpuToCpu(nv * sizeof(PetscScalar))); // for copying to z[] on host PetscFunctionReturn(PETSC_SUCCESS); } @@ -699,16 +707,17 @@ PetscErrorCode VecCopy_SeqKokkos(Vec xin, Vec yin) clear y's sync state. */ ykok->v_dual.clear_sync_state(); - PetscCallCXX(Kokkos::deep_copy(exec, ykok->v_dual, xkok->v_dual)); + PetscCallCXX(Kokkos::deep_copy(exec, ykok->v_dual, xkok->v_dual)); // either cpu2cpu or gpu2cpu, so don't log it } else { PetscScalar *yarray; PetscCall(VecGetArrayWrite(yin, &yarray)); PetscScalarKokkosViewHost yv(yarray, yin->map->n); - if (xkok->v_dual.need_sync_host()) { /* x's device has newer data */ - PetscCallCXX(Kokkos::deep_copy(exec, yv, xkok->v_dual.view_device())); - exec.fence(); // finish the deep copy + if (xkok->v_dual.need_sync_host()) { // x's device has newer data + PetscCallCXX(Kokkos::deep_copy(exec, yv, xkok->v_dual.view_device())); // gpu2cpu + PetscCallCXX(exec.fence()); // finish the deep copy + PetscCall(PetscLogGpuToCpu(xkok->v_dual.extent(0) * sizeof(PetscScalar))); } else { - PetscCallCXX(Kokkos::deep_copy(exec, yv, xkok->v_dual.view_host())); + PetscCallCXX(Kokkos::deep_copy(exec, yv, xkok->v_dual.view_host())); // cpu2cpu } PetscCall(VecRestoreArrayWrite(yin, &yarray)); } @@ -897,6 +906,7 @@ PetscErrorCode VecMAXPY_SeqKokkos_GEMV(Vec yin, PetscInt nv, const PetscScalar * auto av = PetscScalarKokkosDualView(PetscScalarKokkosView(a_d + i, m), PetscScalarKokkosViewHost(const_cast(a_h) + i, m)); av.modify_host(); av.sync_device(); + PetscCall(PetscLogCpuToGpu(av.extent(0) * sizeof(PetscScalar))); PetscCallCXX(KokkosBlas::gemv(PetscGetKokkosExecutionSpace(), "N", 1.0, A, av.view_device(), 1.0, yv)); PetscCall(PetscLogGpuFlops(m * 2.0 * n)); } else { @@ -1274,11 +1284,10 @@ PetscErrorCode VecResetArray_SeqKokkos(Vec vin) { Vec_Seq *vecseq = (Vec_Seq *)vin->data; Vec_Kokkos *veckok = static_cast(vin->spptr); - auto &exec = PetscGetKokkosExecutionSpace(); PetscFunctionBegin; - PetscCallCXX(veckok->v_dual.sync_host(exec)); /* User wants to unhook the provided host array. Sync it so that user can get the latest */ - PetscCallCXX(exec.fence()); + /* User wants to unhook the provided host array. Sync it so that user can get the latest */ + PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); PetscCall(VecResetArray_Seq(vin)); /* Swap back the old host array, assuming its has the latest value */ PetscCall(veckok->UpdateArray(vecseq->array)); PetscFunctionReturn(PETSC_SUCCESS); @@ -1292,11 +1301,7 @@ PetscErrorCode VecReplaceArray_SeqKokkos(Vec vin, const PetscScalar *a) PetscFunctionBegin; /* Make sure the users array has the latest values */ - if (vecseq->array != vecseq->array_allocated) { - auto &exec = PetscGetKokkosExecutionSpace(); - PetscCallCXX(veckok->v_dual.sync_host(exec)); - PetscCallCXX(exec.fence()); - } + if (vecseq->array != vecseq->array_allocated) PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); PetscCall(VecReplaceArray_Seq(vin, a)); PetscCall(veckok->UpdateArray(vecseq->array)); PetscFunctionReturn(PETSC_SUCCESS); @@ -1340,11 +1345,9 @@ PetscErrorCode VecRestoreLocalVector_SeqKokkos(Vec v, Vec w) PetscErrorCode VecGetArray_SeqKokkos(Vec v, PetscScalar **a) { Vec_Kokkos *veckok = static_cast(v->spptr); - auto &exec = PetscGetKokkosExecutionSpace(); PetscFunctionBegin; - PetscCallCXX(veckok->v_dual.sync_host(exec)); - PetscCallCXX(exec.fence()); // make sure the array is ready for access after the call + PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); *a = *((PetscScalar **)v->data); PetscFunctionReturn(PETSC_SUCCESS); } @@ -1372,18 +1375,12 @@ PetscErrorCode VecGetArrayWrite_SeqKokkos(Vec v, PetscScalar **a) PetscErrorCode VecGetArrayAndMemType_SeqKokkos(Vec v, PetscScalar **a, PetscMemType *mtype) { Vec_Kokkos *veckok = static_cast(v->spptr); - auto &exec = PetscGetKokkosExecutionSpace(); PetscFunctionBegin; - if (std::is_same::value) { - *a = veckok->v_dual.view_host().data(); - if (mtype) *mtype = PETSC_MEMTYPE_HOST; - } else { - /* When there is device, we always return up-to-date device data */ - PetscCallCXX(veckok->v_dual.sync_device(exec)); - *a = veckok->v_dual.view_device().data(); - if (mtype) *mtype = PETSC_MEMTYPE_KOKKOS; - } + /* Always return up-to-date in the default memory space */ + PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); + *a = veckok->v_dual.view_device().data(); + if (mtype) *mtype = PETSC_MEMTYPE_KOKKOS; // Could be PETSC_MEMTYPE_HOST when Kokkos was not configured with cuda etc. PetscFunctionReturn(PETSC_SUCCESS); } @@ -1405,15 +1402,11 @@ PetscErrorCode VecGetArrayWriteAndMemType_SeqKokkos(Vec v, PetscScalar **a, Pets Vec_Kokkos *veckok = static_cast(v->spptr); PetscFunctionBegin; - if (std::is_same::value) { - *a = veckok->v_dual.view_host().data(); - if (mtype) *mtype = PETSC_MEMTYPE_HOST; - } else { - /* When there is device, we always return device data (but no need to sync the device) */ - PetscCallCXX(veckok->v_dual.clear_sync_state()); /* So that in restore, we can safely modify_device() */ - *a = veckok->v_dual.view_device().data(); - if (mtype) *mtype = PETSC_MEMTYPE_KOKKOS; - } + // Since the data will be overwritten, we clear the sync state to suppress potential memory copying in sync'ing + PetscCallCXX(veckok->v_dual.clear_sync_state()); // So that in restore, we can safely modify_device() + PetscCall(KokkosDualViewSync(veckok->v_dual, PetscGetKokkosExecutionSpace())); + *a = veckok->v_dual.view_device().data(); + if (mtype) *mtype = PETSC_MEMTYPE_KOKKOS; // Could be PETSC_MEMTYPE_HOST when Kokkos was not configured with cuda etc. PetscFunctionReturn(PETSC_SUCCESS); } @@ -1509,12 +1502,12 @@ PetscErrorCode VecRestoreSubVector_SeqKokkos(Vec x, IS is, Vec *y) /* The tricky part: one has to carefully sync the arrays */ auto &exec = PetscGetKokkosExecutionSpace(); - if (xkok->v_dual.need_sync_device()) { /* x's host has newer data */ - PetscCallCXX(ykok->v_dual.sync_host(exec)); /* Move y's latest values to host (since y is just a subset of x) */ - PetscCallCXX(exec.fence()); - } else if (xkok->v_dual.need_sync_host()) { /* x's device has newer data */ - PetscCallCXX(ykok->v_dual.sync_device(exec)); /* Move y's latest data to device */ - } else { /* x's host and device data is already sync'ed; Copy y's sync state to x */ + if (xkok->v_dual.need_sync_device()) { /* x's host has newer data */ + /* Move y's latest values to host (since y is just a subset of x) */ + PetscCall(KokkosDualViewSync(ykok->v_dual, exec)); + } else if (xkok->v_dual.need_sync_host()) { /* x's device has newer data */ + PetscCall(KokkosDualViewSync(ykok->v_dual, exec)); /* Move y's latest data to device */ + } else { /* x's host and device data is already sync'ed; Copy y's sync state to x */ PetscCall(VecCopySyncState_Kokkos_Private(*y, x)); } PetscCall(PetscObjectStateIncrease((PetscObject)x)); /* Since x is updated */ diff --git a/src/vec/vec/interface/rvector.c b/src/vec/vec/interface/rvector.c index 3c4705f2358..44c1624d4e6 100644 --- a/src/vec/vec/interface/rvector.c +++ b/src/vec/vec/interface/rvector.c @@ -216,7 +216,7 @@ PetscErrorCode VecNorm(Vec x, NormType type, PetscReal *val) b1[0] = -(*val); b1[1] = *val; PetscCallMPI(MPIU_Allreduce(b1, b2, 2, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)x))); - PetscCheck(-b2[0] == b2[1], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Difference in cached %s norms: local %g", NormTypes[type], (double)*val); + PetscCheck((PetscIsNanReal(b2[0]) && PetscIsNanReal(b2[1])) || (-b2[0] == b2[1]), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Difference in cached %s norms: local %g", NormTypes[type], (double)*val); } } if (flg) PetscFunctionReturn(PETSC_SUCCESS); diff --git a/src/vec/vec/utils/projection.c b/src/vec/vec/utils/projection.c index a80f5feda63..448aedbd55b 100644 --- a/src/vec/vec/utils/projection.c +++ b/src/vec/vec/utils/projection.c @@ -966,7 +966,7 @@ PetscErrorCode VecStepMax(Vec X, Vec DX, PetscReal *step) } /*@ - VecPow - Replaces each component of a vector by x_i^p + VecPow - Replaces each component of a vector by $ x_i^p $ Logically Collective @@ -976,6 +976,10 @@ PetscErrorCode VecStepMax(Vec X, Vec DX, PetscReal *step) Level: intermediate + Note: + This handles negative values, Inf, and Nan in the expected IEEE floating pointing manner. For example, the square root of a negative real number is Nan + and 1/0.0 is Inf. + .seealso: `Vec` @*/ PetscErrorCode VecPow(Vec v, PetscScalar p) @@ -996,36 +1000,18 @@ PetscErrorCode VecPow(Vec v, PetscScalar p) for (i = 0; i < n; ++i) { /* Not-a-number left alone Infinity set to one */ - if (v1[i] == v1[i]) v1[i] = 1.0; + if (!PetscIsNanScalar(v1[i])) v1[i] = 1.0; } } else if (0.5 == p) { - for (i = 0; i < n; ++i) { - if (PetscRealPart(v1[i]) >= 0) { - v1[i] = PetscSqrtScalar(v1[i]); - } else { - v1[i] = PETSC_INFINITY; - } - } + for (i = 0; i < n; ++i) { v1[i] = PetscSqrtScalar(v1[i]); } } else if (-0.5 == p) { - for (i = 0; i < n; ++i) { - if (PetscRealPart(v1[i]) >= 0) { - v1[i] = 1.0 / PetscSqrtScalar(v1[i]); - } else { - v1[i] = PETSC_INFINITY; - } - } + for (i = 0; i < n; ++i) { v1[i] = 1.0 / PetscSqrtScalar(v1[i]); } } else if (2.0 == p) { for (i = 0; i < n; ++i) v1[i] *= v1[i]; } else if (-2.0 == p) { for (i = 0; i < n; ++i) v1[i] = 1.0 / (v1[i] * v1[i]); } else { - for (i = 0; i < n; ++i) { - if (PetscRealPart(v1[i]) >= 0) { - v1[i] = PetscPowScalar(v1[i], p); - } else { - v1[i] = PETSC_INFINITY; - } - } + for (i = 0; i < n; ++i) { v1[i] = PetscPowScalar(v1[i], p); } } PetscCall(VecRestoreArray(v, &v1)); PetscFunctionReturn(PETSC_SUCCESS);