CommonMPIModelFactory.java
package edu.udel.cis.vsl.civl.model.common;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import edu.udel.cis.vsl.civl.model.IF.CIVLFunction;
import edu.udel.cis.vsl.civl.model.IF.CIVLSource;
import edu.udel.cis.vsl.civl.model.IF.Identifier;
import edu.udel.cis.vsl.civl.model.IF.MPIModelFactory;
import edu.udel.cis.vsl.civl.model.IF.Scope;
import edu.udel.cis.vsl.civl.model.IF.expression.Expression;
import edu.udel.cis.vsl.civl.model.IF.expression.IntegerLiteralExpression;
import edu.udel.cis.vsl.civl.model.IF.expression.LHSExpression;
import edu.udel.cis.vsl.civl.model.IF.expression.VariableExpression;
import edu.udel.cis.vsl.civl.model.IF.location.Location;
import edu.udel.cis.vsl.civl.model.IF.statement.AssignStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.CallOrSpawnStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.MPIBarrierStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.MPIIrecvStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.MPIIsendStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.MPIRecvStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.MPISendStatement;
import edu.udel.cis.vsl.civl.model.IF.statement.MPIWaitStatement;
import edu.udel.cis.vsl.civl.model.IF.type.CIVLArrayType;
import edu.udel.cis.vsl.civl.model.IF.type.CIVLType;
import edu.udel.cis.vsl.civl.model.IF.variable.Variable;
import edu.udel.cis.vsl.civl.model.common.statement.CommonMPIBarrierStatement;
import edu.udel.cis.vsl.civl.model.common.statement.CommonMPIIrecvStatement;
import edu.udel.cis.vsl.civl.model.common.statement.CommonMPIIsendStatement;
import edu.udel.cis.vsl.civl.model.common.statement.CommonMPIRecvStatement;
import edu.udel.cis.vsl.civl.model.common.statement.CommonMPISendStatement;
import edu.udel.cis.vsl.civl.model.common.statement.CommonMPIWaitStatement;
import edu.udel.cis.vsl.sarl.IF.SymbolicUniverse;
/**
* This class translates MPI function call nodes into the corresponding MPI
* Statements.
*
* @author Ziqing Luo (ziqing)
* @author Manchun Zheng (zmanchun)
*/
public class CommonMPIModelFactory extends CommonModelFactory implements
MPIModelFactory {
/* *************************** Static Fields *************************** */
static final String RANK = "__rank";
static final String MPI_START = "__mpi_start";
static final String PROCS = "__procs";
/* ************************** Instance Fields ************************** */
/**
* The rank variable that stores the rank of each process. It is a parameter
* of the main function added by MPIFunctionTranslator.
*/
private VariableExpression rankVariable;
/**
* A global variable in the root scope added by MPIFunctionTranslator. It
* synchronizes the starting of all MPI processes.
*/
private VariableExpression startVariable;
/**
* A variable of array type in the root function's scope that stores the
* process id's of spawned MPI processes.
*/
private VariableExpression procsVariable;
/**
* The expression that stores the value of the number of processes specified
* by users from the command line.
*/
private Expression numberOfProcs;
/* **************************** Constructors *************************** */
/**
* Create a new instance of MPIStatementFactory.
*
* @param factory
* The model factory to be used for translating AST nodes.
*/
public CommonMPIModelFactory(SymbolicUniverse universe) {
super(universe);
}
/* ******************* Methods from MPIModelFactory ******************** */
/**
* Translate a MPI_Send function call to an instance of
* {@link edu.udel.cis.vsl.civl.model.IF.statement.MPISendStatement}.
*
* @param scope
* The scope of this function call.
* @param functionCallNode
* The AST node to be translated.
* @return A fragment containing exactly one statement, i.e., the MPI_Send
* statement.
*
*/
@Override
public MPISendStatement mpiSendStatement(CIVLSource source,
Location location, LHSExpression lhs,
ArrayList<Expression> arguments) {
CommonMPISendStatement sendStatement = new CommonMPISendStatement(
source, location, lhs, arguments);
Scope finalScope = null;
if (lhs != null) {
finalScope = join(lhs.expressionScope(), finalScope);
}
finalScope = join(finalScope, joinScope(arguments));
sendStatement.setStatementScope(finalScope);
return sendStatement;
}
/**
* Translate a MPI_Recv functionn call to an instance of
* {@link edu.udel.cis.vsl.civl.model.IF.statement.MPIRecvStatement}
*
* @param scope
* The scope of this function call.
* @param functionCallNode
* The AST node to be translated.
* @return A fragment containing exactly one statement, i.e., the MPI_Recv
* statement.
*/
@Override
public MPIRecvStatement mpiRecvStatement(CIVLSource source,
Location location, LHSExpression lhs,
ArrayList<Expression> arguments) {
CommonMPIRecvStatement recvStatement = new CommonMPIRecvStatement(
source, location, lhs, arguments);
Scope finalScope = null;
if (lhs != null) {
finalScope = join(lhs.expressionScope(), finalScope);
}
finalScope = join(finalScope, joinScope(arguments));
recvStatement.setStatementScope(finalScope);
return recvStatement;
}
@Override
public MPIIsendStatement mpiIsendStatement(CIVLSource source,
Location location, LHSExpression lhs,
ArrayList<Expression> arguments) {
CommonMPIIsendStatement isendStatement = new CommonMPIIsendStatement(
source, location, lhs, arguments);
Scope finalScope = null;
if (lhs != null) {
finalScope = join(lhs.expressionScope(), finalScope);
}
finalScope = join(finalScope, joinScope(arguments));
isendStatement.setStatementScope(finalScope);
return isendStatement;
}
@Override
public MPIIrecvStatement mpiIrecvStatement(CIVLSource source,
Location location, LHSExpression lhs,
ArrayList<Expression> arguments) {
CommonMPIIrecvStatement irecvStatement = new CommonMPIIrecvStatement(
source, location, lhs, arguments);
Scope finalScope = null;
if (lhs != null) {
finalScope = join(lhs.expressionScope(), finalScope);
}
finalScope = join(finalScope, joinScope(arguments));
irecvStatement.setStatementScope(finalScope);
return irecvStatement;
}
/**
* Translate a MPI_Wait functionn call to an instance of
* {@link edu.udel.cis.vsl.civl.model.IF.statement.MPIWaitStatement}
*
* @param scope
* The scope of this function call.
* @param functionCallNode
* The AST node to be translated.
* @return A fragment containing exactly one statement, i.e., the MPI_Wait
* statement.
*/
@Override
public MPIWaitStatement mpiWaitStatement(CIVLSource source,
Location location, LHSExpression lhs,
ArrayList<Expression> arguments) {
CommonMPIWaitStatement waitStatement = new CommonMPIWaitStatement(
source, location, lhs, arguments);
Scope finalScope = null;
if (lhs != null) {
finalScope = join(lhs.expressionScope(), finalScope);
}
finalScope = join(finalScope, joinScope(arguments));
waitStatement.setStatementScope(finalScope);
return waitStatement;
}
/**
* Translate a MPI_Barrier function call to an instance of
* {@link edu.udel.cis.vsl.civl.model.IF.statement.MPIBarrierStatement}
*
* @param scope
* The scope of this function call.
* @param functionCallNode
* The AST node to be translated.
* @return A fragment containing exactly one statement, i.e., the
* MPI_Barrier statement.
*/
@Override
public MPIBarrierStatement mpiBarrierStatement(CIVLSource source,
Location location, LHSExpression lhs,
ArrayList<Expression> arguments) {
// MPI_Barrier just have one argument--communicator
CommonMPIBarrierStatement barrierStatement = new CommonMPIBarrierStatement(
source, location, lhs, arguments.get(0));
Scope finalScope = null;
if (lhs != null) {
finalScope = join(lhs.expressionScope(), finalScope);
}
finalScope = join(finalScope, joinScope(arguments));
barrierStatement.setStatementScope(finalScope);
return barrierStatement;
}
/* ******************** Methods from ModelFactory ********************** */
@Override
public Location location(Scope scope) {
return location(systemSource(), scope);
}
@Override
public Variable variable(CIVLType type, Identifier name, int vid) {
return variable(systemSource(), type, name, vid);
}
@Override
public Identifier identifier(String name) {
return identifier(systemSource(), name);
}
@Override
public Scope scope(Scope parent, LinkedHashSet<Variable> variables,
CIVLFunction function) {
return scope(systemSource(), parent, variables, function);
}
@Override
public IntegerLiteralExpression integerLiteralExpression(BigInteger value) {
return integerLiteralExpression(systemSource(), value);
}
@Override
public AssignStatement assignStatement(Location source, LHSExpression lhs,
Expression rhs, boolean isInitialization) {
return assignStatement(systemSource(), source, lhs, rhs,
isInitialization);
}
@Override
public VariableExpression variableExpression(Variable variable) {
return variableExpression(systemSource(), variable);
}
@Override
public CallOrSpawnStatement callOrSpawnStatement(Location source,
boolean isCall, CIVLFunction function, List<Expression> arguments) {
return callOrSpawnStatement(systemSource(), source, isCall, function,
arguments, null);
}
@Override
public CallOrSpawnStatement callOrSpawnStatement(Location source,
boolean isCall, LHSExpression lhs, CIVLFunction function,
List<Expression> arguments) {
CallOrSpawnStatement statement = callOrSpawnStatement(systemSource(),
source, isCall, function, arguments, null);
statement.setLhs(lhs);
return statement;
}
@Override
public void createRankVariable(int vid) {
Variable rankVariable = this.variable(this.integerType(),
this.identifier(RANK), vid);
this.rankVariable = this.variableExpression(rankVariable);
}
@Override
public VariableExpression rankVariable() {
return this.rankVariable;
}
@Override
public void createStartVariable(Scope scope, int vid) {
Variable startVariable = this.variable(this.integerType(),
this.identifier(MPI_START), vid);
this.startVariable = this.variableExpression(startVariable);
scope.addVariable(startVariable);
}
@Override
public VariableExpression startVariable() {
return this.startVariable;
}
@Override
public void createProcsVariable(Scope scope, int vid, Expression nprocs) {
CIVLArrayType arrayType = completeArrayType(processType(), nprocs);
Variable procsVariable = this.variable(arrayType,
this.identifier(PROCS), vid);
this.procsVariable = this.variableExpression(procsVariable);
scope.addVariable(procsVariable);
}
@Override
public VariableExpression procsVariable() {
return this.procsVariable;
}
@Override
public Expression numberOfProcs() {
return this.numberOfProcs;
}
@Override
public void setNumberOfProcs(Expression numberExpression) {
this.numberOfProcs = numberExpression;
}
}