blob: 85cca64d9646bd02ff3954371864664ca1278fb6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.ptp.rm.mpi.openmpi.core.rtsystem;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ptp.core.attributes.IllegalValueException;
import org.eclipse.ptp.core.elements.attributes.ProcessAttributes;
import org.eclipse.ptp.rm.mpi.openmpi.core.OpenMPIApplicationAttributes;
import org.eclipse.ptp.rm.mpi.openmpi.core.OpenMPIJobAttributes;
import org.eclipse.ptp.rm.mpi.openmpi.core.OpenMPINodeAttributes;
import org.eclipse.ptp.rm.mpi.openmpi.core.OpenMPIJobAttributes.MappingMode;
import org.eclipse.ptp.rm.mpi.openmpi.core.messages.Messages;
/**
*
* @author Daniel Felix Ferber
*
*/
public class OpenMPIProcessMapText12Parser {
private OpenMPIProcessMapText12Parser() {
// Do not allow instances.
}
OpenMPIProcessMap map = new OpenMPIProcessMap();
int numApplications;
int numNodes;
public static OpenMPIProcessMap parse(InputStream is) throws IOException {
OpenMPIProcessMapText12Parser parser = new OpenMPIProcessMapText12Parser();
BufferedReader reader = new BufferedReader(new InputStreamReader(is), 1);
parser.readStart(reader);
parser.readVpid(reader);
for (int i = 0; i < parser.numApplications; i++) {
parser.readAppContext(reader);
}
parser.readNumElements(reader);
for (int i = 0; i < parser.numNodes; i++) {
parser.readMappedNode(reader, i);
}
return parser.map;
}
/*
* Find mapped node information, ignoring anything else. Format should be:
*
* Mapped node:
* Cell: 0 Nodename: dyn531995.br.ibm.com Launch id: -1 Username: NULL
* Daemon name:
* Data type: ORTE_PROCESS_NAME Data Value: NULL
* Oversubscribed: True Num elements in procs list: 6
* Mapped proc:
* Proc Name:
* Data type: ORTE_PROCESS_NAME Data Value: [0,1,0]
* Proc Rank: 0 Proc PID: 0 App_context index: 0
*/
private void readMappedNode(BufferedReader reader, int nodeCounter) throws IOException {
Pattern p = Pattern.compile("\\s*Mapped node:"); //$NON-NLS-1$
String line;
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
p = Pattern.compile("\\s*Cell:\\s*(\\S*)\\s*Nodename:\\s*(\\S*)\\s*Launch id:\\s*(\\S*)\\s*Username:\\s*(\\S*)"); //$NON-NLS-1$
String nodeName = ""; //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
nodeName = m.group(2);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
OpenMPIProcessMap.Node node = new OpenMPIProcessMap.Node(nodeName);
map.addNode(node);
p = Pattern.compile("\\s*Daemon name:"); //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
p = Pattern.compile("\\s*Data type:\\s*\\S*\\s*Data Value:\\s*\\S*"); //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
p = Pattern.compile("\\s*Oversubscribed:\\s*(\\S*)\\s*Num elements in procs list:\\s*(\\d*)"); //$NON-NLS-1$
int numProcesses = 0;
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
if (s.equalsIgnoreCase("true")) { //$NON-NLS-1$
node.getAttributeManager().addAttribute(OpenMPINodeAttributes.getOversubscribedAttributeDefinition().create(true));
} else if (s.equalsIgnoreCase("false")) { //$NON-NLS-1$
node.getAttributeManager().addAttribute(OpenMPINodeAttributes.getOversubscribedAttributeDefinition().create(false));
} else {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
s = m.group(2);
numProcesses = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
p = Pattern.compile("\\s*Mapped proc:"); //$NON-NLS-1$
Pattern p2 = Pattern.compile("\\s*Proc Name:\\s*(\\S*)"); //$NON-NLS-1$
Pattern p3 = Pattern.compile("\\s*Data type:\\s*\\S*\\s*Data Value:\\s*\\S*"); //$NON-NLS-1$
Pattern p4 = Pattern.compile("\\s*Proc Rank:\\s*(\\d*)\\s*Proc PID:\\s*(\\d*)\\s*App_context index:\\s*(\\d*)"); //$NON-NLS-1$
for (int i = 0; i < numProcesses; i ++) {
String processName = ""; //$NON-NLS-1$
int processIndex = 0;
int processPid = 0;
int applicationIndex = 0;
// Mapped proc:
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
// Proc Name:
while ((line = reader.readLine()) != null) {
Matcher m = p2.matcher(line);
if (m.matches()) {
processName = m.group(1);
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
// Data type:
while ((line = reader.readLine()) != null) {
Matcher m = p3.matcher(line);
if (m.matches()) {
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
// Proc Rank:
while ((line = reader.readLine()) != null) {
Matcher m = p4.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
processIndex = Integer.parseInt(s);
s = m.group(2);
processPid = Integer.parseInt(s);
s = m.group(3);
applicationIndex = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
OpenMPIProcessMap.Process proc = new OpenMPIProcessMap.Process(node, processIndex, processName, applicationIndex);
map.addProcess(proc);
try {
proc.getAttributeManager().addAttribute(ProcessAttributes.getPIDAttributeDefinition().create(processPid));
} catch (IllegalValueException e) {
// This is not possible.
assert false;
}
}
}
/*
* Find num elements line, ignoring anything else. Format should be:
*
* Num elements in nodes list: 1
*/
private void readNumElements(BufferedReader reader) throws IOException {
Pattern p = Pattern.compile("\\s*Num elements in nodes list:\\s*(\\d*)"); //$NON-NLS-1$
String line;
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
numNodes = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
}
/*
* Find app context, ignoring anything else. Format should be:
*
* Data for app_context: index 0 app: hello
* Num procs: 4
* Argv[0]: hello
* Env[0]: OMPI_MCA_rmaps_base_display_map=1
* Env[1]: OMPI_MCA_orte_precondition_transports=e91ae2fd9a00796a-e5685cefcdbaa089
* ...
* Working dir: /home/dfferber/EclipseWorkspaces/runtime-New_configuration/hello/Debug (user: 0)
* Num maps: 0
*
*/
private void readAppContext(BufferedReader reader) throws IOException {
String line;
int applicationIndex = 0;
String applicationName = ""; //$NON-NLS-1$
int numberOfProcessors = 0;
Pattern p = Pattern.compile("\\s*Data for app_context:\\s*\\w*\\s*(\\d*)[^:]*:\\s*(.*)"); //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
applicationIndex = Integer.parseInt(s);
s = m.group(2);
applicationName = s;
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
}
break;
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
p = Pattern.compile("\\s*Num procs:\\s*(\\d*)"); //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
numberOfProcessors = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
OpenMPIProcessMap.Application application = new OpenMPIProcessMap.Application(applicationIndex, applicationName, numberOfProcessors);
map.addApplication(application);
/*
* Collect Argv and Env lines until we match Working Dir
*/
Pattern p1 = Pattern.compile("\\s*Argv\\[\\d*\\]\\s*:\\s*(.*)"); //$NON-NLS-1$
Pattern p2 = Pattern.compile("\\s*Env\\[\\d*\\]\\s*:\\s*(.*)"); //$NON-NLS-1$
p = Pattern.compile("\\s*Working dir:\\s*(.*)"); //$NON-NLS-1$
List<String> arguments = new ArrayList<String>();
List<String> environment = new ArrayList<String>();
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
String s = m.group(1).trim();
application.getAttributeManager().addAttribute(OpenMPIApplicationAttributes.getEffectiveOpenMPIWorkingDirAttributeDefinition().create(s));
break;
}
m = p1.matcher(line);
if (m.matches()) {
arguments.add(m.group(1));
} else {
m = p2.matcher(line);
if (m.matches()) {
environment.add(m.group(1));
}
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
application.getAttributeManager().addAttribute(OpenMPIApplicationAttributes.getEffectiveOpenMPIProgArgsAttributeDefinition().create(arguments.toArray(new String[arguments.size()])));
application.getAttributeManager().addAttribute(OpenMPIApplicationAttributes.getEffectiveOpenMPIEnvAttributeDefinition().create(environment.toArray(new String[environment.size()])));
int num_maps = 0;
p = Pattern.compile("\\s*Num maps:\\s*(\\d*).*"); //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
num_maps = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
/*
* Skip map information
*/
for (int i = 0; i < num_maps; i++) {
line = reader.readLine();
}
}
/*
* Find second line, ignoring anything else. Format should be:
*
* Starting vpid: 0 Vpid range: 6 Num app_contexts: 2
*/
private void readVpid(BufferedReader reader) throws IOException {
Pattern p = Pattern.compile("\\s*Starting vpid:\\s*(\\d*)\\s*Vpid range:\\s*(\\w*)\\s*Num app_contexts:\\s*(\\w*).*"); //$NON-NLS-1$
String line;
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
String s = m.group(1);
try {
map.getAttributeManager().addAttribute(OpenMPIJobAttributes.getVpidStartAttributeDefinition().create(Integer.parseInt(s)));
} catch (IllegalValueException e) {
// This is not possible.
assert false;
}
s = m.group(2);
try {
map.getAttributeManager().addAttribute(OpenMPIJobAttributes.getVpidRangeAttributeDefinition().create(Integer.parseInt(s)));
} catch (IllegalValueException e) {
// This is not possible.
assert false;
}
s = m.group(3);
numApplications = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_BrokenDisplayMapInformation);
}
}
/*
* Find start of map output. This is a line formatted like the one below. Ignore everything
* before this line.
*
* [dyn531995.br.ibm.com:12281] Map for job: 1 Generated by mapping mode: bynode
*
*/
private void readStart(BufferedReader reader) throws IOException {
Pattern p = Pattern.compile("\\[([^:]*):(\\d*)\\]\\s*Map for job:\\s*(\\d*)[^:]*:\\s*(\\w*).*"); //$NON-NLS-1$
String line;
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches()) {
try {
map.getAttributeManager().addAttribute(OpenMPIJobAttributes.getHostnameAttributeDefinition().create(m.group(1)));
try {
map.getAttributeManager().addAttribute(OpenMPIJobAttributes.getMpiJobIdAttributeDefinition().create(Integer.parseInt(m.group(3))));
} catch (IllegalValueException e) {
// This is not possible.
assert false;
}
String mode = m.group(4);
if (mode.equalsIgnoreCase("bynode")) { //$NON-NLS-1$
map.getAttributeManager().addAttribute(OpenMPIJobAttributes.getMappingModeAttributeDefinition().create(MappingMode.BY_NODE));
} else if (mode.equalsIgnoreCase("byslot")) { //$NON-NLS-1$
map.getAttributeManager().addAttribute(OpenMPIJobAttributes.getMappingModeAttributeDefinition().create(MappingMode.BY_SLOT));
} else {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
} catch (NumberFormatException e) {
throw new IOException(NLS.bind(Messages.OpenMPIProcessMapText12Parser_Exception_InvalidLine, line));
}
break;
}
}
if (line == null) {
throw new IOException(Messages.OpenMPIProcessMapText12Parser_Exception_MissingDisplayMapInformation);
}
}
public static void main(String[] args) {
try {
FileInputStream is = new FileInputStream("test.txt"); //$NON-NLS-1$
OpenMPIProcessMapText12Parser.parse(is);
} catch (Exception e) {
e.printStackTrace();
}
}
}