Skip to content

Commit

Permalink
OTF2: Add a flows analysis with an initial view
Browse files Browse the repository at this point in the history
Added a new analysis in the OTF2 plugin. One view is provided with
this analysis. This view shows the input and output flows of the
threads/processes/nodes/clusters when they are exchanging data through
MPI blocking operations. The colors of states that are displayed when
data is exchanged depends on the mean and standard deviation of all the
data that has been exchanged on the row.

Test case can be found in tracecompass-test-traces, under the name
bandwidth_issue:
tracecompass-test-traces/ctf/src/main/resources/bandwidth_issue

Signed-off-by: yoann-heitz <yoann.heitz@polymtl.ca>
Change-Id: Ie3ea1d99bb0e1d9e6f5d1646895cd2b477387702
Reviewed-on: https://git.eclipse.org/r/c/tracecompass.incubator/org.eclipse.tracecompass.incubator/+/191486
Tested-by: Marco Miller <marco.miller@ericsson.com>
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Reviewed-by: Marco Miller <marco.miller@ericsson.com>
  • Loading branch information
yoann-heitz authored and marco-miller committed Oct 17, 2022
1 parent fefe48c commit ce99299
Show file tree
Hide file tree
Showing 22 changed files with 1,484 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Export-Package: org.eclipse.tracecompass.incubator.internal.otf2.core;x-friends:
org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.callstack;x-friends:="org.eclipse.tracecompass.incubator.otf2.ui",
org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.communicators;x-friends:="org.eclipse.tracecompass.incubator.otf2.ui",
org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.summarytimeline;x-friends:="org.eclipse.tracecompass.incubator.otf2.ui",
org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.flows;x-friends:="org.eclipse.tracecompass.incubator.otf2.ui",
org.eclipse.tracecompass.incubator.otf2.core.trace;x-friends:="org.eclipse.tracecompass.incubator.otf2.ui,org.eclipse.tracecompass.incubator.otf2.core.tests"
Import-Package: com.google.common.collect,
org.apache.commons.io,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
Bundle-Vendor = Eclipse Trace Compass Incubator
Bundle-Name = Trace Compass otf2 Core Plug-in (Incubator)

otf2.analysis.callstack = Callstack analysis
otf2.analysis.callstack = Callstack analysis
otf2.analysis.communicators = MPI communicators state analysis
otf2.analysis.summarytimeline = Summary Timeline analysis
otf2.analysis.summarytimeline = Summary Timeline analysis
otf2.analysis.flows = Flows analysis
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@
class="org.eclipse.tracecompass.incubator.otf2.core.trace.Otf2Trace">
</tracetype>
</module>
<module
analysis_module="org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.flows.Otf2FlowsAnalysis"
automatic="false"
icon="icons/otf2-icon.png"
id="org.eclipse.tracecompass.incubator.otf2.core.analysis.flows"
name="%otf2.analysis.flows">
<tracetype
applies="true"
class="org.eclipse.tracecompass.incubator.otf2.core.trace.Otf2Trace">
</tracetype>
</module>
</extension>
<extension
point="org.eclipse.tracecompass.tmf.core.dataprovider">
Expand All @@ -55,11 +66,18 @@
id="org.eclipse.tracecompass.incubator.otf2.core.analysis.communicators.dataprovider">
</dataProviderFactory>
</extension>
<extension
<extension
point="org.eclipse.tracecompass.tmf.core.dataprovider">
<dataProviderFactory
class="org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.summarytimeline.Otf2SummaryTimelineDataProviderFactory"
id="org.eclipse.tracecompass.incubator.otf2.core.analysis.summarytimeline.dataprovider">
</dataProviderFactory>
</extension>
<extension
point="org.eclipse.tracecompass.tmf.core.dataprovider">
<dataProviderFactory
class="org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.flows.Otf2FlowsDataProviderFactory"
id="org.eclipse.tracecompass.incubator.otf2.core.analysis.flows.dataprovider">
</dataProviderFactory>
</extension>
</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,6 @@ public ITmfStateProvider getNewInstance() {
}
}

/**
* Basic check to figure out if further processing should be done with an
* event
*
* @param event
* the event
* @return true if the event should be handled, false otherwise
*/
protected static boolean considerEvent(ITmfEvent event) {
return true;
}

@Override
protected void eventHandle(ITmfEvent event) {
ITmfEventField content = event.getContent();
Expand Down Expand Up @@ -363,4 +351,21 @@ protected Map<Integer, String> getStringId() {
return fStringId;
}

}
/**
* Return the location id of a process into an MPI communicator.
*
* @param rank
* The rank of the process in the communicator
* @param communicatorReference
* The communicator id
* @return The rank of the location into the communicator, unknown if the
* rank number is >= to the number of members defined.
*/
protected long getLocationIdFromRank(Integer rank, Integer communicatorReference) {
ArrayList<Long> members = getMembersFromCommunicatorReference(communicatorReference);
if (rank >= members.size()) {
return UNKNOWN_RANK;
}
return members.get(rank);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,19 @@ public interface IOtf2Fields {
* Location group field name
*/
String OTF2_LOCATION_GROUP = "locationGroup"; //$NON-NLS-1$
}

/**
* Message length field name
*/
String OTF2_MESSAGE_LENGTH = "msgLength"; //$NON-NLS-1$

/**
* Size received field name
*/
String OTF2_SIZE_RECEIVED = "sizeReceived"; //$NON-NLS-1$

/**
* Size sent field name
*/
String OTF2_SIZE_SENT = "sizeSent"; //$NON-NLS-1$
}
Original file line number Diff line number Diff line change
Expand Up @@ -534,23 +534,6 @@ private void initializeQuarks(ITmfStateSystemBuilder ssb) {
}
}

/**
* Return the location id of a process into an MPI communicator.
*
* @param rank
* The rank of the process in the communicator
* @param communicatorReference
* The communicator id
* @return The rank of the location into the communicator
*/
protected long getLocationIdFromRank(Integer rank, Integer communicatorReference) {
ArrayList<Long> members = getMembersFromCommunicatorReference(communicatorReference);
if (rank >= members.size()) {
return UNKNOWN_RANK;
}
return members.get(rank);
}

/*
* Calls the corresponding method from the associated location given the
* type of event
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*******************************************************************************
* Copyright (c) 2022 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 which accompanies
* this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.flows;

import java.util.Map;

import org.eclipse.tracecompass.incubator.internal.otf2.core.trace.Location;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.StateSystemBuilderUtils;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;

/**
* A class representing a location for the flows analysis
*
* @author Yoann Heitz
*/
class FlowsLocation extends Location implements IFlowsNode {

private int fInputQuark = UNKNOWN_ID;
private int fOutputQuark = UNKNOWN_ID;
private long fLatestEnteredTimestamp = 0;
private long fInputMessageSize = 0;
private long fOutputMessageSize = 0;

/**
* Constructor for this class
*
* @param event
* a GlobalDef_Location event
*/
public FlowsLocation(ITmfEvent event) {
super(event);
}

/**
* Initializes the quarks related to this location. This method should be
* called by the state provider after all definitions have been read
*
* @param ssb
* the state system builder
* @param locationGroupMap
* a map containing the different location groups and their IDs
* @param stringIdMap
* a map containing the different strings and their IDs
*/
public void initializeQuarks(ITmfStateSystemBuilder ssb, FlowsNodeMap<Long, FlowsLocationGroup> locationGroupMap, Map<Integer, String> stringIdMap) {
String locationName = getName(stringIdMap);
long parentId = getLocationGroupId();
int parentInputQuark = locationGroupMap.getNodeQuark(parentId, INPUT);
int parentOutputQuark = locationGroupMap.getNodeQuark(parentId, OUTPUT);
fInputQuark = ssb.getQuarkRelativeAndAdd(parentInputQuark, locationName);
fOutputQuark = ssb.getQuarkRelativeAndAdd(parentOutputQuark, locationName);
}

@Override
public int getInputQuark() {
return fInputQuark;
}

@Override
public int getOutputQuark() {
return fOutputQuark;
}

/**
* Gets the timestamp of the last Enter event for this location
*
* @return the timestamp of the last Enter event for this location
*/
public long getLatestEnteredTimestamp() {
return fLatestEnteredTimestamp;
}

/**
* Sets the timestamp of the last Enter event for this location
*
* @param latestEnteredTimestamp
* the timestamp when this location entered a region the last
* time
*/
public void setLatestEnteredTimestamp(long latestEnteredTimestamp) {
fLatestEnteredTimestamp = latestEnteredTimestamp;
}

/**
* Update the flow value of this location for the correct quark, depending
* on the direction of the communication. The flow value is in
* bytes/nanoseconds
*
* @param ssb
* the state system builder
* @param messageLength
* the number of bytes that were exchanged
* @param endTimestamp
* the timestamp of the end of the communication
* @param direction
* the direction of the communication
*/
private void updateFlow(ITmfStateSystemBuilder ssb, Long messageLength, long endTimestamp, String direction) {
int correctQuark = getQuark(direction);
if (correctQuark == UNKNOWN_ID) {
return;
}
long operationDuration = endTimestamp - fLatestEnteredTimestamp;
double flow = (double) messageLength / operationDuration;
StateSystemBuilderUtils.incrementAttributeDouble(ssb, fLatestEnteredTimestamp, correctQuark, flow);
StateSystemBuilderUtils.incrementAttributeDouble(ssb, endTimestamp, correctQuark, -flow);
}

/**
* Updates the fOutputMessageSize field with a new value
*
* @param messageLength
* the new value for the fOutputMessageSize field
*/
public void updateOutputMessageSize(Long messageLength) {
fOutputMessageSize = messageLength;
}

/**
* Updates the fInputMessageSize field with a new value
*
* @param messageLength
* the new value for the fInputMessageSize field
*/
public void updateInputMessageSize(Long messageLength) {
fInputMessageSize = messageLength;
}

/**
* Method to call when an event representing a region exit for this location
* occurs
*
* @param ssb
* the state system builder
* @param leaveTimestamp
* the timestamp when this location exited a region
*/
public void processLeave(ITmfStateSystemBuilder ssb, long leaveTimestamp) {
if (fInputMessageSize != 0) {
updateFlow(ssb, fInputMessageSize, leaveTimestamp, INPUT);
fInputMessageSize = 0;
}
if (fOutputMessageSize != 0) {
updateFlow(ssb, fOutputMessageSize, leaveTimestamp, OUTPUT);
fOutputMessageSize = 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2022 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 which accompanies
* this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.flows;

import java.util.Map;

import org.eclipse.tracecompass.incubator.internal.otf2.core.trace.LocationGroup;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;

/**
* A class representing a location group for the flows analysis
*
* @author Yoann Heitz
*/
class FlowsLocationGroup extends LocationGroup implements IFlowsNode {

private int fInputQuark = UNKNOWN_ID;
private int fOutputQuark = UNKNOWN_ID;

/**
* Constructor for this class
*
* @param event
* a GlobalDef_LocationGroup event
*/
public FlowsLocationGroup(ITmfEvent event) {
super(event);
}

/**
* Initializes the quarks related to this location group. This method should
* be called by the state provider after all definitions have been read
*
* @param ssb
* the state system builder
* @param systemTreeNodeMap
* a map containing the different system tree nodes and their IDs
* @param stringIdMap
* a map containing the different strings and their IDs
*/
public void initializeQuarks(ITmfStateSystemBuilder ssb, FlowsNodeMap<Long, FlowsSystemTreeNode> systemTreeNodeMap, Map<Integer, String> stringIdMap) {
long parentId = getParentId();
String fullName = getFullName(stringIdMap);
int parentInputQuark = systemTreeNodeMap.getNodeQuark(parentId, INPUT);
int parentOutputQuark = systemTreeNodeMap.getNodeQuark(parentId, OUTPUT);
if (parentInputQuark != UNKNOWN_ID && parentOutputQuark != UNKNOWN_ID) {
fInputQuark = ssb.getQuarkRelativeAndAdd(parentInputQuark, fullName);
fOutputQuark = ssb.getQuarkRelativeAndAdd(parentOutputQuark, fullName);
}
}

@Override
public int getInputQuark() {
return fInputQuark;
}

@Override
public int getOutputQuark() {
return fOutputQuark;
}
}
Loading

0 comments on commit ce99299

Please sign in to comment.