00001
00013 #include "converse.h"
00014 #include "sockRoutines.h"
00015 #define DEBUGP(x)
00016 CpvExtern(int, myCPUAffToCore);
00017 #if CMK_HAS_NUMACTRL
00018 #define _GNU_SOURCE
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <unistd.h>
00022 #include <linux/mempolicy.h>
00023 #include <numaif.h>
00024 #include <numa.h>
00025 #include <string.h>
00026 #include <sched.h>
00027 #include <math.h>
00028 #include <dirent.h>
00029 #include <sys/types.h>
00030 typedef unsigned long mem_aff_mask;
00031 static void MEM_MASK_ZERO(mem_aff_mask *mem_mask) {
00032 memset(mem_mask, 0, sizeof(mem_aff_mask));
00033 }
00034 static void MEM_MASK_SET(int nid, mem_aff_mask *mem_mask) {
00035 *mem_mask = *mem_mask | (1<<nid);
00036 }
00037 static void MEM_MASK_CLEAR(int nid, mem_aff_mask *mem_mask) {
00038 *mem_mask = *mem_mask & (~(1<<nid));
00039 }
00040 int print_mem_affinity(void) {
00041 mem_aff_mask mask;
00042 unsigned int len = 8*sizeof(mask);
00043 char spol[16];
00044 int policy;
00045 spol[0]='\0';
00046
00047 if ((get_mempolicy(&policy,&mask,len,0,0)) < 0) {
00048 perror("mem_getaffinity");
00049 return -1;
00050 }
00051 if (policy == MPOL_INTERLEAVE)
00052 strcpy(spol,"INTERLEAVE");
00053 else if (policy == MPOL_BIND)
00054 strcpy(spol,"BIND");
00055 else
00056 strcpy(spol,"PREFERRED");
00057 CmiPrintf("%d: Mem affinity mask is: %08lx with policy %s\n", CmiMyPe(),mask,spol);
00058 return 0;
00059 }
00060 static int CmiNumNUMANodes(void) {
00061 return numa_max_node()+1;
00062 }
00063 static int getNUMANidByRank(int coreid) {
00064 int i;
00065
00066 int totalNUMANodes = CmiNumNUMANodes();
00067
00068
00069
00070
00071
00072 char nodeStr[256];
00073 DIR* nodeDir;
00074 struct dirent* nodeDirEnt;
00075 int cpuid = -1;
00076 for (i=0; i<totalNUMANodes; i++) {
00077 snprintf(nodeStr, 256, "/sys/devices/system/node/node%d", i);
00078 nodeDir = opendir(nodeStr);
00079 if (nodeDir) {
00080 while ((nodeDirEnt = readdir(nodeDir))) {
00081 if (sscanf(nodeDirEnt->d_name, "cpu%d", &cpuid) == 1) {
00082 if(cpuid == coreid) {
00083 closedir(nodeDir);
00084 return i;
00085 }
00086 }
00087 }
00088 closedir(nodeDir);
00089 }
00090 }
00091
00092 CmiPrintf("%d: the corresponding NUMA node for cpu id %d is not found!\n", CmiMyPe(), coreid);
00093 CmiAssert(0);
00094 return -1;
00095 }
00096
00102 int CmiSetMemAffinity(int policy, int *nids, int len) {
00103 int i;
00104 mem_aff_mask myMask;
00105 unsigned int masksize = 8*sizeof(mem_aff_mask);
00106 MEM_MASK_ZERO(&myMask);
00107 for (i=0; i<len; i++) MEM_MASK_SET(nids[i], &myMask);
00108 if (set_mempolicy(policy, &myMask, masksize)<0) {
00109 CmiPrintf("Error> setting memory policy (%d) error with mask %X\n", policy, myMask);
00110 return -1;
00111 } else
00112 return 0;
00113 }
00114 void CmiInitMemAffinity(char **argv) {
00115
00116 int i;
00117 int policy=-1;
00118
00119 int maffinity_flag = CmiGetArgFlagDesc(argv, "+maffinity", "memory affinity");
00120
00121
00122 char *nodemap = NULL;
00123
00124 char *mpol = NULL;
00125 CmiGetArgStringDesc(argv, "+memnodemap", &nodemap, "define memory node mapping");
00126 CmiGetArgStringDesc(argv, "+mempol", &mpol, "define memory policy {bind, preferred or interleave} ");
00127
00128
00129 if (!maffinity_flag) return;
00130
00131
00139 if (CmiMyPe() >= CmiNumPes()) {
00140 CmiNodeAllBarrier();
00141 return;
00142 }
00143
00144
00145 if (CpvInitialized(myCPUAffToCore) && CpvAccess(myCPUAffToCore)==-1) {
00146 if (CmiMyPe()==0)
00147 CmiPrintf("Charm++> memory affinity disabled because cpu affinity is not enabled!\n");
00148 CmiNodeAllBarrier();
00149 return;
00150 }
00151
00152 if (CmiMyPe()==0) {
00153 CmiPrintf("Charm++> memory affinity enabled! \n");
00154 }
00155
00156
00157 if (mpol==NULL) {
00158 CmiAbort("Memory policy must be specified!\n");
00159 }
00160 if (strcmp(mpol, "interleave")==0) policy = MPOL_INTERLEAVE;
00161 else if (strcmp(mpol, "preferred")==0) policy = MPOL_PREFERRED;
00162 else if (strcmp(mpol, "bind")==0) policy = MPOL_BIND;
00163 else {
00164 CmiPrintf("Error> Invalid memory policy :%s\n", mpol);
00165 CmiAbort("Invalid memory policy!");
00166 }
00167
00174 if (nodemap!=NULL) {
00175 int *nodemapArr = NULL;
00176 int nodemapArrSize = 1;
00177 int prevIntStart,j;
00178 int curnid;
00179 int myPhyRank = CpvAccess(myCPUAffToCore);
00180 int myMemNid;
00181 int retval = -1;
00182 for (i=0; i<strlen((const char *)nodemap); i++) {
00183 if (nodemap[i]==',') nodemapArrSize++;
00184 }
00185 nodemapArr = malloc(nodemapArrSize*sizeof(int));
00186 prevIntStart=j=0;
00187 for (i=0; i<strlen((const char *)nodemap); i++) {
00188 if (nodemap[i]==',') {
00189 curnid = atoi(nodemap+prevIntStart);
00190 if (curnid >= CmiNumNUMANodes()) {
00191 CmiPrintf("Error> Invalid node number %d, only have %d nodes (0-%d) on the machine. \n", curnid, CmiNumNUMANodes(), CmiNumNUMANodes()-1);
00192 CmiAbort("Invalid node number!");
00193 }
00194 nodemapArr[j++] = curnid;
00195 prevIntStart=i+1;
00196 }
00197 }
00198
00199 curnid = atoi(nodemap+prevIntStart);
00200 if (curnid >= CmiNumNUMANodes()) {
00201 CmiPrintf("Error> Invalid node number %d, only have %d nodes (0-%d) on the machine. \n", curnid, CmiNumNUMANodes(), CmiNumNUMANodes()-1);
00202 CmiAbort("Invalid node number!");
00203 }
00204 nodemapArr[j] = curnid;
00205
00206 myMemNid = nodemapArr[myPhyRank%nodemapArrSize];
00207 if (policy==MPOL_INTERLEAVE) {
00208 retval = CmiSetMemAffinity(policy, nodemapArr, nodemapArrSize);
00209 } else {
00210 retval = CmiSetMemAffinity(policy, &myMemNid, 1);
00211 }
00212 if (retval<0) {
00213 CmiAbort("set_mempolicy error w/ mem nodemap");
00214 }
00215 free(nodemapArr);
00216 } else {
00217
00218 int myPhyRank = CpvAccess(myCPUAffToCore);
00219
00220 int myMemNid = getNUMANidByRank(myPhyRank);
00221
00222 int retval=-1;
00223 if (policy==MPOL_INTERLEAVE) {
00224 int totalNUMANodes = CmiNumNUMANodes();
00225 int *nids = (int *)malloc(totalNUMANodes*sizeof(int));
00226 for (i=0; i<totalNUMANodes; i++) nids[i] = i;
00227 retval = CmiSetMemAffinity(policy, nids, totalNUMANodes);
00228 free(nids);
00229 } else {
00230 retval = CmiSetMemAffinity(policy, &myMemNid, 1);
00231 }
00232 if (retval<0) {
00233 CmiAbort("set_mempolicy error w/o mem nodemap");
00234 }
00235 }
00236
00237
00238 CmiNodeAllBarrier();
00239 }
00240 #else
00241 void CmiInitMemAffinity(char **argv) {
00242 char *tmpstr = NULL;
00243 int maffinity_flag = CmiGetArgFlagDesc(argv,"+maffinity",
00244 "memory affinity");
00245 if (maffinity_flag && CmiMyPe()==0)
00246 CmiPrintf("memory affinity is not supported, +maffinity flag disabled.\n");
00247
00248
00249 CmiGetArgStringDesc(argv, "+memnodemap", &tmpstr, "define memory node mapping");
00250 CmiGetArgStringDesc(argv, "+mempol", &tmpstr, "define memory policy {bind, preferred or interleave} ");
00251 }
00252 #endif
00253