A practical introduction to OptimalGrid - Part IV  
 

(Post 01/09/2006) In this tutorial, we described the OptimalGrid system and showed how it enables you to use a Grid to solve a problem. You need only to write the Java code to describe the problem at the level of the cell and its interaction with its neighbors. The OptimalGrid system then handles all of the details of mapping this into a problem with thousands or millions of cells and running it on a computing Grid consisting of hundreds of computers.

Các phần đã đăng:

Section 6. Summary

In this tutorial, we described the OptimalGrid system and showed how it enables you to use a Grid to solve a problem. You need only to write the Java code to describe the problem at the level of the cell and its interaction with its neighbors. The OptimalGrid system then handles all of the details of mapping this into a problem with thousands or millions of cells and running it on a computing Grid consisting of hundreds of computers.

We described how to install OptimalGrid and run a sample problem.

Finally, we went step by step through the code you would write to implement a solution to your own unique problem.

Section 7. Appendices

Code listing for OPCEden class

Following is the complete code for the OPCEden class, except that the propagation() and localInteraction() methods are shown next.

// OPCEden.java
package com.ibm.almaden.smartgrid.apps.eden;
/*
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT IBM Corp. 2002 All rights reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule
** Contract with IBM Corp.
**
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.Vector;
import com.ibm.almaden.smartgrid.AppUtilsGeneric;
import com.ibm.almaden.smartgrid.Coordinates;
import com.ibm.almaden.smartgrid.EntityAbstract;
import com.ibm.almaden.smartgrid.OPCAbstract;
import com.ibm.almaden.smartgrid.AppUtilsAbstract;
import com.ibm.almaden.smartgrid.VppAbstract;
import com.ibm.almaden.smartgrid.util.ConfigFile;
import com.ibm.almaden.smartgrid.util.Debug; /** for xml output
*/
import org.jdom.Element;
// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// || Class OPCEden (Original Problem Cell ||
// ||||||||||||||||||||||||||||||||||||||
/**
**
**
** OPCEden.java defines the "Original Problem Cell"
* for the Eden model of bacteria growth.
**
* OPCEden extends OPCAbstract
*
* The Eden model OPC describes a region of space representing the
surface of a petri dish. If may contain entity objects such as bacteria,
nutrients, etc. It may also have local properties that affect the behavior
(reproduction rate) of the bacteria. The required methods, propagate(),
and localInteraction(), determine how these entities reproduce and
spread to neighboring OPCs based on other entities and properties
that may be present.
*
** An original problem cell is an "atomic" problem unit -- piece
** of the problem that represents a unit of computation (like an
** area (2D) or a volume (3D) that is exposed to some external
** interactions over time). OPCs interact with their
** neighbors -- sharing information to produce a larger (big picture)
** computation. That means, though, that an OPC must communicate
** its state with its neighboring OPCs at the end of each "time slice"
** so that the neighbor interaction can be computed in order to produce
** the next frame.
**
* The creator of a problem computation sets up the collection of
** OPCs and also separates groups of OPCs into computable partitions
** (called Variable Problem Partitions -- VPPs) that are given to the
** compute agents to, well, compute. Each VPP (mostly running on
a separate machine) must communicate its edges to the other VPPs
**
*
* OPCs are stored in collections of class OPCCollection.
**
**
* For a picture showing how OPCs fit into VPPs refer
to {@link OPCAbstract}.
*
*
* The Eden model of bacterial growth.
*
* In the Eden model, each OPC represents a cell that may
* contain an entity that represents one of 3 kinds of bacteria; A, B or C.
* In this case, the interaction method causes A eats B, B eats C,
* and C eats A.
* In addition, the entities can propagate to their neighbors with
* a specified probability where it will either be eaten by the neighbor or
* eat the neighbor.
*
*
** @author >A HREF="mailto:kaufman@almaden.ibm.com"<James Kaufman>/A<
** @author >A HREF="mailto:toby@almaden.ibm.com"<Toby Lehman>/A<
** @author >A HREF="mailto:glenn@almaden.ibm.com"<Glenn Deen>/A<
** @version $Revision: 1.3 $ $Date: 2003/05/22 15:19:32 $
** @see com.ibm.almaden.smartgrid.OPCAbstract
** @see com.ibm.almaden.smartgrid.OPCCollection
** @see EntityEden
** @see EntityAbstract
*/
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //
public class OPCEden extends OPCAbstract implements Serializable, Cloneable {
static final long serialVersionUID = -41318389852439458L;
static private final String _className = "OPCEden"; /**************************************************************************
** OPCEden ** (empty)
*********/
/**
** This class OPCEden creates an original problem cell
** for a predator prey calculation
***************************************************************************
*/
public OPCEden() {
super._occupants = null;
super._properties = null;
}
/**************************************************************************
** processNeighbor **
*******************/
/**
* Given a neighboring OPC, see if any of the entities from it
* will propagate to the list of Occupants for the current OPC
*
* @param OPCNeighbor OPC that is a neighbor of the current OPC
* @param newOccupants ArrayList that contains current competing entities.
* @param vpp_ The parent Vpp.
* @param iteration_ The current iteration number
* @return void
***************************************************************************
*/
private void processNeighbor(OPCEden OPCNeighbor, ArrayList newOccupants,
VppAbstract vpp_, int iteration_, Random rnd_) {
ArrayList hisOccupants = OPCNeighbor.getOccupants();
if (hisOccupants.size() > 0) {
int numOccupants = hisOccupants.size();
// look at all of his occupants
for (int j = 0; j <numOccupants; j++) {
// get the occupant as an entity
EntityEden ea = (EntityEden) (hisOccupants.get(j));
// generate the propagation probability for this entity
double prob = getPropagationProb(ea, rnd_);
if ((prob > ea.getPropProb()) && \
(entityNotPresent(ea, newOccupants))) {
// if probability threshold exceeded and not already an occupant
EntityAbstract child = ea.getChild();
//vpp_._valueMonitor.accumulateValueData\
(iteration_, child.getEntityID(), 1);
// add to the new list of Occupants
newOccupants.add(child);
}
} // for j (num occupants)
} // size > 0
}
/**************************************************************************
** getPropagationProb **
*******************/
/**
* Generate the propagation probability for some entity
* given the entity and properties of this OPC.
*
* If the OPC does not have any properties, then the next generated
* random probability is returned. Otherwise the Property object is obtained
* from the Properties collection and the probability is calculated based
* on the Property.
* This (somewhat unrealistic) method assumes that the first Property contains
* a probability value. If the property ID matches \
the entity ID (type of bacteria)
* then this value is added to the calculated propagation probability,
* otherwise it is subtracted.
*
* @param ea entityAbstract
* @param rnd_ Random rnd_
* @return probability
***************************************************************************
*/
private double getPropagationProb(entityAbstract ea, Random rnd_) {
double prob = rnd_.nextDouble(); int entityID = ea.getentityID();
int numProps = 0;
if (_properties != null) {
numProps = _properties.size();
if (numProps > 0) {
PropertyEden p = (PropertyEden) _properties.get(0);
if (p.getPropertyID() == entityID) {
prob += p.getProbability();
if (prob > 1.0)
prob = 1.0;
} else {
prob -= p.getProbability();
if (prob <0.0)
prob = 0.0;
}
}
}
return prob;
}
/**
*******************************************************************************
* cloneOPC()
* required method to return a clone of the OPC with a
* copy of those objects in this OPC that may be modified.
*
*
* Eden model requires that we do a deep copy of the occupants only
*
* The following variables are not required
* in this eden model clone method but could be required
* in other synchronized applications
*
* newOPC._properties = new Vector();
* newOPC._loc = this._loc;
* newOPC._index = this._index;=
* newOPC._edgeCollectionID = this._edgeCollectionID;
* newOPC._edgeIndex = this._edgeIndex;
*
* @return a clone of this OPC
**/
public OPCAbstract cloneOPC() {
OPCEden newOPC = null;
try {
newOPC = (OPCEden)this.clone();
} catch (CloneNotSupportedException cns) {
Debug.error(_className+"cloneOPC ","Error",cns);
}
// do deep copy of occupants ArrayList.
ArrayList newOccupants = new ArrayList();
ArrayList oldOccupants = this.getOccupants();
if (oldOccupants == null || oldOccupants.size() == 0) {
newOPC.setOccupants(null);
} else {
newOccupants.addAll(oldOccupants);
newOPC.setOccupants(newOccupants);
} // not null
return newOPC;
};
/**************************************************************************
** entityNotPresent **
*********************/
/**
* Test an EntityEden object against an Array list and return "true" if
* there is No EntityEden of the same type already in the ArrayList
*
*
* @param ea_ An abstract entity
* @param a_ An ArrayList of entities (EntityEden objects)
*
* @return true if this type of entity NOT already present.
*
* ***************************************************************************
*/
public boolean entityNotPresent(EntityAbstract ea_, ArrayList a_) {
// first make sure this class object is not already present
int classID = ea_.getEntityID();
int numEnts = a_.size();
for (int i = 0; i < numEnts; i++) {
EntityAbstract obj = (EntityAbstract)a_.get(i);
int classID2 = obj.getEntityID();
// if already there, punt
if (classID==classID2) return false;
}
// else
return true;
}
/**************************************************************************
** initFromXML() **
*******************/
/**
* This method is only needed if we defined new instance variable
* for this class. Refer to EntityEden for an example of the required coding.
*
***************************************************************************
*/
// public void initFromXML(Element OPCElement_) {
// super.initCommonSubsetFromXML(OPCElement_);
// } // getXML()
/**************************************************************************
** getXML() **
*******************/
/**
* This method is only needed if we defined new instance variable
* for this class. Refer to EntityEden for an example of the required coding.
***************************************************************************
*/
// public Element getXML() {
// Element OPCElement = super.getXmlElement();
// return OPCElement;
// } // getXML()
/**************************************************************************
** toString **
**************/
/**
** Provide good debug output This will pick up the output from the
* OPCAbstract.toString() method and then append some information
* about the occupants and properties.
**
** @return String that represents the values in the object
***************************************************************************
*/
public String toString() {
// Put everything into a string buffer first (pick the right size),
// and then turn into a string at the end.
//
StringBuffer sb = new StringBuffer(64);
sb.append(super.toString());
sb.append(" OPCEden: ");
if (_occupants != null) {
sb.append("#Occupants="+_occupants.size());
}
if (_properties != null) {
sb.append(" #Properties="+_properties.size());
}
return sb.toString();
} // end toString()
} // Class OPCEden

Code listing for OPCEden Propagate()

Following is the complete code for the OPCEden propagate() method.

/**************************************************************************
** propagate **
**************/
/**
*
* All OPCs communicate with neighbors (local or remote)
* propagate() for OPCEden determines what entities are
* present at neighboring sites and clones them, adding any
* new types of entities to this site. There is never more
* than one type of entity represented. This step is done
* before the entities are allowed to compete (eat each other)
* which is done later by the localInteraction method.
* Following that method call we know what bacteria spread to
* what OPCs - and which ones survived.
*
* Note that the new "occupant" list is returned but not
* stored back into the OPC. This is so that when the next
* OPC is processed and they look back at me (as a neighbor)
* they will see my old occupant status.
*
* In general, in the propagate() method you only want to
* manipulate the list of occupants and not modify the OPC
* or the properties. Use the localInteraction() method to
* make changes to the OPC and Properties.
*
* @param collectionIndex_ The Index into the array of
* OPCCollections for the
* OPCCollection that this OPC belongs to.
* @param vpp_ The parent VPP
* @param iteration_ Current iteration (cycle) number
* @param rnd_ Random number generator.
*
* @return Updated collection of occupants (entities) for this OPC.
*
***************************************************************************
*/
public synchronized ArrayList propagate(int collectionIndex_, \
VppAbstract vpp_, int iteration_, Random rnd_) {
String methodName = _className + ".propagate ";
ArrayList newOccupants = new ArrayList();
ArrayList oldOccupants = super.getOccupants();
// uncomment the following if we wanted to use the appUtils class.
//AppUtilsGeneric appUtil = \
(AppUtilsGeneric)OPCAbstract.getAppUtils();
if (oldOccupants.size() > 0)
newOccupants.addAll(oldOccupants);
// || ==============================================||
// || = Get all neighbors (whether local or remote =========||
// || ==============================================||
ArrayList tempArray = this.getAllOPCNeighbors(collectionIndex_, vpp_);
Iterator iter = tempArray.iterator();
while (iter.hasNext()) {
// get the collection element
OPCEden OPCNeighbor = (OPCEden) iter.next();
// propagate neighbors entities to newOccupants
processNeighbor(OPCNeighbor,newOccupants,vpp_,iteration_,rnd_);
} // while hasNext
// return the new list of occupants
return newOccupants;
} // propagate()

Code listing for OPCEden localInteraction()

Following is the complete code for the OPCEden localInteraction() method.

/**************************************************************************
** localInteraction **
**********************/
/**
* After we learn from propagate which species of bacteria are
* competing to live on this site in the next time step, we cycle
* through all the competing occupants of this OPCEden
* and see if, for each occupant, there is a predator that
* eats the occupant.
*
* We then loop through the occupants again and remove the dead
* bacteria. We then call the updateCount method which updates
* the information about the number of entities for the chart.
*
* Finally we store the current list of occupants back into the OPC.
*
*
* @param vpp_ The parent Vpp.
* @param iteration_ The current iteration number
* @param occupants_ ArrayList of the new entities for this OPC
* This is the ArrayList of occupants that was returned by the
propagate method. We are required to store it into the OPC.
*
* @return void
*
***************************************************************************
*/
public synchronized void localInteraction(VppAbstract vpp_, \
int iteration_, ArrayList occupants_) {
String methodName = _className + ".localInteraction ";
// are there any occupants?
if ((occupants_ != null) && (!occupants_.isEmpty())) {
// yes, then loop through them
for (int i = 0; i <occupants_.size(); i++) {
for (int j = 0; j < occupants_.size(); j++) {
if (i == j) continue;
EntityEden obj1 = (EntityEden) occupants_.get(i);
EntityEden obj2 = (EntityEden) occupants_.get(j);
// obj2._foodID contains the type of food that obj2 eats.
// so if it matches the EntityID for obj1, then obj2 eats obj1.
if (obj2.isAlive() && (obj2.getFoodID() == obj1.getEntityID())) {
//yes, then obj1 is dead
obj1.setAlive(false);
}
} // for j
} // for i. First loop checks for predators
// finally loop through one more time and remove the dead ones
for (Iterator iter = occupants_.iterator(); iter.hasNext();) {
EntityEden obj1 = (EntityEden) iter.next();
if ( ! obj1.isAlive() ) {
iter.remove();
}
} // iterate. Second loop removed dead occupants
} // end if not null or empty
// update running totals of entities
super.updateCounter(vpp_, iteration_, occupants_);
// update the OPCAbstract
super.setOccupants(occupants_);
} //localInteraction()

(Copyright IBM Corporation)


 
 

 
     
 
Công nghệ khác:


A practical introduction to OptimalGrid - Part IIIA practical introduction to OptimalGrid - Part II
A practical introduction to OptimalGrid - Part INhững Keyboard cho dân chơi Game - phần 1
Kiến trúc đa nhân, thời đại mới của vi xử lý (Phần II)Kiến trúc đa nhân, thời đại mới của vi xử lý (Phần I)
  Xem tiếp    
 
Lịch khai giảng của hệ thống
 
Ngày
Giờ
T.Tâm
TP Hồ Chí Minh
Hà Nội
 
   
New ADSE - Nhấn vào để xem chi tiết
Mừng Sinh Nhật Lần Thứ 20 FPT-APTECH
Nhấn vào để xem chi tiết
Bảng Vàng Thành Tích Sinh Viên FPT APTECH - Nhấn vào để xem chi tiết
Cập nhật công nghệ miễn phí cho tất cả cựu sinh viên APTECH toàn quốc
Tiết Thực Vì Cộng Đồng
Hội Thảo CNTT
Những khoảnh khắc không phai của Thầy Trò FPT-APTECH Ngày 20-11