xref: /petsc/src/sys/utils/memc.c (revision bfcb38ea38335faa6e7f8d97f6bc6ce9aa2a1dd1)
1 
2 /*
3     We define the memory operations here. The reason we just do not use
4   the standard memory routines in the PETSc code is that on some machines
5   they are broken.
6 
7 */
8 #include <petscsys.h>        /*I  "petscsys.h"   I*/
9 #include <petscbt.h>
10 #include <../src/sys/utils/ftn-kernels/fcopy.h>
11 #if defined(PETSC_HAVE_STRING_H)
12 #include <string.h>
13 #endif
14 
15 /*@
16    PetscMemcmp - Compares two byte streams in memory.
17 
18    Not Collective
19 
20    Input Parameters:
21 +  str1 - Pointer to the first byte stream
22 .  str2 - Pointer to the second byte stream
23 -  len  - The length of the byte stream
24          (both str1 and str2 are assumed to be of length len)
25 
26    Output Parameters:
27 .   e - PETSC_TRUE if equal else PETSC_FALSE.
28 
29    Level: intermediate
30 
31    Note:
32    This routine is anologous to memcmp()
33 @*/
34 PetscErrorCode  PetscMemcmp(const void *str1,const void *str2,size_t len,PetscBool  *e)
35 {
36   int r;
37 
38   PetscFunctionBegin;
39   if (len > 0 && !str1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
40   if (len > 0 && !str2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
41   r = memcmp((char*)str1,(char*)str2,len);
42   if (!r) *e = PETSC_TRUE;
43   else    *e = PETSC_FALSE;
44   PetscFunctionReturn(0);
45 }
46 
47 /*@
48    PetscMemmove - Copies n bytes, beginning at location b, to the space
49    beginning at location a. Copying  between regions that overlap will
50    take place correctly.
51 
52    Not Collective
53 
54    Input Parameters:
55 +  b - pointer to initial memory space
56 -  n - length (in bytes) of space to copy
57 
58    Output Parameter:
59 .  a - pointer to copy space
60 
61    Level: intermediate
62 
63    Note:
64    This routine is analogous to memmove().
65 
66    Since b can overlap with a, b cannot be declared as const
67 
68    Concepts: memory^copying with overlap
69    Concepts: copying^memory with overlap
70 
71 .seealso: PetscMemcpy()
72 @*/
73 PetscErrorCode  PetscMemmove(void *a,void *b,size_t n)
74 {
75   PetscFunctionBegin;
76   if (n > 0 && !a) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy to null pointer");
77   if (n > 0 && !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
78 #if !defined(PETSC_HAVE_MEMMOVE)
79   if (a < b) {
80     if (a <= b - n) memcpy(a,b,n);
81     else {
82       memcpy(a,b,(int)(b - a));
83       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
84     }
85   } else {
86     if (b <= a - n) memcpy(a,b,n);
87     else {
88       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
89       PetscMemmove(a,b,n - (int)(a - b));
90     }
91   }
92 #else
93   memmove((char*)(a),(char*)(b),n);
94 #endif
95   PetscFunctionReturn(0);
96 }
97 
98 #if defined(PETSC_HAVE_HWLOC)
99 #include <petsc/private/petscimpl.h>
100 #include <hwloc.h>
101 
102 /*@C
103      PetscProcessPlacementView - display the MPI process placement by core
104 
105   Input Parameter:
106 .   viewer - ASCII viewer to display the results on
107 
108   Level: intermediate
109 
110   Notes:
111     Requires that PETSc be installed with hwloc, for example using --download-hwloc
112 @*/
113 PetscErrorCode PetscProcessPlacementView(PetscViewer viewer)
114 {
115   PetscErrorCode   ierr;
116   PetscBool        isascii;
117   PetscMPIInt      rank;
118   hwloc_bitmap_t   set;
119   hwloc_topology_t topology;
120   int              err;
121 
122   PetscFunctionBegin;
123   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
124   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
125   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only ASCII viewer is supported");
126 
127   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr);
128   hwloc_topology_init ( &topology);
129   hwloc_topology_load ( topology);
130   set = hwloc_bitmap_alloc();
131 
132   err = hwloc_get_proc_cpubind(topology, getpid(), set, HWLOC_CPUBIND_PROCESS);
133   if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error %d from hwloc_get_proc_cpubind()",err);
134   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
135   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"MPI rank %d Process id: %d coreid %d\n",rank,getpid(),hwloc_bitmap_first(set));CHKERRQ(ierr);
136   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
137   hwloc_bitmap_free(set);
138   hwloc_topology_destroy(topology);
139   PetscFunctionReturn(0);
140 }
141 #endif
142 
143