| /********************************************************************** |
| * Copyright (c) 2007,2010 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.pldt.mpi.analysis.analysis; |
| |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.cdt.core.dom.ast.IASTCastExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTFileLocation; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTIdExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; |
| import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTName; |
| import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; |
| import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.ptp.pldt.common.Artifact; |
| import org.eclipse.ptp.pldt.common.util.SourceInfo; |
| |
| public class BarrierTable { |
| /** |
| * Set of barriers for a communicator. |
| * Key: <String>communicator, Value: set of <BarrierInfo>barriers |
| */ |
| protected Hashtable<String,List<BarrierInfo>> table_; |
| protected int commCounter = 0; |
| private static boolean dbg_barrier=false; |
| |
| public BarrierTable(){ |
| table_ = new Hashtable<String,List<BarrierInfo>>(); |
| } |
| |
| public Hashtable<String,List<BarrierInfo>> getTable(){ |
| return table_; |
| } |
| public boolean isEmpty() {return table_.isEmpty();} |
| |
| public BarrierInfo addBarrier(IASTFunctionCallExpression barE, |
| int id, IResource res, String func){ |
| BarrierInfo bar = new BarrierInfo(barE, id, res, func); |
| if(table_.containsKey(bar.getComm())){ |
| List<BarrierInfo> list = table_.get(bar.getComm()); |
| list.add(bar); |
| } else { |
| List<BarrierInfo> list = new ArrayList<BarrierInfo>(); |
| list.add(bar); |
| table_.put(bar.getComm(), list); |
| } |
| return bar; |
| } |
| |
| /** |
| * @return barrier ID if it is a barrier; -1 otherwise |
| * <br>BRT barrier ids may not match with OpenMPI 1.3.3 headers?? see setComm() |
| */ |
| public int isBarrier(IASTFunctionCallExpression funcE){ |
| IASTExpression funcname = funcE.getFunctionNameExpression(); |
| String signature = funcname.getRawSignature(); |
| if(!signature.equals("MPI_Barrier")) return -1; //$NON-NLS-1$ |
| for(Enumeration e = table_.elements(); e.hasMoreElements();){ |
| ArrayList list = (ArrayList)e.nextElement(); |
| for(Iterator i = list.iterator(); i.hasNext();){ |
| BarrierInfo bar = (BarrierInfo)i.next(); |
| if(bar.getFunc() == funcE) |
| return bar.getID(); |
| } |
| } |
| return -1; |
| } |
| |
| public String getComm(int id){ |
| for(Enumeration e = table_.elements(); e.hasMoreElements();){ |
| ArrayList list = (ArrayList)e.nextElement(); |
| for(Iterator i = list.iterator(); i.hasNext();){ |
| BarrierInfo bar = (BarrierInfo)i.next(); |
| if(bar.getID() == id) |
| return bar.getComm(); |
| } |
| } |
| return null; |
| } |
| |
| public BarrierInfo searchBarrierbyID(int id){ |
| for(Enumeration e = table_.elements(); e.hasMoreElements();){ |
| ArrayList list = (ArrayList)e.nextElement(); |
| for(Iterator i = list.iterator(); i.hasNext();){ |
| BarrierInfo bar = (BarrierInfo)i.next(); |
| if(bar.getID() == id) |
| return bar; |
| } |
| } |
| return null; |
| } |
| |
| |
| |
| public class BarrierInfo{ |
| protected String comm_ = null; |
| protected IASTFunctionCallExpression barrier_ = null; |
| protected int id = -1; |
| protected String fileName_ = null; |
| protected SourceInfo sourceInfo_ = null; |
| protected List<BarrierInfo> matchingSet_ = null; |
| protected IResource resource_ = null; |
| protected String enclosingFunc_ = null; |
| |
| public BarrierInfo(IASTFunctionCallExpression funcE, int id, IResource res, String func){ |
| barrier_ = funcE; |
| this.id = id; |
| setComm(); |
| setSourceInfo(); |
| matchingSet_ = new ArrayList<BarrierInfo>(); |
| resource_ = res; |
| enclosingFunc_ = func; |
| } |
| |
| /** |
| * Determine the communicator from the the barrier function call |
| * ("MPI_Barrier(communicator)"). <br> |
| * If the communicator is the default (MPI_COMM_WORLD), then the type of |
| * the returned object from getOperand() depends on how the header file |
| * defines it (In windows, it is IASTLiteralExpression, and in Linux, it |
| * becomes IASTIdExpression). So we account for that here. |
| * |
| * BRT clarification: 09/09/09 |
| * OpenMPI < 1.3? defines MPI_COMM_WORLD as: |
| * #define MPI_COMM_WORLD (&ompi_mpi_comm_world) |
| * OpenMPI 1.3.3 defines MPI_COMM_WORLD as: |
| * #define MPI_COMM_WORLD OMPI_PREDEFINED_GLOBAL( MPI_Comm, ompi_mpi_comm_world) |
| * which makes the CDT objects for the barrier/communicator show up differently when it gets here. |
| * It shows up as an IASTCastExpression, so we recognize that and get its name, |
| * instead of relying on the default fallback plan here, which seems to always |
| * make each barrier/communicator found be unique, in which case no barriers match, because their |
| * communicators all look different. |
| * |
| * Problem: for the case of #define newcomm MPI_COMM_WORLD |
| * I don't want the getRawSignature() on the communicator arg, i want the |
| * pre-processed value. How to get that? |
| */ |
| protected void setComm() { |
| IASTExpression parameter = barrier_.getParameterExpression(); |
| IASTInitializerClause[] newParms = barrier_.getArguments(); // BRT could fix deprecation? |
| |
| if (parameter instanceof IASTUnaryExpression) { |
| IASTUnaryExpression commExpr = (IASTUnaryExpression) parameter; |
| IASTExpression commOp=commExpr.getOperand(); |
| if (commOp instanceof IASTUnaryExpression) { |
| if(dbg_barrier)System.out.println("setComm(): communicator is IASTUnaryExpression"); //$NON-NLS-1$ |
| //IASTUnaryExpression commOprd = (IASTUnaryExpression) commOp; |
| if (commOp instanceof IASTLiteralExpression) {//Yuan says windows |
| if(dbg_barrier)System.out.println(); |
| IASTLiteralExpression comm = (IASTLiteralExpression) commOp; |
| comm_ = comm.toString(); |
| } else if (commOp instanceof IASTIdExpression) { //Yuan says linux |
| IASTIdExpression comm = (IASTIdExpression) commOp; |
| comm_ = comm.getName().toString(); |
| } else if (commOp instanceof IASTName) {//? |
| comm_ = commOp.toString(); |
| } else { |
| |
| if(commOp instanceof IASTUnaryExpression) {// Mac OSX Openmpi < 1.3 (/usr/include/mpi.h) // 4/14/10: got here OMPI 1.3.3 |
| IASTUnaryExpression iastUnaryExpression = (IASTUnaryExpression) commOp; |
| if(dbg_barrier)System.out.println("bdbg: communicator is IASTUnaryExpression"); //$NON-NLS-1$ |
| comm_= iastUnaryExpression.getRawSignature(); |
| |
| } else { |
| // last resort: use a unique name, but it won't |
| // match anything?? |
| comm_ = "COMM_" + commCounter; //$NON-NLS-1$ |
| commCounter++; |
| } |
| } |
| } else { |
| if(commOp instanceof IASTCastExpression) {//MAC OSX Openmpi 1.3.3 ;mpich2 |
| IASTCastExpression iastCastExpression = (IASTCastExpression) commOp; |
| comm_ = iastCastExpression.getRawSignature(); |
| } |
| else{ |
| comm_ = "COMM_" + commCounter; //$NON-NLS-1$ |
| commCounter++; |
| } |
| |
| } |
| } else if (parameter instanceof IASTIdExpression) {//windows mpich 1.2 |
| IASTIdExpression idE = (IASTIdExpression) parameter; |
| comm_ = idE.getName().toString(); |
| |
| /* BRT 9/9/09: why hide the actual name? no non-mpi-comm-world comms will match! |
| if (!comm_.equals("MPI_COMM_WORLD")) { |
| comm_ = "COMM_" + commCounter; |
| commCounter++; |
| } |
| */ |
| } else if (parameter instanceof IASTLiteralExpression){// added 9/9/09 for windows/mpich |
| IASTLiteralExpression iastLiteralExpression = (IASTLiteralExpression) parameter; |
| |
| String str=iastLiteralExpression.getRawSignature(); |
| comm_=iastLiteralExpression.getRawSignature(); |
| } |
| else { |
| comm_ = "COMM_" + commCounter; //$NON-NLS-1$ |
| commCounter++; |
| } |
| if(dbg_barrier)System.out.println("setComm(): communicator: "+comm_); //$NON-NLS-1$ |
| } |
| |
| |
| protected void setSourceInfo() { |
| IASTExpression funcNameE = barrier_.getFunctionNameExpression(); |
| IASTNodeLocation[] locations = funcNameE.getNodeLocations(); |
| if (locations.length == 1) { |
| IASTFileLocation astFileLocation = null; |
| if (locations[0] instanceof IASTFileLocation) { |
| astFileLocation = (IASTFileLocation) locations[0]; |
| fileName_ = astFileLocation.getFileName(); |
| //System.out.println(fileName_); |
| sourceInfo_ = new SourceInfo(); |
| sourceInfo_.setStartingLine(astFileLocation.getStartingLineNumber()); |
| sourceInfo_.setStart(astFileLocation.getNodeOffset()); |
| sourceInfo_.setEnd(astFileLocation.getNodeOffset() + astFileLocation.getNodeLength()); |
| sourceInfo_.setConstructType(Artifact.FUNCTION_CALL); |
| } |
| } |
| } |
| |
| public String getComm() {return comm_;} |
| public IASTFunctionCallExpression getFunc() {return barrier_;} |
| public int getID() {return id;} |
| public String getFileName() {return fileName_;} |
| public SourceInfo getSourceInfo() {return sourceInfo_;} |
| public List<BarrierInfo> getMatchingSet() {return matchingSet_;} |
| public IResource getResource() {return resource_;} |
| public String getEnclosingFunc() {return enclosingFunc_;} |
| } |
| |
| } |