00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.mpi;
00032
00033 import org.apache.log4j.Logger;
00034
00035 import org.objectweb.proactive.core.descriptor.data.VirtualNode;
00036 import org.objectweb.proactive.core.node.NodeException;
00037 import org.objectweb.proactive.core.process.AbstractExternalProcess;
00038 import org.objectweb.proactive.core.process.AbstractExternalProcessDecorator;
00039 import org.objectweb.proactive.core.process.ExternalProcess;
00040 import org.objectweb.proactive.core.process.mpi.MPIProcess;
00041 import org.objectweb.proactive.core.util.log.Loggers;
00042 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00043
00044 import java.io.IOException;
00045
00046 import java.util.ArrayList;
00047 import java.util.Hashtable;
00048
00049
00050 public class MPISpmdImpl implements MPISpmd, java.io.Serializable {
00051 private final static Logger MPI_IMPL_LOGGER = ProActiveLogger.getLogger(Loggers.MPI);
00052
00054 private String name;
00055
00057 private ExternalProcess mpiProcess = null;
00058
00060 private VirtualNode vn;
00061
00063 private ArrayList<String> spmdClasses = null;
00064
00066 private Hashtable<String, ArrayList<Object[]>> spmdClassesParams;
00067
00069 private ArrayList<String> classes = null;
00070
00072 private Hashtable<String, Object[]> classesParams;
00073 private Object[] classesParamsByRank;
00074
00075
00076 public MPISpmdImpl() {
00077 }
00078
00083 public MPISpmdImpl(VirtualNode vn) throws RuntimeException, NodeException {
00084 MPI_IMPL_LOGGER.debug(
00085 "[MPISpmd object] creating MPI SPMD active object: " +
00086 vn.getName());
00087
00088 if (!(vn.isActivated())) {
00089 vn.activate();
00090 }
00091 if (vn.hasMPIProcess()) {
00092 this.spmdClasses = new ArrayList<String>();
00093 this.classes = new ArrayList<String>();
00094 this.spmdClassesParams = new Hashtable<String, ArrayList<Object[]>>();
00095 this.classesParams = new Hashtable<String, Object[]>();
00096 this.classesParamsByRank = new Object[vn.getNodes().length];
00097 this.mpiProcess = vn.getMPIProcess();
00098 this.name = vn.getName();
00099 this.vn = vn;
00100 } else {
00101 throw new RuntimeException(
00102 "!!! ERROR: Cannot create MPISpmd object Cause: No MPI process attached with the virtual node " +
00103 vn.getName());
00104 }
00105 }
00106
00111 public MPIResult startMPI() {
00112 MPI_IMPL_LOGGER.debug("[MPISpmd Object] Start MPI Process ");
00113 MPIResult result = new MPIResult();
00114 try {
00115 mpiProcess.startProcess();
00116 mpiProcess.waitFor();
00117 result.setReturnValue(mpiProcess.exitValue());
00118 return result;
00119 } catch (IOException e) {
00120 e.printStackTrace();
00121 MPI_IMPL_LOGGER.error(
00122 "!!! ERROR startMPI: cannot start MPI process " + this.name +
00123 " with command " + mpiProcess.getCommand());
00124 } catch (InterruptedException e) {
00125 e.printStackTrace();
00126 }
00127 return null;
00128 }
00129
00135 public MPIResult reStartMPI() {
00136 MPI_IMPL_LOGGER.debug("[MPISpmd Object] reStart MPI Process ");
00137 reinitProcess();
00138 return this.startMPI();
00139 }
00140
00146 public boolean killMPI() {
00147 MPI_IMPL_LOGGER.debug("[MPISpmd Object] Kill MPI Process ");
00148
00149
00150 try {
00151 mpiProcess.stopProcess();
00152
00153
00154 Thread.sleep(200);
00155 return true;
00156 } catch (IllegalStateException e) {
00157 MPI_IMPL_LOGGER.error(
00158 "Exception caught, waiting process to start to kill it.");
00159 while (!mpiProcess.isStarted()) {
00160 }
00161 mpiProcess.stopProcess();
00162 } catch (InterruptedException e) {
00163 e.printStackTrace();
00164 MPI_IMPL_LOGGER.error("!!! ERROR killMPI: cannot kill MPI process " +
00165 this.name);
00166 }
00167 return false;
00168 }
00169
00174 public void setMPICommandArguments(String arguments) {
00175 MPI_IMPL_LOGGER.debug(((AbstractExternalProcess) this.mpiProcess).getCommand());
00176
00177 int rank = getMPIProcessRank(this.mpiProcess);
00178 ExternalProcess tempProc = this.mpiProcess;
00179 while (rank != 0) {
00180 tempProc = ((AbstractExternalProcessDecorator) tempProc).getTargetProcess();
00181 rank--;
00182 }
00183 ((MPIProcess) tempProc).setMpiCommandOptions(arguments);
00184 MPI_IMPL_LOGGER.debug(((AbstractExternalProcess) this.mpiProcess).getCommand());
00185 }
00186
00187 public String getName() {
00188 return this.name;
00189 }
00190
00191 public String toString() {
00192 StringBuilder sb = new StringBuilder();
00193 sb.append("\n Class: ");
00194 sb.append(this.getClass().getName());
00195 sb.append("\n Name: ");
00196 sb.append(this.name);
00197 sb.append("\n Command: ");
00198 sb.append(getMPIProcess(this.mpiProcess).getCommand());
00199 sb.append("\n Processes number: ");
00200 sb.append(getMPIProcess(this.mpiProcess).getHostsNumber());
00201 return sb.toString();
00202 }
00203
00204 public void reinitProcess() {
00205 this.killMPI();
00206 mpiProcess.setStarted(false);
00207 mpiProcess.setFinished(false);
00208 }
00209
00210 public String getStatus() {
00211 return null;
00212 }
00213
00214
00215 private MPIProcess getMPIProcess(ExternalProcess process) {
00216 while (!(process instanceof MPIProcess)) {
00217 process = ((ExternalProcess) ((AbstractExternalProcessDecorator) process).getTargetProcess());
00218 }
00219 return (MPIProcess) process;
00220 }
00221
00222
00223 private int getMPIProcessRank(ExternalProcess process) {
00224 int res = 0;
00225 while (!(process instanceof MPIProcess)) {
00226 res++;
00227 process = ((ExternalProcess) ((AbstractExternalProcessDecorator) process).getTargetProcess());
00228 }
00229 return res;
00230 }
00231
00232 public boolean isFinished() {
00233 return mpiProcess.isFinished();
00234 }
00235
00236 public VirtualNode getVn() {
00237 return vn;
00238 }
00239
00240
00241
00242
00243 public void newActiveSpmd(String cl) {
00244 if (spmdClasses.contains(cl) || classes.contains(cl)) {
00245 MPI_IMPL_LOGGER.info("!!! ERROR newActiveSpmd: " + cl +
00246 " class has already been added to the list of user classes to instanciate ");
00247 } else {
00248 this.spmdClasses.add(cl);
00249 ArrayList<Object[]> parameters = new ArrayList<Object[]>(2);
00250 parameters.add(0, null);
00251 parameters.add(1, null);
00252 this.spmdClassesParams.put(cl, parameters);
00253 }
00254 }
00255
00256 public void newActiveSpmd(String cl, Object[] params) {
00257 if (spmdClasses.contains(cl) || classes.contains(cl)) {
00258 MPI_IMPL_LOGGER.info("!!! ERROR newActiveSpmd: " + cl +
00259 " class has already been added to the list of user classes to instanciate ");
00260 } else {
00261 this.spmdClasses.add(cl);
00262
00263 ArrayList<Object[]> parameters = new ArrayList<Object[]>(2);
00264
00265
00266
00267 parameters.add(0, params);
00268 parameters.add(1, null);
00269 this.spmdClassesParams.put(cl, parameters);
00270 }
00271 }
00272
00273 public void newActiveSpmd(String cl, Object[][] params) {
00274 try {
00275 if (params.length != vn.getNodes().length) {
00276 throw new RuntimeException(
00277 "!!! ERROR: mismatch between number of parameters and number of Nodes");
00278 }
00279
00280 if (spmdClasses.contains(cl) || classes.contains(cl)) {
00281 MPI_IMPL_LOGGER.info("!!! ERROR newActiveSpmd: " + cl +
00282 " class has already been added to the list of user classes to instanciate ");
00283 } else {
00284 this.spmdClasses.add(cl);
00285 ArrayList<Object[]> parameters = new ArrayList<Object[]>(2);
00286
00287
00288
00289 parameters.add(0, null);
00290 parameters.add(1, params);
00291 this.spmdClassesParams.put(cl, parameters);
00292 }
00293 } catch (NodeException e) {
00294 e.printStackTrace();
00295 }
00296 }
00297
00298 public void newActive(String cl, Object[] params, int rank)
00299 throws ArrayIndexOutOfBoundsException {
00300 if (spmdClasses.contains(cl) ||
00301 (classes.contains(cl) &&
00302 (rank < this.classesParamsByRank.length) &&
00303 (this.classesParamsByRank[rank] != null))) {
00304 MPI_IMPL_LOGGER.info("!!! ERROR newActive: " + cl +
00305 " class has already been added to the list of user classes to instanciate ");
00306 } else if (rank < this.classesParamsByRank.length) {
00307 if (!classes.contains(cl)) {
00308 this.classes.add(cl);
00309 }
00310 this.classesParamsByRank[rank] = params;
00311 this.classesParams.put(cl, this.classesParamsByRank);
00312 } else {
00313 throw new ArrayIndexOutOfBoundsException("Rank " + rank +
00314 " is out of range while trying to instanciate class " + cl);
00315 }
00316 }
00317
00318 public ArrayList<String> getSpmdClasses() {
00319 return this.spmdClasses;
00320 }
00321
00322 public Hashtable<String, ArrayList<Object[]>> getSpmdClassesParams() {
00323 return this.spmdClassesParams;
00324 }
00325
00326 public ArrayList<String> getClasses() {
00327 return this.classes;
00328 }
00329
00330 public Hashtable<String, Object[]> getClassesParams() {
00331 return this.classesParams;
00332 }
00333
00334 public String getRemoteLibraryPath() {
00335 return getMPIProcess(this.mpiProcess).getRemotePath();
00336 }
00337 }