📄 mpirun.cpp
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* $Id: MPIRun.cpp,v 1.2 2002/09/27 21:11:12 toonen Exp $ * * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#include <stdio.h>#include "MPICH_pwd.h"#include "MPIJobDefs.h"#include <conio.h>#include <time.h>#include "Translate_Error.h"#include "localonly.h"#include "GetOpt.h"#include "LaunchProcess.h"#include "global.h"#include "WaitThread.h"#include "mpd.h"#include "mpdutil.h"//#include "bsocket.h"#include "RedirectIO.h"#include <ctype.h>#include <stdlib.h>// Prototypesvoid WaitForExitCommands();void ExeToUnc(char *pszExe);// Function name : PrintOptions// Description : // Return type : void void PrintOptions(){ printf("\n"); printf("Usage:\n"); printf(" MPIRun -np #processes [options] executable [args ...]\n"); printf(" MPIRun [options] configfile [args ...]\n"); //printf(" MPIRun -localonly #processes [-mpirun options] exe [args ...]\n"); printf("\n"); printf("mpirun options:\n"); printf(" -localonly\n"); printf(" -env \"var1=val1|var2=val2|var3=val3...\"\n"); printf(" -dir drive:\\my\\working\\directory\n"); printf(" -logon\n"); printf(" -map drive:\\\\host\\share\n"); printf("\n"); printf("Config file format:\n"); printf(" >exe c:\\temp\\mpiprogram.exe\n"); printf(" OR \\\\host\\share\\mpiprogram.exe\n"); printf(" >[env var1=val1|var2=val2|var3=val3...]\n"); printf(" >[dir drive:\\my\\working\\directory]\n"); printf(" >[map drive:\\\\host\\share]\n"); printf(" >[args arg1 arg2 ...]\n"); printf(" >hosts\n"); printf(" >hostname1 #procs [path\\mpiprogram.exe]\n"); printf(" >hostname2 #procs [path\\mpiprogram.exe]\n"); printf(" >hostname3 #procs [path\\mpiprogram.exe]\n"); printf(" >...\n"); printf("\n"); printf("bracketed lines are optional\n"); printf("\n"); printf("For a list of all mpirun options, execute 'mpirun -help2'\n"); printf("\n");}void PrintExtraOptions(){ printf("\n"); printf("All options to mpirun:\n"); printf("\n"); printf("-np x\n"); printf(" launch x processes\n"); printf("-localonly x\n"); printf("-np x -localonly\n"); printf(" launch x processes on the local machine\n"); printf("-machinefile filename\n"); printf(" use a file to list the names of machines to launch on\n"); printf("-map drive:\\\\host\\share\n"); printf(" map a drive on all the nodes\n"); printf(" this mapping will be removed when the processes exit\n"); printf("-dir drive:\\my\\working\\directory\n"); printf(" launch processes in the specified directory\n"); printf("-env \"var1=val1|var2=val2|var3=val3...\"\n"); printf(" set environment variables before launching the processes\n"); printf("-logon\n"); printf(" prompt for user account and password\n"); printf("-tcp\n"); printf(" use tcp instead of shared memory on the local machine\n"); printf("-getphrase\n"); printf(" prompt for the passphrase to access remote mpds\n"); printf("-nocolor\n"); printf(" don't use process specific output coloring\n"); printf("-nompi\n"); printf(" launch processes without the mpi startup mechanism\n"); printf("-nodots\n"); printf(" don't output dots while logging on the user\n"); printf("-nomapping\n"); printf(" don't try to map the current directory on the remote nodes\n"); printf("-nopopup_debug\n"); printf(" disable the system popup dialog if the process crashes\n"); printf("-hosts n host1 host2 ... hostn\n"); printf("-hosts n host1 m1 host2 m2 ... hostn mn\n"); printf(" launch on the specified hosts\n"); printf(" the number of processes = m1 + m2 + ... + mn\n");}// Function name : ConnectReadMPDRegistry// Description : // Return type : bool // Argument : char *pszHost// Argument : int nPort// Argument : char *pszPassPhrase// Argument : char *name// Argument : char *value// Argument : DWORD *length = NULLbool ConnectReadMPDRegistry(char *pszHost, int nPort, char *pszPassPhrase, char *name, char *value, DWORD *length = NULL){ int error; SOCKET sock; char pszStr[1024]; if ((error = ConnectToMPD(pszHost, nPort, pszPassPhrase, &sock)) == 0) { sprintf(pszStr, "lget %s", name); WriteString(sock, pszStr); ReadString(sock, pszStr); if (strlen(pszStr)) { WriteString(sock, "done"); easy_closesocket(sock); strcpy(value, pszStr); if (length) *length = strlen(pszStr); //printf("ConnectReadMPDRegistry successfully used to read the host entry:\n%s\n", pszStr);fflush(stdout); return true; } WriteString(sock, "done"); easy_closesocket(sock); } else { //printf("MPIRunLaunchProcess: Connect to %s failed, error %d\n", pszHost, error);fflush(stdout); } return false;}// Function name : ReadMPDRegistry// Description : // Return type : bool // Argument : char *name// Argument : char *value// Argument : DWORD *length = NULLbool ReadMPDRegistry(char *name, char *value, DWORD *length /*= NULL*/){ HKEY tkey; DWORD len, result; // Open the root key if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, MPD_REGISTRY_KEY, 0, KEY_READ, &tkey) != ERROR_SUCCESS) { //printf("Unable to open the MPD registry key, error %d\n", GetLastError()); return false; } if (length == NULL) len = MAX_CMD_LENGTH; else len = *length; result = RegQueryValueEx(tkey, name, 0, NULL, (unsigned char *)value, &len); if (result != ERROR_SUCCESS) { //printf("Unable to read the mpd registry key '%s', error %d\n", name, GetLastError()); RegCloseKey(tkey); return false; } if (length != NULL) *length = len; RegCloseKey(tkey); return true;}// Function name : GetHostsFromRegistry// Description : // Return type : bool // Argument : HostNode **listbool GetHostsFromRegistry(HostNode **list){ // Read the hosts entry char pszHosts[MAX_CMD_LENGTH+1]; DWORD nLength = MAX_CMD_LENGTH; if (!ReadMPDRegistry("hosts", pszHosts, &nLength)) { char localhost[100]; gethostname(localhost, 100); if (!ConnectReadMPDRegistry(localhost, MPD_DEFAULT_PORT, MPD_DEFAULT_PASSPHRASE, "hosts", pszHosts, &nLength)) return false; } /* // If this code is used, the program fails at the delete // statement at the end of the function. I don't know why. char *pszHosts = NULL; DWORD num_bytes = 0;//1024*sizeof(char); if (!ReadMPDRegistry("hosts", NULL, &num_bytes)) return false; pszHosts = new char[num_bytes+1]; if (!ReadMPDRegistry("hosts", pszHosts, &num_bytes)) { delete pszHosts; return false; } *//* char *token = NULL; token = strtok(pszHosts, "|"); if (token != NULL) { HostNode *n, *l = new HostNode; // Make a list of the available nodes l->next = NULL; strncpy(l->host, token, MAX_HOST_LENGTH); l->host[MAX_HOST_LENGTH-1] = '\0'; l->nSMPProcs = 1; n = l; while ((token = strtok(NULL, "|")) != NULL) { n->next = new HostNode; n = n->next; n->next = NULL; strncpy(n->host, token, MAX_HOST_LENGTH); n->host[MAX_HOST_LENGTH-1] = '\0'; n->nSMPProcs = 1; } *list = l; //delete pszHosts; return true; } //delete pszHosts; return false;*/ QVS_Container *phosts; phosts = new QVS_Container(pszHosts); if (phosts->first(pszHosts, MAX_CMD_LENGTH)) { HostNode *n, *l = new HostNode; l->next = NULL; strncpy(l->host, pszHosts, MAX_HOST_LENGTH); l->host[MAX_HOST_LENGTH-1] = '\0'; l->nSMPProcs = 1; n = l; while (phosts->next(pszHosts, MAX_CMD_LENGTH)) { n->next = new HostNode; n = n->next; n->next = NULL; strncpy(n->host, pszHosts, MAX_HOST_LENGTH); n->host[MAX_HOST_LENGTH-1] = '\0'; n->nSMPProcs = 1; } *list = l; delete phosts; return true; } delete phosts; return false;}// Function name : GetAvailableHosts// Description : This function requires g_nHosts to have been previously set.// Return type : bool bool GetAvailableHosts(){ HostNode *list = NULL; //dbg_printf("finding available hosts\n"); if (g_nHosts > 0) { if (GetHostsFromRegistry(&list)) { // Insert the first host into the list g_pHosts = new HostNode; strncpy(g_pHosts->host, list->host, MAX_HOST_LENGTH); g_pHosts->host[MAX_HOST_LENGTH-1] = '\0'; strncpy(g_pHosts->exe, g_pszExe, MAX_CMD_LENGTH); g_pHosts->exe[MAX_CMD_LENGTH-1] = '\0'; g_pHosts->nSMPProcs = 1; g_pHosts->next = NULL; // add the nodes to the target list, cycling if necessary int num_left = g_nHosts-1; HostNode *n = list->next, *target = g_pHosts; if (n == NULL) n = list; while (num_left) { target->next = new HostNode; target = target->next; target->next = NULL; strncpy(target->host, n->host, MAX_HOST_LENGTH); target->host[MAX_HOST_LENGTH-1] = '\0'; strncpy(target->exe, g_pHosts->exe, MAX_CMD_LENGTH); target->exe[MAX_CMD_LENGTH-1] = '\0'; target->nSMPProcs = 1; n = n->next; if (n == NULL) n = list; num_left--; } // free the list while (list) { n = list; list = list->next; delete n; } } else { return false; } } return true;}// Function name : GetHostsFromFile// Description : // Return type : bool // Argument : char *pszFileNamebool GetHostsFromFile(char *pszFileName){ FILE *fin; char buffer[1024] = ""; char *pChar, *pChar2; HostNode *node = NULL, *list = NULL, *cur_node; fin = fopen(pszFileName, "r"); if (fin == NULL) { printf("unable to open file '%s'\n", pszFileName); return false; } // Read the host names from the file while (fgets(buffer, 1024, fin)) { pChar = buffer; // Advance over white space while (*pChar != '\0' && isspace(*pChar)) pChar++; if (*pChar == '#' || *pChar == '\0') continue; // Trim trailing white space pChar2 = &buffer[strlen(buffer)-1]; while (isspace(*pChar2) && (pChar >= pChar)) { *pChar2 = '\0'; pChar2--; } // If there is anything left on the line, consider it a host name if (strlen(pChar) > 0) { node = new HostNode; node->nSMPProcs = 1; node->next = NULL; node->exe[0] = '\0'; // Copy the host name pChar2 = node->host; while (*pChar != '\0' && !isspace(*pChar)) { *pChar2 = *pChar; pChar++; pChar2++; } *pChar2 = '\0'; pChar2 = strtok(node->host, ":"); pChar2 = strtok(NULL, "\n"); if (pChar2 != NULL) { node->nSMPProcs = atoi(pChar2); if (node->nSMPProcs < 1) node->nSMPProcs = 1; } else { // Advance over white space while (*pChar != '\0' && isspace(*pChar)) pChar++; // Get the number of SMP processes if (*pChar != '\0') { node->nSMPProcs = atoi(pChar); if (node->nSMPProcs < 1) node->nSMPProcs = 1; } } if (list == NULL) { list = node; cur_node = node; } else { cur_node->next = node; cur_node = node; } } } fclose(fin); if (list == NULL) return false; // Allocate the first host node g_pHosts = new HostNode; int num_left = g_nHosts; HostNode *n = list, *target = g_pHosts; // add the nodes to the target list, cycling if necessary while (num_left) { target->next = NULL; strncpy(target->host, n->host, MAX_HOST_LENGTH); target->host[MAX_HOST_LENGTH-1] = '\0'; strncpy(target->exe, g_pszExe, MAX_CMD_LENGTH); target->exe[MAX_CMD_LENGTH-1] = '\0'; if (num_left <= n->nSMPProcs) { target->nSMPProcs = num_left; num_left = 0; } else { target->nSMPProcs = n->nSMPProcs; num_left = num_left - n->nSMPProcs; } if (num_left) { target->next = new HostNode; target = target->next; } n = n->next; if (n == NULL) n = list; } // free the list while (list) { n = list; list = list->next; delete n; } return true;}// Function name : ParseLineIntoHostNode// Description : // Return type : HostNode* // Argument : char * lineHostNode* ParseLineIntoHostNode(char * line){ char buffer[1024]; char *pChar, *pChar2; HostNode *node = NULL; strncpy(buffer, line, 1024); buffer[1023] = '\0'; pChar = buffer; // Advance over white space while (*pChar != '\0' && isspace(*pChar)) pChar++; if (*pChar == '#' || *pChar == '\0') return NULL; // Trim trailing white space pChar2 = &buffer[strlen(buffer)-1]; while (isspace(*pChar2) && (pChar >= pChar)) { *pChar2 = '\0'; pChar2--; } // If there is anything left on the line, consider it a host name if (strlen(pChar) > 0) { node = new HostNode; node->nSMPProcs = 1; node->next = NULL; node->exe[0] = '\0'; // Copy the host name pChar2 = node->host; while (*pChar != '\0' && !isspace(*pChar)) { *pChar2 = *pChar; pChar++; pChar2++; } *pChar2 = '\0'; // Advance over white space while (*pChar != '\0' && isspace(*pChar)) pChar++; // Get the number of SMP processes if (*pChar != '\0') { node->nSMPProcs = atoi(pChar); if (node->nSMPProcs < 1) node->nSMPProcs = 1; } // Advance over the number while (*pChar != '\0' && isdigit(*pChar))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -