Logo
Distributed Genetic Programming Framework
print print

File org.dgpf.gp.netvm.base.NetVMContext.java

Here you can find all the information about the file org.dgpf.gp.netvm.base.NetVMContext.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2006 Thomas Weise
 * 
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2006-07-06 15:00:45
 * Original Filename: org.dgpf.gp.netvm.NetVMContext.java
 * Version          : 1.0.0
 * Last modification: 2006-07-06
 *                by: Thomas Weise
 * 
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *                    
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */

 
package org.dgpf.gp.netvm.base;

import org.dgpf.gp.netvm.instructions.Send;
import org.dgpf.gp.vm.base.Program;
import org.dgpf.gp.vm.base.VMContext;
import org.dgpf.gp.vm.base.VMMemory;
import org.dgpf.gp.vm.instructions.ctrl.Push;
import org.sfc.events.IEventListener;
import org.sfc.math.Mathematics;
import org.sfc.math.stochastic.Randomizer;

/**
 * The context for virtual machines interconnected by a virtual network.
 *
 * @author Thomas Weise
 */

public class NetVMContext extends     VMContext
                          implements  INetVMInformation
  {
/**
 * The serial version uid.
 */

  private static final long serialVersionUID = 1;
  
/**
 * The array of networked virtual machines.
 */

  private NetVM[]             m_vms ;
/**
 * The maximum count of messages a virtual machine may send. 
 */

          int                 m_max_msgs   ;
/**
 * The current count.
 */

  private int                 m_cur_c ;
/**
 * The network implementation.
 */

  private NetworkImpl         m_net ;
/**
 * The network implemenation factory to be used.
 * @see #get_network_impl_factory()
 */

  private INetworkImplFactory m_net_factory;
/**
 * The id's to be used for our virtual machines.
 */

  private int[][]             m_ids ;
  
/**
 * Create a net vm context.
 * @param p_definition  The search definition to use as blueprint for the
 *                      internally stored data.
 * @param p_events      The event listener to be used to propagate
 *                      error events, if needed.
 */

  public    NetVMContext (final NetVMDefinition p_definition,
                          final IEventListener  p_events) 
    {
    super(p_definition, p_events);
    
    }

/**
 * Obtain the count of virtual machines to be simulated.
 * @return The count of virtual machines to be simulated.
 */

  public  final int get_vm_count()
    {
    return this.m_vms.length;
    }
  
  
/**
 * Assign this virtual machine context to the specified object.
 * @param p_data  The object to assign to.
 */

  @Override
  public void  assign  (final Object p_data)
    {
    NetVMDefinition l_nvd;
    NetVMContext    l_nvc;
    
    super.assign(p_data);
    
    if(p_data instanceof NetVMDefinition)
      {
      l_nvd = ((NetVMDefinition)p_data);
      this.set_network_impl_factory(l_nvd.get_network_impl_factory());      
      this.set_vm_count(l_nvd.get_vm_count());
      this.set_max_message_count(l_nvd.get_max_message_count());
      }
    else if(p_data instanceof NetVMContext)
      {
      l_nvc = ((NetVMContext)p_data);
      this.set_network_impl_factory(l_nvc.m_net_factory);
      this.set_vm_count(l_nvc.m_vms.length);
      this.set_max_message_count(l_nvc.m_max_msgs);
      }
    }
  
/**
 * Obtain one of the networked virtual machines.
 * @param p_index The index of the vm to be obtained.
 * @return  The networked virtual machine at that index.
 */

  public  final NetVM get_vm  (final int p_index)
    {
    return this.m_vms[p_index];
    }
  

/**
 * Get the next defined prime number.
 * @param p_int   The integer to start with.
 * @return  A new prime number.
 */

  private static  final int get_prime  (int p_int)
    {
    int l_i, l_m;

    if( (p_int & 1) == 0) p_int++;

mainloop:
    for(; ; p_int += 2)
      {
      l_i = 3;
      l_m = Mathematics.sqrt(p_int);
      while(l_i <= l_m)
        {
        if( (p_int % l_i) == 0 ) continue mainloop;
        l_i += 2;
        }
      return p_int;
      }
    }
  
  
/**
 * Initialize the id buffer.
 */

  private final void  init_id_buffer  ()
    {
    int     l_sim_count, l_vm_count;
    int     l_s, l_incr, l_i;
    int[][] l_ids;
    int[]   l_id;
    
    l_sim_count = this.get_simulation_count();
    l_vm_count  = this.get_vm_count();
    
    if((l_sim_count > 0) && (l_vm_count > 0))
      {
      l_ids  = this.m_ids;
      l_s    = (Integer.MAX_VALUE >>> 2);
      l_incr = (((Integer.MAX_VALUE >>> 1) / (l_vm_count * l_sim_count))+1);
      
      l_ids  = new int[l_sim_count][];
      
      for(--l_sim_count; l_sim_count >= 0; l_sim_count--)
        {
        l_ids[l_sim_count] = l_id = new int[l_vm_count];
        for(l_i = (l_vm_count-1); l_i >= 0; l_i--)
          {
          l_id[l_i] = get_prime(l_s);
          l_s      += l_incr;
          }
        }
      
      this.m_ids = l_ids;
      }
    }
  
/**
 * Randomize the id buffer.
 */

  private final void  randomize_id_buffer ()
    {
    int         l_sim_count, l_vm_count, l_i, l_j, l_y, l_x, l_s;
    int[][]     l_ids;
    Randomizer  l_r;
        
    l_sim_count = this.get_simulation_count();
    l_vm_count  = this.get_vm_count();
    l_r         = this.get_randomizer();
    l_ids       = this.m_ids;
    
    for(l_i = (l_sim_count-1); l_i >= 0; l_i--)
      {
      for(l_j = (l_vm_count-1); l_j >= 0; l_j--)
        {
        do
          {
          l_y = l_r.nextInt(l_sim_count);
          } while( (l_i == l_y) && (l_sim_count > 2) );
        l_x = l_r.nextInt(l_vm_count);
        
        l_s             = l_ids[l_y][l_x];
        l_ids[l_y][l_x] = l_ids[l_i][l_j];
        l_ids[l_i][l_j] = l_s;
        }
      }
    }
  
/**
 * Set the count of simulations to be performed for every individual
 * (genotype) to determine a stable fitness value.
 * @param p_simulation_count  How many simulations will be needed
 *                            per individual.
 */

  @Override
  public synchronized void set_simulation_count(final int p_simulation_count)
    {
    int l_c;
    
    l_c = this.get_simulation_count();
    super.set_simulation_count(p_simulation_count);
    
    if( (this.get_simulation_count() > l_c) && (this.m_vms != null) )
      {
      this.init_id_buffer();
      }
    }
  
/**
 * Set the count of virtual machines to be simulated.
 * @param p_vm_count  The new count of virtual machines to be simulated.
 */

  public  final void set_vm_count(final int p_vm_count)
    {
    NetVM[] l_v;
    int     l_i;
    
    if(p_vm_count > 0)
      {      
      l_v = this.m_vms;
      if(l_v != null)
        {
        if(l_v.length == p_vm_count) return;
        
        for(l_i = (l_v.length-1); l_i >= 0; l_i--)
          {
          l_v[l_i].dispose();
          }
        }
            
      l_v = new NetVM[p_vm_count];
      for(l_i = (p_vm_count-1); l_i >= 0; l_i--)
        {
        l_v[l_i] = this.create_vm(l_i);
        }
      this.m_vms = l_v;
            
      if((this.m_ids == null) || (this.m_ids[0].length < p_vm_count))
        {
        this.init_id_buffer();
        }
      
      if(this.m_net != null) this.m_net.set_vm_count(p_vm_count);
      }    
    }
  
/**
 * Creates a new networked virtual machine to be used inside this context.
 * @param p_index A unique index identifier for the vm to be created.
 * @return A new networked virtual machine to be used inside this context.
 */

  protected NetVM create_vm(final int p_index)
    {
    return new NetVM(this);
    }
  

/**
 * This method needs to be called whenever the internal caches (virtual
 * machines for example) need to be resetted.
 */

  @Override
  protected void  reset_caches()
    {
    int     l_i;
    NetVM[] l_v;
        
    l_v = this.m_vms;
    if(l_v != null)
      {
      for(l_i = (l_v.length-1); l_i >= 0; l_i--)
        {
        l_v[l_i].dispose();
        }
      }
    
    super.reset_caches();
    
    if(l_v != null)
      {      
      for(l_i = (l_v.length-1); l_i >= 0; l_i--)
        {
        l_v[l_i] = this.create_vm(l_i);
        }
      }
    
    this.m_net.reset_caches();
    }
  
  
/**
 * Obtained the total count of consumed ticks of the (or all if more than
 * one) simulated virtual machines.
 * @return The total count of consumed ticks of the (or all if more than
 *         one) simulated virtual machines.
 */

  public  final long    get_consumed_ticks  ()  
    {
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_consumed_ticks();
      }
    
    return l_l;
    }
  

/**
 * Obtained the total count of consumed costs of the (or all if more than
 * one) simulated virtual machines.
 * @return The total count of consumed costs of the (or all if more than
 *         one) simulated virtual machines.
 */

  public  final double  get_consumed_costs  () 
    {
    int     l_i;
    NetVM[] l_v;
    double  l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_consumed_costs();
      }
    
    return l_l;
    }

  

/**
 * Obtained the total size of consumed memory of the (or all if more than
 * one) simulated virtual machines.
 * @return The total size of consumed memory of the (or all if more than
 *         one) simulated virtual machines.
 */

  public  final int     get_peak_memory () 
    {
    int     l_i;
    NetVM[] l_v;
    int     l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_peak_memory();
      }
    
    return l_l;
    }
  

/**
 * Obtained the total count of used frames of the (or all if more than
 * one) simulated virtual machines.
 * @return The count of used frames of the memory of the (or all if more
 *         than one) simulated virtual machines.
 */

  public  final int     get_peak_frames () 
    {
    int     l_i;
    NetVM[] l_v;
    int     l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_peak_frames();
      }
    
    return l_l;
    }
  
/**
 * Obtain the count a procedure call failed due to insufficient free frames
 * which reflects a stack overflow in normal programming environments.
 * @return The count a procedure call failed due to insufficient free
 *         frames which reflects a stack overflow in normal programming
 *         environments.
 */

  public  final long    get_frame_errors  ()
    {
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_frame_errors();
      }
    
    return l_l;
    }
  
/**
 * Obtain the count of invalid write operations, that is, write operations
 * that surpass the maximum memory address available.
 * @return The count of invalid write operations, that is, write operations
 * that surpass the maximum memory address available.
 */

  public  final long get_mem_errors       ()
    {
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_mem_errors();
      }
    
    return l_l;
    }
  
  

  
/**
 * Obtain the count of messages successfully delivered.
 * @return The count of messages successfully delivered.
 */

  public  final long    get_delivered()
    {
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_delivered();
      }
    
    return l_l;
    }
  
/**
 * Obtain the count of messages lost due to busyness at the receiving node.
 * @return The count of messages lost due to busyness at the receiving node.
 */

  public  final  long    get_lost_at_receive()
    {
    
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_lost_at_receive();
      }
    
    return l_l;
    }
  

/**
 * Obtain the maximum count of messages a virtual machine may send.
 * @return  The maximum count of messages a virtual machine may send.
 */

  public  final int get_max_message_count ()
    {
    return this.m_max_msgs;
    }
  

/**
 * Set the maximum count of messages a virtual machine may send.
 * @param p_max_msgs  The next maximum count of messages a virtual machine
 *                    may send.
 */

  public  final void set_max_message_count (final int p_max_msgs)
    {
    if(p_max_msgs > 0) this.m_max_msgs = p_max_msgs;
    }
  

/**
 * Obtain the count of messages sent by this virtual machine.
 * @return The count of messages sent by this virtual machine.
 */

  public  final int get_successful_sends ()
    {
    int     l_i;
    NetVM[] l_v;
    int     l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_successful_sends();
      }
    
    return l_l;
    }
  
/**
 * Obtain the count of messages that could not be sent because the maximum
 * allowed count of messages has already been exceeded by this virtual
 * machine.
 * @return The count of messages that could not be sent because the maximum
 *         allowed count of messages has already been exceeded by this
 *         virtual machine. 
 */

  public  final long  get_failed_sends()
    {
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_failed_sends();
      }
    
    return l_l;
    }
  
/**
 * The minimum count of procedures. You may set this count to some value
 * greater than one if needing asynchronous io.
 * @param p_min_proc_count  The new minimum procedure count. You may set
 *                          this count to some value greater than one if
 *                          needing asynchronous io.
 */

  @Override
  public  void  set_min_proc_count  (final int p_min_proc_count)
    {
    if(p_min_proc_count > NetVMUtils.RECEIVE_INTERRUPT)
      {
      super.set_min_proc_count(p_min_proc_count);
      }
    }
  

  
/**
 * This method is called right before a simulation starts. It allows you
 * to perform some simulation-specific initialization.
 * The simulation-setup of the fitness functions will also be invoked here.
 * @param p_index   The index number of the current simulation. The first
 *                  simulation will have index 0, the second will have
 *                  index 1 and so on.
 * @see #end_simulation(int)
 */

  @Override
  protected void begin_simulation  (final int p_index)
    {
    Program     l_c;
    NetVM[]     l_nvm;
    int         l_i;
    int[]       l_ids;
    NetVM       l_vm;
    
    l_nvm         = this.m_vms;
    l_i           = l_nvm.length;    
    this.m_cur_c  = l_i;
    
    
    l_c           = this.get_current();
    l_ids         = this.m_ids[p_index];
    for(--l_i; l_i >= 0; l_i--)
      {
      l_vm      = l_nvm[l_i];
      l_vm.m_id = l_ids[l_i];
      l_vm.init(l_c);
      }
    
    this.m_net.init_network(p_index);
    
    super.begin_simulation(p_index);    
    }
  
/**
 * This method is called right when a simulation has finished.
 * It performs some simulation-based cleanup.
 * @param p_index   The index number of the current simulation. The first
 *                  simulation will have index 0, the second will have
 *                  index 1 and so on.
 * @see #begin_simulation(int)
 */

  @Override
  protected void    end_simulation    (final int p_index)
    {
    this.m_net.end_network(p_index);
    super.end_simulation(p_index);
    }
  
/**
 * This method delivers a message send.
 * @param p_source  The source vm.
 * @param p_data    The message data.
 */

  final void  deliver (final NetVM    p_source,
                             VMMemory p_data)
    {
    if(this.m_net.deliver(p_source, p_data))
      {    
      this.m_cur_c = this.m_vms.length;
      this.m_vms[0].m_last = false;
      }
    }
  

  
/**
 * Perform a single clock tick.
 * @return  <code>true</code> if and only if the program wasn't terminated
 *          yet and an instruction was executed.
 */

  public  boolean tick  ()
    {
    NetVM[]     l_v;
    NetVM       l_x;
    int         l_c, l_i, l_d;
    Randomizer  l_r;
    
    l_v  = this.m_vms;
    l_r  = this.get_randomizer();
    l_i  = 0;
    l_d  = this.m_cur_c;
    
    while(l_i < l_d)
      {
      l_c = l_r.nextInt(l_d);
      l_x = l_v[l_c];
      
      if(l_x.tick())
        {
        l_d = this.m_cur_c;
        }
      else
        {
        l_d          = this.m_cur_c;
        l_v[l_c]     = l_v[--l_d];
        l_v[l_d]     = l_x;
        this.m_cur_c = l_d;
        l_x.m_last   = false;
        
        if(l_d == 1)
          {
          l_v[0].m_last = true;
          }
        }
      
      l_i++;
      }
    
    return (l_d > 0);
    }
  
/**
 * Perform some simulation steps. This method is used to simulate the
 * current individual.
 * @param p_steps       The count of stepps suggested to run now in a row.
 * @return  <code>true</code> if everything went ok, <code>false</code> if
 *          something failed.
 */

  @Override
  protected boolean  simulate  (long p_steps)
    {
    for(; p_steps > 0; p_steps--)
      {
      if(!(this.tick())) return false;
      }
    
    return true;
    }
  
  

/**
 * Obtain the count of send operations failed because the send buffer was
 * empty.
 * @return The count of send operations failed because the send buffer was
 *         empty.
 */

  public  final long  get_empty_sends ()
    {
    int     l_i;
    NetVM[] l_v;
    long    l_l;
    
    l_v = this.m_vms;
    l_l = 0;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      l_l += l_v[l_i].get_empty_sends();
      }
    
    return l_l;
    }
  
/**
 * Prepare the context for the given individual. This method is called
 * before any simulation concerning the given individual is done. It
 * provides the context the opportunity to prepare some information or
 * other data. This function also invokes the sanity checking of the
 * fitness functions.
 * @param p_individual  The individual to prepare for.
 * @return  <code>true</code> if everything is ok and we cal begin the
 *          simulations, <code>false/<code> if something is wrong and no
 *          simulations should be performed.
 * @see #get_current()
 * @see #end_individual()
 */

  @Override
  protected boolean begin_individual(final Program p_individual)
    {
    boolean l_b;
    
    l_b = super.begin_individual(p_individual);
    
    if(l_b && (p_individual.get_count(Send.class) > 0) &&
              (p_individual.get_count(Push.class) > 0))
      {
      this.randomize_id_buffer();
      return true;
      }
    
    return false;
    }
 
/**
 * Obtain the network implementation factory.
 * @return The network implementation factory used to power up the network
 *         simulation.
 */

  public  final INetworkImplFactory get_network_impl_factory  ()
    {
    return this.m_net_factory;
    }
  

  
/**
 * Set the network implementation factory to be used by contexts derived
 * from this definition.
 * @param p_factory   The network implementation factory to be used by
 *                    contexts derived from this definition.
 */

  public final void  set_network_impl_factory(
                          final INetworkImplFactory p_factory)
    {
    if((p_factory != null) && (p_factory != this.m_net_factory))
      {
      this.m_net_factory = p_factory;
      if(this.m_net != null) this.m_net.dispose();
      this.m_net = p_factory.create(this);
      }
    }
  
/**
 * Obtain the id of the <code>p_index</code>'th virtual machine running in
 * the network.
 * @param p_index The index of the vm we want to know the id of.
 * @return The id of the <code>p_index</code>'th virtual machine running in
 *         the network.
 */

  public  final int get_vm_id (final int p_index)
    {
    return this.m_vms[p_index].m_id;
    }
  
/**
 * Check whether an id is valid or not.
 * @param p_id  The id to check.
 * @return  <code>true</code> if and only if the id is a valid virtual
 *          machine id in the current simulation.
 */

  public  final boolean is_valid_id (final int p_id)
    {
    return (this.get_id_index(p_id) >= 0);
    }

/**
 * Obtain the index of the specified id.
 * @param p_id  The id to check.
 * @return  <code>-1</code> if and only if the id is a invalid, or a number
 *          denoting its index in the id list. The smaller this number is,
 *          the bigger is the id.
 */

  public  final int get_id_index (final int p_id)
    {
    int     l_i;
    NetVM[] l_v;
    
    l_v = this.m_vms;
    for(l_i = (l_v.length-1); l_i >= 0; l_i--)
      {
      if(l_v[l_i].m_id == p_id) return l_i;
      }
    
    return -1;
    }
  }

File Information:

file name:NetVMContext.java
package:org.dgpf.gp.netvm.base
qualified name:org.dgpf.gp.netvm.base.NetVMContext.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/dgpf/gp/netvm/base/NetVMContext.java
size:21.853 KB (22378 B)
uploaded: 2015-07-22 04:10:56 GMT+0000
last update: 2006-08-21 06:45:19 GMT+0000
last access: 2017-11-20 18:51:10 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2015-07-22 04:10:53 GMT+0000 served at 2017-11-20 18:51:10 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo