xref: /petsc/src/sys/utils/memc.c (revision 8e3e01fc0d569b6af103fd34c478fc7e3dd65835)
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 #undef __FUNCT__
103 #define __FUNCT__ "PetscProcessPlacementView"
104 /*@C
105      PetscProcessPlacementView - display the MPI process placement by core
106 
107   Input Parameter:
108 .   viewer - ASCII viewer to display the results on
109 
110   Notes: Requires that PETSc be installed with hwloc, for example using --download-hwloc
111 @*/
112 PetscErrorCode PetscProcessPlacementView(PetscViewer viewer)
113 {
114   PetscErrorCode   ierr;
115   PetscBool        isascii;
116   PetscMPIInt      rank;
117   hwloc_bitmap_t   set;
118   hwloc_topology_t topology;
119   int              err;
120 
121   PetscFunctionBegin;
122   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
123   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
124   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only ASCII viewer is supported");
125 
126   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank);CHKERRQ(ierr);
127   hwloc_topology_init ( &topology);
128   hwloc_topology_load ( topology);
129   set = hwloc_bitmap_alloc();
130 
131   err = hwloc_get_proc_cpubind(topology, getpid(), set, HWLOC_CPUBIND_PROCESS);
132   if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error %d from hwloc_get_proc_cpubind()",err);
133   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
134   ierr = PetscViewerASCIISynchronizedPrintf(viewer,"MPI rank %d Process id: %d coreid %d\n",rank,getpid(),hwloc_bitmap_first(set));CHKERRQ(ierr);
135   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
136   hwloc_bitmap_free(set);
137   hwloc_topology_destroy(topology);
138   PetscFunctionReturn(0);
139 }
140 #endif
141 
142