org/objectweb/proactive/mpi/MPISpmdImpl.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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     // empty no-args constructor 
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         //  active
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         // as killMPI is an immediate service method it's possible that
00149         // stop method is called before start method on process thus interrupted exceptionis launched. 
00150         try {
00151             mpiProcess.stopProcess();
00152 
00153             //the sleep might be needed for processes killed
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         // check for the position of the MPIProcess in the mpiProcess
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     //  returns MPI process 
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     // returns the rank of MPI process in the processes hierarchie
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     //  --+----+---- methods for the future wrapping with control ----+----+----
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             // index=0 => Object[] type
00266             // index=1 => Object[][] type
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                 // index=0 => Object[] type
00288                 // index=1 => Object[][] type
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 }

Generated on Mon Jan 22 15:16:11 2007 for ProActive by  doxygen 1.5.1