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 typedef unsigned long mem_aff_mask;
00029 static void MEM_MASK_ZERO(mem_aff_mask *mem_mask) {
00030 memset(mem_mask, 0, sizeof(mem_aff_mask));
00031 }
00032 static void MEM_MASK_SET(int nid, mem_aff_mask *mem_mask) {
00033 *mem_mask = *mem_mask | (1<<nid);
00034 }
00035 static void MEM_MASK_CLEAR(int nid, mem_aff_mask *mem_mask) {
00036 *mem_mask = *mem_mask & (~(1<<nid));
00037 }
00038 int print_mem_affinity() {
00039 mem_aff_mask mask;
00040 unsigned int len = 8*sizeof(mask);
00041 char spol[16];
00042 int policy;
00043 spol[0]='\0';
00044
00045 if ((get_mempolicy(&policy,&mask,len,0,0)) < 0) {
00046 perror("mem_getaffinity");
00047 return -1;
00048 }
00049 if (policy == MPOL_INTERLEAVE)
00050 strcpy(spol,"INTERLEAVE");
00051 else if (policy == MPOL_BIND)
00052 strcpy(spol,"BIND");
00053 else
00054 strcpy(spol,"PREFERRED");
00055 CmiPrintf("%d: Mem affinity mask is: %08lx with policy %s\n", CmiMyPe(),mask,spol);
00056 return 0;
00057 }
00058 static int CmiNumNUMANodes(void) {
00059 FILE *fp_nodes;
00060 int max_node=-1;
00061 char command[]="ls -1d /sys/devices/system/node/node*|wc|awk '{print $1}'";
00062 fp_nodes = popen(command,"r");
00063 fscanf(fp_nodes,"%d",&max_node);
00064 pclose(fp_nodes);
00065 return max_node;
00066 }
00067 static int getNUMANidByRank(int coreid) {
00068 int i;
00069
00070 int totalNUMANodes = CmiNumNUMANodes();
00071
00072
00073
00074
00075
00076 char command[256];
00077 for (i=0; i<totalNUMANodes; i++) {
00078 FILE *cmd;
00079 int cpuid;
00080 sprintf(command, "ls -1d /sys/devices/system/node/node%d/cpu[0-9]* | cut -d'u' -f2", i);
00081 cmd = popen(command, "r");
00082 while (1) {
00083 int ret=fscanf(cmd, "%d\n", &cpuid);
00084 if (ret==EOF) break;
00085 if (cpuid == coreid) {
00086 pclose(cmd);
00087
00088 return i;
00089 }
00090 }
00091 pclose(cmd);
00092 }
00093
00094 CmiPrintf("%d: the corresponding NUMA node for cpu id %d is not found!\n", CmiMyPe(), coreid);
00095 CmiAssert(0);
00096 return -1;
00097 }
00098
00104 int CmiSetMemAffinity(int policy, int *nids, int len) {
00105 int i;
00106 mem_aff_mask myMask;
00107 unsigned int masksize = 8*sizeof(mem_aff_mask);
00108 MEM_MASK_ZERO(&myMask);
00109 for (i=0; i<len; i++) MEM_MASK_SET(nids[i], &myMask);
00110 if (set_mempolicy(policy, &myMask, masksize)<0) {
00111 CmiPrintf("Error> setting memory policy (%d) error with mask %X\n", policy, myMask);
00112 return -1;
00113 } else
00114 return 0;
00115 }
00116 void CmiInitMemAffinity(char **argv) {
00117
00118 int i;
00119 int policy=-1;
00120
00121 int maffinity_flag = CmiGetArgFlagDesc(argv, "+maffinity", "memory affinity");
00122
00123
00124 char *nodemap = NULL;
00125
00126 char *mpol = NULL;
00127 CmiGetArgStringDesc(argv, "+memnodemap", &nodemap, "define memory node mapping");
00128 CmiGetArgStringDesc(argv, "+mempol", &mpol, "define memory policy {bind, preferred or interleave} ");
00129
00130
00131 if (!maffinity_flag) return;
00132
00133
00141 if (CmiMyPe() >= CmiNumPes()) {
00142 CmiNodeAllBarrier();
00143 return;
00144 }
00145
00146
00147 if (CpvInitialized(myCPUAffToCore) && CpvAccess(myCPUAffToCore)==-1) {
00148 if (CmiMyPe()==0)
00149 CmiPrintf("Charm++> memory affinity disabled because cpu affinity is not enabled!\n");
00150 CmiNodeAllBarrier();
00151 return;
00152 }
00153
00154 if (CmiMyPe()==0) {
00155 CmiPrintf("Charm++> memory affinity enabled! \n");
00156 }
00157
00158
00159 if (mpol==NULL) {
00160 CmiAbort("Memory policy must be specified!\n");
00161 }
00162 if (strcmp(mpol, "interleave")==0) policy = MPOL_INTERLEAVE;
00163 else if (strcmp(mpol, "preferred")==0) policy = MPOL_PREFERRED;
00164 else if (strcmp(mpol, "bind")==0) policy = MPOL_BIND;
00165 else {
00166 CmiPrintf("Error> Invalid memory policy :%s\n", mpol);
00167 CmiAbort("Invalid memory policy!");
00168 }
00169
00176 if (nodemap!=NULL) {
00177 int *nodemapArr = NULL;
00178 int nodemapArrSize = 1;
00179 int prevIntStart,j;
00180 int curnid;
00181 for (i=0; i<strlen((const char *)nodemap); i++) {
00182 if (nodemap[i]==',') nodemapArrSize++;
00183 }
00184 nodemapArr = malloc(nodemapArrSize*sizeof(int));
00185 prevIntStart=j=0;
00186 for (i=0; i<strlen((const char *)nodemap); i++) {
00187 if (nodemap[i]==',') {
00188 curnid = atoi(nodemap+prevIntStart);
00189 if (curnid >= CmiNumNUMANodes()) {
00190 CmiPrintf("Error> Invalid node number %d, only have %d nodes (0-%d) on the machine. \n", curnid, CmiNumNUMANodes(), CmiNumNUMANodes()-1);
00191 CmiAbort("Invalid node number!");
00192 }
00193 nodemapArr[j++] = curnid;
00194 prevIntStart=i+1;
00195 }
00196 }
00197
00198 curnid = atoi(nodemap+prevIntStart);
00199 if (curnid >= CmiNumNUMANodes()) {
00200 CmiPrintf("Error> Invalid node number %d, only have %d nodes (0-%d) on the machine. \n", curnid, CmiNumNUMANodes(), CmiNumNUMANodes()-1);
00201 CmiAbort("Invalid node number!");
00202 }
00203 nodemapArr[j] = curnid;
00204
00205 int myPhyRank = CpvAccess(myCPUAffToCore);
00206 int myMemNid = nodemapArr[myPhyRank%nodemapArrSize];
00207 int retval = -1;
00208 if (policy==MPOL_INTERLEAVE) {
00209 retval = CmiSetMemAffinity(policy, nodemapArr, nodemapArrSize);
00210 } else {
00211 retval = CmiSetMemAffinity(policy, &myMemNid, 1);
00212 }
00213 if (retval<0) {
00214 CmiAbort("set_mempolicy error w/ mem nodemap");
00215 }
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