Skip to content
Snippets Groups Projects
Select Git revision
  • 4bd6f0978be628903eadeaa29c938c31956ba855
  • master default protected
  • tut_ring_allen
  • docs_furo
  • docs_reorder_cable_cell
  • docs_graphviz
  • docs_rtd_dev
  • ebrains_mirror
  • doc_recat
  • docs_spike_source
  • docs_sim_sample_clar
  • docs_pip_warn
  • github_template_updates
  • docs_fix_link
  • cv_default_and_doc_clarification
  • docs_add_numpy_req
  • readme_zenodo_05
  • install_python_fix
  • install_require_numpy
  • typofix_propetries
  • docs_recipe_lookup
  • v0.10.0
  • v0.10.1
  • v0.10.0-rc5
  • v0.10.0-rc4
  • v0.10.0-rc3
  • v0.10.0-rc2
  • v0.10.0-rc
  • v0.9.0
  • v0.9.0-rc
  • v0.8.1
  • v0.8
  • v0.8-rc
  • v0.7
  • v0.6
  • v0.5.2
  • v0.5.1
  • v0.5
  • v0.4
  • v0.3
  • v0.2.2
41 results

functionexpander.cpp

Blame
  • testMsg.cpp 12.15 KiB
    /**********************************************************************
    ** This program is part of 'MOOSE', the
    ** Messaging Object Oriented Simulation Environment.
    **           Copyright (C) 2003-2010 Upinder S. Bhalla. and NCBS
    ** It is made available under the terms of the
    ** GNU Lesser General Public License version 2.1
    ** See the file COPYING.LIB for the full notice.
    **********************************************************************/
    
    #include "header.h"
    #include "../builtins/Arith.h"
    
    #include "../shell/Shell.h"
    
    void testAssortedMsg()
    {
    	Eref sheller = Id().eref();
    	Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
    	ObjId pa = shell->doCreate( "Neutral", ObjId(), "pa", 1 );
    	unsigned int numData = 5;
    
    
    	///////////////////////////////////////////////////////////
    	// Set up the objects.
    	///////////////////////////////////////////////////////////
    	Id a1 = shell->doCreate( "Arith", pa, "a1", numData );
    	Id a2 = shell->doCreate( "Arith", pa, "a2", numData );
    
    	Id b1 = shell->doCreate( "Arith", pa, "b1", numData );
    	Id b2 = shell->doCreate( "Arith", pa, "b2", numData );
    
    	Id c1 = shell->doCreate( "Arith", pa, "c1", numData );
    	Id c2 = shell->doCreate( "Arith", pa, "c2", numData );
    
    	Id d1 = shell->doCreate( "Arith", pa, "d1", numData );
    	Id d2 = shell->doCreate( "Arith", pa, "d2", numData );
    
    	Id e1 = shell->doCreate( "Arith", pa, "e1", numData );
    	Id e2 = shell->doCreate( "Arith", pa, "e2", numData );
    
    	///////////////////////////////////////////////////////////
    	// Set up initial conditions
    	///////////////////////////////////////////////////////////
    	bool ret = 0;
    	vector< double > init; // 12345
    	for ( unsigned int i = 1; i < 6; ++i )
    		init.push_back( i );
    	ret = SetGet1< double >::setVec( a1, "arg1", init ); // 12345
    	assert( ret );
    	ret = SetGet1< double >::setVec( b1, "arg1", init ); // 12345
    	assert( ret );
    	ret = SetGet1< double >::setVec( c1, "arg1", init ); // 12345
    	assert( ret );
    	ret = SetGet1< double >::setVec( d1, "arg1", init ); // 12345
    	assert( ret );
    	ret = SetGet1< double >::setVec( e1, "arg1", init ); // 12345
    	assert( ret );
    
    	///////////////////////////////////////////////////////////
    	// Set up messaging
    	///////////////////////////////////////////////////////////
    	// Should give 04000
    	ObjId m1 = shell->doAddMsg( "Single", 
    		ObjId( a1, 3 ), "output", ObjId( a2, 1 ), "arg1" );
    	assert( !m1.bad() );
    
    	// Should give 33333
    	ObjId m2 = shell->doAddMsg( "OneToAll", 
    		ObjId( b1, 2 ), "output", ObjId( b2, 0 ), "arg1" );
    	assert( !m2.bad() );
    
    	// Should give 12345
    	ObjId m3 = shell->doAddMsg( "OneToOne", 
    		ObjId( c1, 0 ), "output", ObjId( c2, 0 ), "arg1" );
    	assert( !m3.bad() );
    
    	// Should give 01234
    	ObjId m4 = shell->doAddMsg( "Diagonal", 
    		ObjId( d1, 0 ), "output", ObjId( d2, 0 ), "arg1" );
    	assert( !m4.bad() );
    
    	// Should give 54321
    	ObjId m5 = shell->doAddMsg( "Sparse", 
    		ObjId( e1, 0 ), "output", ObjId( e2, 0 ), "arg1" );
    	assert( !m5.bad() );
    
    	ret = SetGet3< unsigned int, unsigned int, unsigned int >::set(
    		m5, "setEntry", 0, 4, 0 );
    	assert( ret );
    	ret = SetGet3< unsigned int, unsigned int, unsigned int >::set(
    		m5, "setEntry", 1, 3, 0 );
    	assert( ret );
    	ret = SetGet3< unsigned int, unsigned int, unsigned int >::set(
    		m5, "setEntry", 2, 2, 0 );
    	assert( ret );
    	ret = SetGet3< unsigned int, unsigned int, unsigned int >::set(
    		m5, "setEntry", 3, 1, 0 );
    	assert( ret );
    	ret = SetGet3< unsigned int, unsigned int, unsigned int >::set(
    		m5, "setEntry", 4, 0, 0 );
    	assert( ret );
    
    	assert( ret );
    
    	///////////////////////////////////////////////////////////
    	// Test traversal
    	///////////////////////////////////////////////////////////
    	// Single
    	ObjId f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a1, 3 ) );
    	assert( f == ObjId( a2, 1 ) );
    
    	f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a2, 1 ) );
    	assert( f == ObjId( a1, 3 ) );
    
    	f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a1, 0 ) );
    	assert( f.bad() );
    
    	f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a2, 0 ) );
    	assert( f.bad() );
    
    	f = Msg::getMsg( m1 )->findOtherEnd( ObjId( b2, 1 ) );
    	assert( f.bad() );
    
    	// OneToAll
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b1, 2 ) );
    	assert( f == ObjId( b2, 0 ) );
    
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 0 ) );
    	assert( f == ObjId( b1, 2 ) );
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 1 ) );
    	assert( f == ObjId( b1, 2 ) );
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 2 ) );
    	assert( f == ObjId( b1, 2 ) );
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 3 ) );
    	assert( f == ObjId( b1, 2 ) );
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 4 ) );
    	assert( f == ObjId( b1, 2 ) );
    
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b1, 0 ) );
    	assert( f.bad() );
    
    	f = Msg::getMsg( m2 )->findOtherEnd( ObjId( a2, 1 ) );
    	assert( f.bad() );
    
    	// OneToOne
    	for ( unsigned int i = 0; i < 5; ++i ) {
    		f = Msg::getMsg( m3 )->findOtherEnd( ObjId( c1, i ) );
    		assert( f == ObjId( c2, i ) );
    		f = Msg::getMsg( m3 )->findOtherEnd( ObjId( c2, i ) );
    		assert( f == ObjId( c1, i ) );
    	}
    	f = Msg::getMsg( m3 )->findOtherEnd( ObjId( a2, 1 ) );
    	assert( f.bad() );
    
    	// Diagonal
    	for ( unsigned int i = 0; i < 4; ++i ) {
    		f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d1, i ) );
    		assert( f == ObjId( d2, i + 1 ) );
    		f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d2, i + 1 ) );
    		assert( f == ObjId( d1, i ) );
    	}
    	f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d1, 4 ) );
    	assert( f.bad() );
    	f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d2, 0 ) );
    	assert( f.bad() );
    
    	f = Msg::getMsg( m4 )->findOtherEnd( ObjId( a2, 1 ) );
    	assert( f.bad() );
    
    	// Sparse
    	for ( unsigned int i = 0; i < 5; ++i ) {
    		f = Msg::getMsg( m5 )->findOtherEnd( ObjId( e1, i ) );
    		assert( f == ObjId( e2, 4 - i ) );
    		f = Msg::getMsg( m5 )->findOtherEnd( ObjId( e2, i ) );
    		assert( f == ObjId( e1, 4 - i ) );
    	}
    
    	f = Msg::getMsg( m5 )->findOtherEnd( ObjId( a2, 1 ) );
    	assert( f.bad() );
    
    	cout << "." << flush;
    
    	///////////////////////////////////////////////////////////
    	// Check lookup by funcId.
    	///////////////////////////////////////////////////////////
    	const Finfo* aFinfo = Arith::initCinfo()->findFinfo( "arg1" );
    	FuncId afid = dynamic_cast< const DestFinfo* >( aFinfo )->getFid();
    
    	ObjId m = a2.element()->findCaller( afid );
    	assert ( m == m1 );
    	m = b2.element()->findCaller( afid );
    	assert ( m == m2 );
    	m = c2.element()->findCaller( afid );
    	assert ( m == m3 );
    	m = d2.element()->findCaller( afid );
    	assert ( m == m4 );
    	m = e2.element()->findCaller( afid );
    	assert ( m == m5 );
    
    	///////////////////////////////////////////////////////////
    	// Clean up.
    	///////////////////////////////////////////////////////////
    	shell->doDelete( pa );
    
    	cout << "." << flush;
    }
    
    // Reported as a bug by Subha 22 Feb 2012.
    void testMsgElementListing()
    {
    	Eref sheller = Id().eref();
    	Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
    	unsigned int numData = 1;
    	Id pa = shell->doCreate( "Neutral", Id(), "pa", numData );
    	numData = 5;
    
    
    	///////////////////////////////////////////////////////////
    	// Set up the objects.
    	///////////////////////////////////////////////////////////
    	Id a1 = shell->doCreate( "Arith", pa, "a1", numData );
    	Id a2 = shell->doCreate( "Arith", pa, "a2", numData );
    
    	Id b1 = shell->doCreate( "Arith", pa, "b1", numData );
    	Id b2 = shell->doCreate( "Arith", pa, "b2", numData );
    
    	Id c1 = shell->doCreate( "Arith", pa, "c1", numData );
    	Id c2 = shell->doCreate( "Arith", pa, "c2", numData );
    
    	Id d1 = shell->doCreate( "Arith", pa, "d1", numData );
    	Id d2 = shell->doCreate( "Arith", pa, "d2", numData );
    
    	Id e1 = shell->doCreate( "Arith", pa, "e1", numData );
    	Id e2 = shell->doCreate( "Arith", pa, "e2", numData );
    
    	///////////////////////////////////////////////////////////
    	// Set up messaging
    	///////////////////////////////////////////////////////////
    	ObjId m1 = shell->doAddMsg( "Single", 
    		ObjId( a1, 3 ), "output", ObjId( a2, 1 ), "arg1" );
    	assert( !m1.bad() );
    	ObjId m2 = shell->doAddMsg( "OneToAll", 
    		ObjId( b1, 2 ), "output", ObjId( b2, 0 ), "arg1" );
    	assert( !m2.bad() );
    	ObjId m3 = shell->doAddMsg( "OneToOne", 
    		ObjId( c1, 0 ), "output", ObjId( c2, 0 ), "arg1" );
    	assert( !m3.bad() );
    	ObjId m4 = shell->doAddMsg( "Diagonal", 
    		ObjId( d1, 0 ), "output", ObjId( d2, 0 ), "arg1" );
    	assert( !m4.bad() );
    	ObjId m5 = shell->doAddMsg( "Sparse", 
    		ObjId( e1, 0 ), "output", ObjId( e2, 0 ), "arg1" );
    	assert( !m5.bad() );
    
    	///////////////////////////////////////////////////////////
    	// List messages
    	///////////////////////////////////////////////////////////
    	Id manager( "/Msgs" );
    	assert( manager != Id() );
    	vector< Id > children = 
    		Field< vector< Id > >::get( manager, "children" );
    	assert( children.size() == 5 );
    	assert( children[0].element()->getName() == "singleMsg" );
    	assert( children[1].element()->getName() == "oneToOneMsg" );
    	assert( children[2].element()->getName() == "oneToAllMsg" );
    	assert( children[3].element()->getName() == "diagonalMsg" );
    	assert( children[4].element()->getName() == "sparseMsg" );
    
    	/*
    	// A remarkably large number of some message classes, including 645
    	// OneToAll which are used by parent-child messages. I thought they
    	// were cleaned out as the tests proceed.
    	for ( unsigned int i = 0; i < children.size(); ++i ) {
    		cout << "\nlocalEntries[" << i << "] = " << 
    			children[i].element()->dataHandler()->localEntries() << endl;
    	}
    	*/
    	/*
    	string path = children[0].path();
    	cout << "\nlocalEntries = " << 
    		children[0].element()->dataHandler()->localEntries() << endl;
    	assert( path == "/Msgs/singleMsg[0]" );
    	*/
    	assert( children[0].path() == "/Msgs[0]/singleMsg" );
    	assert( children[1].path() == "/Msgs[0]/oneToOneMsg" );
    	assert( children[2].path() == "/Msgs[0]/oneToAllMsg" );
    	assert( children[3].path() == "/Msgs[0]/diagonalMsg" );
    	assert( children[4].path() == "/Msgs[0]/sparseMsg" );
    
    
    	///////////////////////////////////////////////////////////
    	// Next: check that the child messages have the appropriate number
    	// and indices of entries.
    	///////////////////////////////////////////////////////////
    
    	shell->doDelete( pa );
    	cout << "." << flush;
    }
    
    /**
     * In all cases we set up the same amount of data transfer by the msgs, that
     * is, equivalent to a fully recurrently connected network.
     * Used in regressionTests/benchmarkTests.cpp
     */
    void benchmarkMsg( unsigned int n, string msgType )
    {
    	Eref sheller = Id().eref();
    	Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
    	vector< double > init( n );
    	for ( unsigned int i = 0; i < n; ++i )
    		init[i] = (i + 1) * 1e6;
    
    	Id a1 = shell->doCreate( "Arith", Id(), "a1", n );
    
    	if ( msgType == "Single" ) {
    		for ( unsigned int i = 0; i < n; ++i ) {
    			for ( unsigned int j = 0; j < n; ++j ) {
    				ObjId m1 = shell->doAddMsg( "Single", 
    					ObjId( a1, i ), "output", ObjId( a1, j ), "arg3" );
    				assert( !m1.bad() );
    			}
    		}
    	} else if ( msgType == "OneToAll" ) {
    		for ( unsigned int i = 0; i < n; ++i ) {
    			ObjId m1 = shell->doAddMsg( "OneToAll", 
    				ObjId( a1, i ), "output", ObjId( a1, 0 ), "arg3" );
    			assert( !m1.bad() );
    		}
    	} else if ( msgType == "OneToOne" ) {
    		for ( unsigned int i = 0; i < n; ++i ) { // just repeat it n times
    			ObjId m1 = shell->doAddMsg( "OneToOne", 
    				ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" );
    			assert( !m1.bad() );
    		}
    	} else if ( msgType == "Diagonal" ) {
    		for ( unsigned int i = 0; i < 2 * n; ++i ) { // Set up all offsets
    			ObjId m1 = shell->doAddMsg( "Diagonal", 
    				ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" );
    			Field< int >::set( m1, "stride", n - i );
    		}
    	} else if ( msgType == "Sparse" ) {
    		ObjId m1 = shell->doAddMsg( "Sparse", 
    			ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" );
    	
    		SetGet2< double, long >::set( m1, 
    			"setRandomConnectivity", 1.0, 1234 );
    	} 
    
    	shell->doUseClock( "/a1", "proc", 0 );
    	for ( unsigned int i = 0; i < 10; ++i )
    		shell->doSetClock( i, 0 );
    	shell->doSetClock( 0, 1 );
    	shell->doReinit();
    	SetGet1< double >::setVec( a1, "arg1", init );
    	shell->doStart( 100 );
    	for ( unsigned int i = 0; i < n; ++i )
    		init[i] = 0; // be sure we don't retain old info.
    	init.clear();
    	Field< double >::getVec( a1, "outputValue", init );
    	cout << endl;
    	for ( unsigned int i = 0; i < n; ++i ) {
    		cout << i << " " << init[i] << "	";
    		if ( i % 5 == 4 )
    			cout << endl;
    	}
    
    	shell->doDelete( a1 );
    }
    
    void testMsg()
    {
        testAssortedMsg();
        testMsgElementListing();
    }
    
    void testMpiMsg( )
    {
        cout << "." << flush;
    }