0

Can you see why the code from simulation.cpp marked with:
// clipped output start
and
// clipped output end
produces the clipped output below.(The "..." is where I deleted repeating output to make it more readable)
Letter key can be found below after output.

Initializing neural network...
SOMa memory usage: 155232 Bytes 44 Bytes each
cycle index0 cei0
f1n0c1cycle index0 cei0
f1n1c1cycle index0 cei0
f1n14c1cycle index0 cei0
f1n15c1cycle index0 cei0
f1n28c1cycle index0 cei0
f1n29c1cycle index0 cei0
f1n42c1cycle index0 cei0
f1n43c1cycle index0 cei0
f1n56c1cycle index0 cei0
f1n57c1cycle index0 cei0
f1n70c1cycle index0 cei0
f1n71c1cycle index0 cei0
f1n84c1cycle index0 cei0
f1n85c1cycle index0 cei0
...
f1n3516c1cycle index0 cei0
f1n3517c1cycle index0 cei0
f1n3522c1cycle index0 cei0
f1n3523c1
cei0
i0c0n0e00n1e00n2e00n3e00n4e00n5e00n6e00n7e00n8e00n9e00n10e00n11e00n12e00n13e00n14e00n15e00n16e00n17e00...n3526e00n3527e00

The lines:
f1n0c1cycle index0 cei0
f1n1c1cycle index0 cei0
f1n14c1cycle index0 cei0
f1n15c1cycle index0 cei0
...
should have been
f1n0c1cycle index0 cei0
f1n1c2cycle index0 cei0
f1n14c3cycle index0 cei0
f1n15c4cycle index0 cei0
...

I wanted this last line to read:
i0c840n0e10n1e10n2e00n3e00n4e00n5e00n6e00n7e00n8e00n9e00n10e00n11e00n12e00n13e00n14e10n15e10n16e00...

n - neuron id
f - forcefire
cei - current event index
i - cycle index
c - cycle event count

simulation.cpp

#include <iostream>
#include <sstream>
#include <string>
#include "simulation.h"
#include "connection.h"
#include "config.h"
#include "potentialqueue_local.h"
#include "easy_bmp/EasyBMP.h"

using namespace std;

unsigned int machine_y;
unsigned int machine_x;
unsigned int machines_per_side;

void setup_remote_queues(brain_t *brain_p);

int make_connections(int x, int y, neuron_t *neuron_p, int radius,
		      short pulse_strength, int conn_index, brain_t *brain_p);

unsigned int get_side_size(const config_t &config)
{
    // some locals
    unsigned int side_size = config.brain_field_side_size;

    // Adjust the side size
    machines_per_side = sqrt((double)machine_count);
    unsigned int temp_side_size = side_size / machines_per_side;
    if(temp_side_size * machines_per_side != side_size) {
		if(machine_id == MPI_MASTER) {
			cerr << side_size << "(the length of the grid side) "
			 << "must be a multiple of " << machines_per_side 
			 << " (the square root of number of machines)" << endl
			 << "Exiting..." << endl;
		}
		bad_exit();
    }
    side_size /= machines_per_side;

    return side_size;
}

unsigned int get_neuron_count(unsigned int side_size)
{
	return side_size * side_size*2;
}

void make_simple_brain(const config_t &config, brain_t &brain)
{
    // some locals
	unsigned int side_size = brain.side_size;
    short threshold = config.neuron_threshold;
    unsigned int e_radius = config.e_connection_radius;
    unsigned int i_radius = config.i_connection_radius;

 // clipped output start
    if(config_t::self_p->print_stats_flag && machine_id == MPI_MASTER)
	cout << "Initializing neural network..." << endl;

    // Determine location of our machine in the machine grid
    // (Machine grid is in row major order)
    machine_y = machine_id / machines_per_side;
    machine_x = machine_id - (machine_y * machines_per_side);

	// Set up remote queues
    setup_remote_queues(&brain);

#ifdef STATS_ON
    if(machine_id == MPI_MASTER)
	cout << "SOMa memory usage: " << brain.neuron_count * sizeof(neuron_t) * machine_count
		<< " Bytes " << sizeof(neuron_t) << " Bytes each" << endl;
#endif
    // Some definitions
    potentialqueue_local_t *queue_p = &(brain.loc_potentialqueue);

	int global_x_ref = machine_x * side_size;
	int global_y_ref = machine_y * side_size;
	int id;
	int global_x;
	int global_y;
	int cell_id;
	short stride;
	short stride_spacing = config.stride_spacing;
	short upper_stimuli_stride = config.upper_stimuli_stride * (1+stride_spacing);
	short lower_stimuli_stride = config.lower_stimuli_stride * (1+stride_spacing);

    // setup neurons (row major order)
	if (TESTRUN) {
		for(int y = 0; y < side_size; y++)
		{
			for(int x = 0; x < side_size; x++)
			{
				id = (y * side_size + x)*2;
				brain.neurons[id]
				.init(id, machine_id, x, y, E_NEURON, threshold, 0,
					config.pulse_duration, config.refractory_period, &brain);
				brain.neurons[id+1]
				.init(id+1, machine_id, x, y, I_NEURON, threshold, 0,
					config.pulse_duration, config.refractory_period, &brain);
			}
		}
	} else {
		for(int y = 0; y < side_size; y++)
		{
			global_y = global_y_ref + y;
			for(int x = 0; x < side_size; x++)
			{
				id = (y * side_size + x)*2;
				global_x = global_x_ref + x;
				cell_id = (global_y * config.brain_field_side_size + global_x)*2;
				if(global_y < config.brain_field_side_size / 2)  // upper half
					stride = upper_stimuli_stride;
				else											 // lower half
					stride = lower_stimuli_stride;

				if((cell_id % stride) == 0){
					event_t signala(id, 0, 0);
					queue_p->push_event(signala, 0);
				}
				if(((cell_id+1-stride_spacing) % stride) == 0) {
					event_t signalb(id+1, 0, 0);
					queue_p->push_event(signalb, 0);
				}

				brain.neurons[id].init(id, machine_id, x, y, E_NEURON, threshold,
					 0, config.pulse_duration, config.refractory_period, &brain);
				brain.neurons[id+1].init(id+1, machine_id, x, y, I_NEURON, threshold,
					 0, config.pulse_duration, config.refractory_period, &brain);
			}
		}
	}

    queue_p->show();
 // clipped output end

    cout << endl << "after neuron init" << endl;
    // Create connections
    unsigned int e_conn_count = 
		brain.neuron_count * ((e_radius * 2 + 1) * (e_radius * 2 + 1) - 1);
    unsigned int i_conn_count = 
		brain.neuron_count * ((i_radius * 2 + 1) * (i_radius * 2 + 1) - 1);
	#ifdef STATS_ON
    if(machine_id == MPI_MASTER)
	cout << "SYnapse memory usage: " << (e_conn_count + i_conn_count) * machine_count *
		sizeof(connection_t) << " Bytes " << sizeof(connection_t) << " Bytes each" << endl << endl;
	#endif
    brain.connections = new connection_t[e_conn_count + i_conn_count];

queue_p->show();
cout << endl << "after connections" << endl;

	// Go through each neuron
    int conn_index = 0;
	neuron_t *self_p;
	for(int y = 0; y < side_size; y++) {
		for(int x = 0; x < side_size; x++) {
			// Find our neuron
			id = (y * side_size + x)*2;
			self_p = &(brain.neurons[id]);
			conn_index = make_connections(x, y, self_p, e_radius,
							config.e_pulse_strength, conn_index, &brain);
			self_p = &(brain.neurons[id+1]);
			conn_index = make_connections(x, y, self_p, i_radius,
							config.i_pulse_strength, conn_index, &brain);
		}
    }

	if(config_t::self_p->print_stats_flag && machine_id == MPI_MASTER) {
		queue_p->show();
		cout << "Finished initialization" << endl;
	}
}

void setup_remote_queues(brain_t *brain_p)
{
    if(machine_count > 1)
    {
	unsigned int queue_size = brain_p->loc_potentialqueue.queue_size;
	int left_machine, up_machine, right_machine, down_machine;
	// left
	if(machine_x > 0)
	    left_machine = machine_x - 1;
	else
	    left_machine = machines_per_side - 1;
	brain_p->remotequeues_p[LEFT] =
	    new eventqueue_remote_t(queue_size, machine_y * machines_per_side + left_machine);
	// up
	if(machine_y > 0)
	    up_machine = (machine_y - 1) * machines_per_side;
	else
	    up_machine = (machines_per_side - 1) * machines_per_side;
	brain_p->remotequeues_p[UP] =
	    new eventqueue_remote_t(queue_size, up_machine + machine_x);
	// right
	if(machine_x < (machines_per_side - 1))
	    right_machine = machine_x + 1;
	else
	    right_machine = 0;
	brain_p->remotequeues_p[RIGHT] =
	    new eventqueue_remote_t(queue_size, machine_y * machines_per_side + right_machine);
	// down
	if(machine_y < (machines_per_side - 1))
	    down_machine = (machine_y + 1) * machines_per_side;
	else
	    down_machine = 0 * machines_per_side;
	brain_p->remotequeues_p[DOWN] =
	    new eventqueue_remote_t(queue_size, down_machine + machine_x);
	// leftup
	brain_p->remotequeues_p[LEFTUP] =
	    new eventqueue_remote_t(queue_size, up_machine + left_machine);
	// leftdown
	brain_p->remotequeues_p[LEFTDOWN] =
	    new eventqueue_remote_t(queue_size, down_machine + left_machine);
	// rightup
	brain_p->remotequeues_p[RIGHTUP] =
	    new eventqueue_remote_t(queue_size, up_machine + right_machine);
	// rightdown
	brain_p->remotequeues_p[RIGHTDOWN] =
	    new eventqueue_remote_t(queue_size, down_machine + right_machine);
    }
}

int make_connections(int x, int y, neuron_t *neuron_p, int radius,
					 short pulse_strength, int conn_index, brain_t *brain_p)
{
    // Set up some locals
    event_storage_t *queue_p = NULL;
    int side_size = brain_p->side_size;
    int i = 0;
	int neighbor_neuron;
	int x_abs;
	int x_rel;
	int y_abs;
	int y_rel;
	int id_y_offset;
	connection_t *connection_p; 

	// Create connections in the radius
	for (y_rel = -radius; y_rel <= radius; y_rel++) {
		y_abs = y + y_rel;
		id_y_offset = ((y_abs + side_size) % side_size) * side_size*2;
		for (x_rel = -radius; x_rel <= radius; x_rel++) {
			if(x_rel != 0 || y_rel != 0) {
				x_abs = x + x_rel;
				if ((machine_count == 1) ||
				   (x_abs >= 0 && x_abs < side_size && y_abs >= 0 && y_abs < side_size))
					queue_p = &(brain_p->loc_potentialqueue);
				else {
					if (y_abs < 0)
						queue_p = brain_p->remotequeues_p[UP];
					else if(y_abs >= side_size)
						queue_p = brain_p->remotequeues_p[DOWN];
					if (x_abs < 0)	{
						queue_p = brain_p->remotequeues_p[LEFT];
						if(y_abs < 0)
							queue_p = brain_p->remotequeues_p[LEFTUP];
						else if(y_abs >= side_size)
							queue_p = brain_p->remotequeues_p[LEFTDOWN];
					} else if(x_abs >= side_size) {
						queue_p = brain_p->remotequeues_p[RIGHT];
						if(y_abs < 0)
							queue_p = brain_p->remotequeues_p[RIGHTUP];
						else if(y_abs >= side_size)
							queue_p = brain_p->remotequeues_p[RIGHTDOWN];
					}
				}
				x_abs = (x_abs + side_size) % side_size;
				neighbor_neuron= id_y_offset + x_abs*2;
				connection_p = &(brain_p->connections[conn_index + i++]);
				connection_p->init(max(abs(x_rel), abs(y_rel)), neighbor_neuron, pulse_strength, queue_p);
				connection_p = &(brain_p->connections[conn_index + i++]);
				connection_p->init(max(abs(x_rel), abs(y_rel)), neighbor_neuron+1, pulse_strength, queue_p);
			}
		}
    }
	neuron_p->connections = &(brain_p->connections[conn_index]);
    neuron_p->connection_count = i;
	return conn_index + i;
}


void output_frame(long frame, const brain_t *brain_p, unsigned int side)
{
    frame--;
    
    BMP out;
    out.SetSize(side, side);
    out.SetBitDepth(24);

    // Set colors...
	neuron_t *neuron_p;
	unsigned int neuron_id;
	float potential;
	float threshold;
	float color;
	int x;
	int y;
/* posible problem with the following code:
	if there is only one neuron per x,y coordinate one color (red or blue)
	would not be set.  In that case you would need to init colors to 0. */
	if(config_t::self_p->output_images_flag == 1) {
		for(neuron_id = 0; neuron_id < brain_p->neuron_count; neuron_id++) {
			neuron_p = &(brain_p->neurons[neuron_id]);
			potential = max(0, (int)neuron_p->get_potential());
			threshold = neuron_p->get_threshold();
			color = min((int)potential, (int)threshold) / threshold * 255.0f;
			x = neuron_p->get_x();
			y = neuron_p->get_y();
			if (neuron_p->neuron_type == E_NEURON)
				out(x, y)->Red = color;
			else
				out(x, y)->Blue = color;
			out(x, y)->Green = 0;
		    
			// reset neuron
			neuron_p->must_or_just_fired = false;
		} 
	} else {
		for(neuron_id = 0; neuron_id < brain_p->neuron_count; neuron_id++) {
			neuron_p = &(brain_p->neurons[neuron_id]);
			x = neuron_p->get_x();
			y = neuron_p->get_y();
			if(neuron_p->must_or_just_fired) {
				color = 255;
				neuron_p->must_or_just_fired = false;  	// reset neuron
			} else
				color = 0;
			if (neuron_p->neuron_type == E_NEURON)
				out(x, y)->Red = color;
			else
				out(x, y)->Blue = color;
			out(x, y)->Green = 0;
		}
    }

    ostringstream oss, xss, yss;
    oss << frame;
    xss << machine_x;
    yss << machine_y;
    string dir(config_t::self_p->output_dir);
    dir = dir + "/" + oss.str() + "_" + xss.str() + "_" + yss.str() + ".bmp";
    out.WriteToFile(dir.c_str());
}

potentialqueue_local.h

#ifndef _POTENTIALQUEUE_LOCAL_H_
#define _POTENTIALQUEUE_LOCAL_H_

#include <vector>
#include "event_storage.h"
#include "neuron.h"
#include "eventqueue_remote.h"

// stores a potential sum for a neuron for a cycle
class combine_event_t
{
public:
	combine_event_t();
	void add_potential(short _potential);
	short pop_potential();
	void set_forcefire();
	bool pop_forcefire();
	void show();

private:
    short potential;
	bool forcefire;
};

class cycle_data_t
{
protected:
	typedef std::vector<combine_event_t> combine_events_t;

public:
	cycle_data_t();
	cycle_data_t(unsigned int size);
	~cycle_data_t();
	void show();

public:
	combine_events_t combine_events;
	unsigned int event_count;
};


class potentialqueue_local_t : public event_storage_t
{
protected:
    typedef std::vector<cycle_data_t> potentials_t;

public:
	potentialqueue_local_t();
	potentialqueue_local_t(unsigned int size, unsigned int neuron_count);
	virtual ~potentialqueue_local_t();
    void push_event(const event_t &signal, unsigned int delay);
    void execute_moment(unsigned long step, eventqueue_remote_t *remotequeues_p[8]);
	unsigned int get_capacity();
	void show();

protected:
    potentials_t potential_queue;

public:
    neuron_t *neurons; // array of neurons


};

#endif // _POTENTIALQUEUE_LOCAL_H_

potentialqueue_local.cpp

#include <iostream>
#include "config.h"
#include "potentialqueue_local.h"

using namespace std;

combine_event_t::combine_event_t()
{
	potential = 0;
	forcefire = false;
	cout << "f" << 0;
}

void combine_event_t::add_potential(short _potential)
{
	potential += _potential;
}

void combine_event_t::set_forcefire()
{
	forcefire = true;
	cout << "f" << forcefire;
}

bool combine_event_t::pop_forcefire()
{
	bool current_forcefire = forcefire;
	forcefire = false;
	cout << "f" << 0;
	return current_forcefire;
}

short combine_event_t::pop_potential()
{
	short current_potential = potential;
	potential = 0;
	return current_potential;
}

void combine_event_t::show()
{
	cout << "e" << forcefire << potential;
}

cycle_data_t::cycle_data_t()
{
}

cycle_data_t::cycle_data_t(unsigned int neuron_count) : combine_events(neuron_count)
{
	int id = 0;
	for(;id < neuron_count; id++) {
		combine_events[id] = combine_event_t();
	}
	event_count = 0;
}

cycle_data_t::~cycle_data_t()
{
}

void cycle_data_t::show()
{
	cout << "c" << event_count;
	int id = 0;
	for(;id < combine_events.size(); id++) {
		cout << "n" << id;
		combine_events[id].show();
	}
}

potentialqueue_local_t::potentialqueue_local_t()
{
}

potentialqueue_local_t::potentialqueue_local_t(unsigned int size, unsigned int neuron_count)
	: event_storage_t(size), potential_queue(size, cycle_data_t(neuron_count))
{
    // Initialize the queue
/*	int i;
    for(i = 0; i < size; i++) {
		potential_queue[i] = cycle_data_t(neuron_count);
    }*/
}

potentialqueue_local_t::~potentialqueue_local_t()
{
}

void potentialqueue_local_t::push_event(const event_t &signal, unsigned int delay)
{
	int cycle_index = (current_event_index + delay) % queue_size;
	cout << "cycle index" << cycle_index << " cei" << current_event_index << endl;
	cycle_data_t event_cycle = potential_queue[cycle_index];
	if (signal.potential == 0) {
		event_cycle.combine_events[signal.dest_neuron].set_forcefire();
		event_cycle.event_count++;
		future_events_count++;
		cout << "n" << signal.dest_neuron << "c" << event_cycle.event_count;
	}else {
		event_cycle.combine_events[signal.dest_neuron].add_potential(signal.potential);
		cycle_index = (cycle_index + signal.duration) % queue_size;
		event_cycle = potential_queue[cycle_index];
		event_cycle.combine_events[signal.dest_neuron].add_potential(-signal.potential);
		event_cycle.event_count += 2;
		future_events_count += 2;
	}
}

void potentialqueue_local_t::execute_moment(unsigned long step, eventqueue_remote_t *remotequeues_p[8])
{
    // Grab the moment
	cycle_data_t event_cycle = potential_queue[current_event_index];

    // Execute the moment

	unsigned int neuron_id = 0;
	unsigned int neuron_count = event_cycle.combine_events.size();
    for(; neuron_id < neuron_count; neuron_id++) {
		if(event_cycle.combine_events[neuron_id].pop_forcefire()) {  
			// Force neuron to fire
			neurons[neuron_id].force_fire(this, remotequeues_p);
			cout << "1";
		} else {
			// Add potential to subject neurons
			neurons[neuron_id].add_potential(event_cycle.combine_events[neuron_id].pop_potential());
			cout << "0";
		}
    }
	cout << " " << current_event_index << endl;

	current_events_count = event_cycle.event_count;
	event_cycle.event_count = 0;
    #ifdef STATS_ON
	future_events_count -= current_events_count;
    #endif

    if(config_t::self_p->print_stats_flag)
	std::cout << "Machine " << machine_id << ", step " << step + 1 
	<< ": performed " << current_events_count << " events" << std::endl;
}

unsigned int potentialqueue_local_t::get_capacity()
{
	int capacity = 0;
	int cycle_index;
    for(cycle_index = 0; cycle_index < queue_size; cycle_index++) {
		capacity += potential_queue[cycle_index].combine_events.capacity();
    }

	return capacity;
}

void potentialqueue_local_t::show()
{
	cout << endl << "cei" << current_event_index << endl;
	int cycle_index;
    for(cycle_index = 0; cycle_index < queue_size; cycle_index++) {
		cout << "i" << cycle_index;
		potential_queue[cycle_index].show();
		cout << endl << endl;
    }
}

event_storage.h

#ifndef _EVENT_STORAGE_H_
#define _EVENT_STORAGE_H_

// An event
class event_t
{
public:
    event_t();
    event_t(int _dest_neuron, short _potential, short _duration);
    
public:
    int dest_neuron;
    short potential;
    short duration; // values < 0 induce a the dest_neuron to force fire
};


class event_storage_t
{
public:
	event_storage_t();
	event_storage_t(unsigned int size);
	virtual ~event_storage_t();

    // Pushing events on the queue
    virtual void push_event(const event_t &signal, unsigned int delay) = 0;
	virtual unsigned int get_capacity() = 0;

    void update_moment();

	unsigned int get_future_events_count();
	unsigned int get_current_events_count();
    unsigned int queue_size;
	
protected:
    unsigned int current_event_index;
	unsigned int current_events_count;
	unsigned int future_events_count;

};

#endif // _EVENT_STORAGE_H_

event_storage.cpp

#include <iostream>
#include "event_storage.h"

event_t::event_t()
{
}

event_t::event_t(int _dest_neuron, short _potential, short _duration)
    : dest_neuron(_dest_neuron), potential(_potential), duration(_duration)
{
}

event_storage_t::event_storage_t()
{
}

event_storage_t::event_storage_t(unsigned int size)
{
    queue_size = size;
    current_event_index = 0;
	current_events_count = 0;
	future_events_count = 0;
}

event_storage_t::~event_storage_t()
{
}

void event_storage_t::update_moment()
{
    current_event_index = (current_event_index + 1) % queue_size;
}

unsigned int event_storage_t::get_future_events_count()
{
	return future_events_count;
}

unsigned int event_storage_t::get_current_events_count()
{
	return current_events_count;
}
2
Contributors
1
Reply
2
Views
7 Years
Discussion Span
Last Post by Salem
0

Wait, you want us to wade through a 700+ line haystack (which isn't even complete) looking for a needle which might not even be present in the subset you've posted?

Try using the debugger again.

You might also try simplifying some of those overly long and deeply nested functions.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.