00001
00002
00003
00004
00005 #include <string.h>
00006 #include "ampiimpl.h"
00007
00008 #if defined(_WIN32)
00009 #include <windows.h>
00010 #include <sstream>
00011 #include <direct.h>
00012 #include <stdlib.h>
00013 #define getcwd _getcwd
00014 #else
00015 #include <sys/utsname.h>
00016 #include <unistd.h>
00017 #endif
00018
00019
00020 std::string create_stripped_string(const char *str) noexcept {
00021 int newLen;
00022 int len = strlen(str);
00023
00024 int start=0;
00025 while((start<len) && (str[start]==' ')){
00026 start++;
00027 }
00028
00029 if(start>=len){
00030 newLen=0;
00031 }else{
00032 int end=len-1;
00033 while((end>start) && (str[end]==' ')){
00034 end--;
00035 }
00036 newLen = end - start+1;
00037 }
00038
00039 if(newLen==0){
00040 return std::string();
00041 }else{
00042 std::string newStr(&str[start], newLen);
00043 return newStr;
00044 }
00045 }
00046
00047 KeyvalPair::KeyvalPair(const char* k, const char* v) noexcept {
00048 key = create_stripped_string(k);
00049 val = create_stripped_string(v);
00050 }
00051
00052 void InfoStruct::pup(PUP::er& p) noexcept {
00053 p|nodes;
00054 p|valid;
00055 }
00056
00057 int InfoStruct::set(const char* k, const char* v) noexcept {
00058 std::string key = create_stripped_string(k);
00059 for(int i=0;i<nodes.size();i++){
00060 if(nodes[i]->key == key){
00061 nodes[i]->val.clear();
00062 nodes[i]->val = create_stripped_string(v);
00063 return MPI_SUCCESS;
00064 }
00065 }
00066
00067 KeyvalPair* newkvp = new KeyvalPair(k,v);
00068 nodes.push_back(newkvp);
00069 return MPI_SUCCESS;
00070 }
00071
00072 int InfoStruct::dup(InfoStruct& src) noexcept {
00073 for(int i=0;i<nodes.size();i++){
00074 KeyvalPair* newkvp = new KeyvalPair(src.nodes[i]->key.c_str(), src.nodes[i]->val.c_str());
00075 nodes.push_back(newkvp);
00076 }
00077 return MPI_SUCCESS;
00078 }
00079
00080 int InfoStruct::deletek(const char* k) noexcept {
00081 std::string key = create_stripped_string(k);
00082 for(int i=0;i<nodes.size();i++){
00083 if(nodes[i]->key == key){
00084 delete nodes[i];
00085 nodes.remove(i);
00086 return MPI_SUCCESS;
00087 }
00088 }
00089 return MPI_ERR_INFO_KEY;
00090 }
00091
00092 int InfoStruct::get(const char* k, int vl, char*& v, int *flag) const noexcept {
00093 std::string key = create_stripped_string(k);
00094 for(int i=0;i<nodes.size();i++){
00095 if(nodes[i]->key == key){
00096 strncpy(v, nodes[i]->val.c_str(), vl);
00097 if(vl<strlen(nodes[i]->val.c_str()))
00098 v[vl]='\0';
00099 *flag=1;
00100 return MPI_SUCCESS;
00101 }
00102 }
00103 *flag=0;
00104 return MPI_ERR_INFO_KEY;
00105 }
00106
00107 int InfoStruct::get_valuelen(const char* k, int* vl, int *flag) const noexcept {
00108 std::string key = create_stripped_string(k);
00109 for(int i=0;i<nodes.size();i++){
00110 if(nodes[i]->key == key){
00111 *vl=strlen(nodes[i]->val.c_str());
00112 *flag=1;
00113 return MPI_SUCCESS;
00114 }
00115 }
00116 *flag=0;
00117 return MPI_ERR_INFO_KEY;
00118 }
00119
00120 int InfoStruct::get_nkeys(int *n) const noexcept {
00121 *n = nodes.size();
00122 return MPI_SUCCESS;
00123 }
00124
00125 int InfoStruct::get_nthkey(int n, char* k) const noexcept {
00126 #if AMPI_ERROR_CHECKING
00127 if(n<0 || n>=nodes.size())
00128 return MPI_ERR_INFO_KEY;
00129 #endif
00130 strcpy(k,nodes[n]->key.c_str());
00131 return MPI_SUCCESS;
00132 }
00133
00134 void InfoStruct::myfree() noexcept {
00135 for(int i=0;i<nodes.size();i++){
00136 delete nodes[i];
00137 }
00138 nodes.resize(0);
00139 valid=false;
00140 }
00141
00142 int ampiParent::createInfo(MPI_Info *newinfo) noexcept {
00143 #if AMPI_ERROR_CHECKING
00144 if(newinfo==NULL)
00145 return MPI_ERR_INFO;
00146 #endif
00147 InfoStruct* newInfoStruct = new InfoStruct;
00148 infos.push_back(newInfoStruct);
00149 *newinfo = (MPI_Info)(infos.size()-1);
00150 return MPI_SUCCESS;
00151 }
00152
00153 int ampiParent::dupInfo(MPI_Info info, MPI_Info *newinfo) noexcept {
00154 #if AMPI_ERROR_CHECKING
00155 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00156 return MPI_ERR_INFO;
00157 if(newinfo==NULL)
00158 return MPI_ERR_INFO;
00159 #endif
00160 InfoStruct *newInfoStruct = new InfoStruct;
00161 newInfoStruct->dup(*infos[info]);
00162 infos.push_back(newInfoStruct);
00163 *newinfo = (MPI_Info)(infos.size()-1);
00164 return MPI_SUCCESS;
00165 }
00166
00167 int ampiParent::setInfo(MPI_Info info, const char *key, const char *value) noexcept {
00168 #if AMPI_ERROR_CHECKING
00169 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00170 return MPI_ERR_INFO;
00171 if(key==NULL || strlen(key)>MPI_MAX_INFO_KEY || strlen(key)==0)
00172 return MPI_ERR_INFO_KEY;
00173 if(value==NULL || strlen(value)>MPI_MAX_INFO_VAL || strlen(value)==0)
00174 return MPI_ERR_INFO_VALUE;
00175 #endif
00176 return infos[info]->set(key,value);
00177 }
00178
00179 int ampiParent::deleteInfo(MPI_Info info, const char *key) noexcept {
00180 #if AMPI_ERROR_CHECKING
00181 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00182 return MPI_ERR_INFO;
00183 if(key==NULL || strlen(key)>MPI_MAX_INFO_KEY || strlen(key)==0)
00184 return MPI_ERR_INFO_KEY;
00185 #endif
00186 return infos[info]->deletek(key);
00187 }
00188
00189 int ampiParent::getInfo(MPI_Info info, const char *key, int valuelen, char *value, int *flag) const noexcept {
00190 #if AMPI_ERROR_CHECKING
00191 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00192 return MPI_ERR_INFO;
00193 if(key==NULL || strlen(key)>MPI_MAX_INFO_KEY || strlen(key)==0)
00194 return MPI_ERR_INFO_KEY;
00195 if(value==NULL)
00196 return MPI_ERR_INFO_VALUE;
00197 if(valuelen<0)
00198 return MPI_ERR_ARG;
00199 #endif
00200 return infos[info]->get(key,valuelen,value,flag);
00201 }
00202
00203 int ampiParent::getInfoValuelen(MPI_Info info, const char *key, int *valuelen, int *flag) const noexcept {
00204 #if AMPI_ERROR_CHECKING
00205 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00206 return MPI_ERR_INFO;
00207 if(key==NULL || strlen(key)>MPI_MAX_INFO_KEY || strlen(key)==0)
00208 return MPI_ERR_INFO_KEY;
00209 #endif
00210 return infos[info]->get_valuelen(key,valuelen,flag);
00211 }
00212
00213 int ampiParent::getInfoNkeys(MPI_Info info, int *nkeys) const noexcept {
00214 #if AMPI_ERROR_CHECKING
00215 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00216 return MPI_ERR_INFO;
00217 if(nkeys==NULL)
00218 return MPI_ERR_ARG;
00219 #endif
00220 return infos[info]->get_nkeys(nkeys);
00221 }
00222
00223 int ampiParent::getInfoNthkey(MPI_Info info, int n, char *key) const noexcept {
00224 #if AMPI_ERROR_CHECKING
00225 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00226 return MPI_ERR_INFO;
00227 if(key==NULL)
00228 return MPI_ERR_INFO_KEY;
00229 #endif
00230 return infos[info]->get_nthkey(n,key);
00231 }
00232
00233 int ampiParent::freeInfo(MPI_Info info) noexcept {
00234 #if AMPI_ERROR_CHECKING
00235 if(info<0 || info>=infos.size() || !infos[info]->getvalid())
00236 return MPI_ERR_INFO;
00237 #endif
00238 infos[info]->myfree();
00239 info = MPI_INFO_NULL;
00240 return MPI_SUCCESS;
00241 }
00242
00243 void ampiParent::defineInfoEnv(int nRanks_) noexcept {
00244 char **p_argv;
00245 std::string argv_str, maxprocs_str;
00246 char hostname[255], work_dir[1024];
00247 #if defined(_WIN32)
00248 SYSTEM_INFO sys_info_data;
00249 #else
00250 struct utsname uname_data;
00251 #endif
00252 MPI_Info envInfo;
00253
00254 p_argv = CkGetArgv();
00255 createInfo(&envInfo);
00256 CkAssert(envInfo == MPI_INFO_ENV);
00257
00258 setInfo(envInfo, "command", p_argv[0]);
00259
00260 for(int i=1; i<CkGetArgc(); i++) {
00261 argv_str += p_argv[i];
00262 argv_str += " ";
00263 }
00264 setInfo(envInfo, "argv", argv_str.c_str());
00265
00266 maxprocs_str = std::to_string(nRanks_);
00267 setInfo(envInfo, "maxprocs", maxprocs_str.c_str());
00268
00269
00270
00271 gethostname(hostname, sizeof(hostname));
00272 setInfo(envInfo, "host", hostname);
00273
00274
00275 #if defined(_WIN32)
00276 std::stringstream win_arch;
00277 GetSystemInfo(&sys_info_data);
00278 win_arch << sys_info_data.dwProcessorType;
00279 setInfo(envInfo, "arch", win_arch.str().c_str());
00280 #else
00281 if (uname(&uname_data) == -1) {
00282 CkAbort("uname call in defineInfoEnv() failed\n");
00283 }
00284 else {
00285 setInfo(envInfo, "arch", uname_data.machine);
00286 }
00287 #endif
00288
00289 if (getcwd(work_dir, sizeof(work_dir)) == NULL) {
00290 CkAbort("AMPI> call to getcwd() for MPI_INFO_ENV failed!");
00291 }
00292 setInfo(envInfo, "wdir", work_dir);
00293
00294
00295 }
00296
00297 void ampiParent::defineInfoMigration() noexcept {
00298 MPI_Info lb_sync_info, lb_async_info, chkpt_mem_info, chkpt_msg_log_info;
00299
00300
00301 createInfo(&lb_sync_info);
00302 CkAssert(lb_sync_info == AMPI_INFO_LB_SYNC);
00303 setInfo(lb_sync_info, "ampi_load_balance", "sync");
00304
00305
00306 createInfo(&lb_async_info);
00307 CkAssert(lb_async_info == AMPI_INFO_LB_ASYNC);
00308 setInfo(lb_async_info, "ampi_load_balance", "async");
00309
00310
00311 createInfo(&chkpt_mem_info);
00312 CkAssert(chkpt_mem_info == AMPI_INFO_CHKPT_IN_MEMORY);
00313 setInfo(chkpt_mem_info, "ampi_checkpoint", "in_memory");
00314 }
00315
00316 AMPI_API_IMPL(int, MPI_Info_create, MPI_Info *info)
00317 {
00318 AMPI_API("AMPI_Info_create");
00319 int ret = getAmpiParent()->createInfo(info);
00320 return ampiErrhandler("AMPI_Info_create", ret);
00321 }
00322
00323 AMPI_API_IMPL(int, MPI_Info_set, MPI_Info info, const char *key, const char *value)
00324 {
00325 AMPI_API("AMPI_Info_set");
00326 int ret = getAmpiParent()->setInfo(info, key, value);
00327 return ampiErrhandler("AMPI_Info_set", ret);
00328 }
00329
00330 AMPI_API_IMPL(int, MPI_Info_delete, MPI_Info info, const char *key)
00331 {
00332 AMPI_API("AMPI_Info_delete");
00333 int ret = getAmpiParent()->deleteInfo(info, key);
00334 return ampiErrhandler("AMPI_Info_delete", ret);
00335 }
00336
00337 AMPI_API_IMPL(int, MPI_Info_get, MPI_Info info, const char *key, int valuelen,
00338 char *value, int *flag)
00339 {
00340 AMPI_API("AMPI_Info_get");
00341 getAmpiParent()->getInfo(info, key, valuelen, value, flag);
00342 return MPI_SUCCESS;
00343 }
00344
00345 AMPI_API_IMPL(int, MPI_Info_get_valuelen, MPI_Info info, const char *key,
00346 int *valuelen, int *flag)
00347 {
00348 AMPI_API("AMPI_Info_get_valuelen");
00349 getAmpiParent()->getInfoValuelen(info, key, valuelen, flag);
00350 return MPI_SUCCESS;
00351 }
00352
00353 AMPI_API_IMPL(int, MPI_Info_get_nkeys, MPI_Info info, int *nkeys)
00354 {
00355 AMPI_API("AMPI_Info_get_nkeys");
00356 int ret = getAmpiParent()->getInfoNkeys(info, nkeys);
00357 return ampiErrhandler("AMPI_Info_get_nkeys", ret);
00358 }
00359
00360 AMPI_API_IMPL(int, MPI_Info_get_nthkey, MPI_Info info, int n, char *key)
00361 {
00362 AMPI_API("AMPI_Info_get_nthkey");
00363 int ret = getAmpiParent()->getInfoNthkey(info, n, key);
00364 return ampiErrhandler("AMPI_Info_get_nthkey", ret);
00365 }
00366
00367 AMPI_API_IMPL(int, MPI_Info_dup, MPI_Info info, MPI_Info *newinfo)
00368 {
00369 AMPI_API("AMPI_Info_dup");
00370 int ret = getAmpiParent()->dupInfo(info, newinfo);
00371 return ampiErrhandler("AMPI_Info_dup", ret);
00372 }
00373
00374 AMPI_API_IMPL(int, MPI_Info_free, MPI_Info *info)
00375 {
00376 AMPI_API("AMPI_Info_free");
00377 int ret = getAmpiParent()->freeInfo(*info);
00378 *info = MPI_INFO_NULL;
00379 return ampiErrhandler("AMPI_Info_free", ret);
00380 }
00381
00382 #ifdef AMPIMSGLOG
00383 #if CMK_USE_ZLIB
00384
00385 void PUP::tozDisk::bytes(void *p,int n,size_t itemSize,dataType )
00386 { gzwrite(F,p,itemSize*n);}
00387 void PUP::fromzDisk::bytes(void *p,int n,size_t itemSize,dataType )
00388 { gzread(F,p,itemSize*n);}
00389
00390
00391 void PUP::zdisk::impl_startSeek(seekBlock &s)
00392 {s.data.loff=gztell(F);}
00393 int PUP::zdisk::impl_tell(seekBlock &s)
00394 {return (int)(gztell(F)-s.data.loff);}
00395 void PUP::zdisk::impl_seek(seekBlock &s,int off)
00396 {gzseek(F,s.data.loff+off,0);}
00397 #endif
00398 #endif
00399
00400 void beginTraceBigSim(char* msg){}
00401 void endTraceBigSim(char* msg, char* param){}