samples/fib/fib_tutorial/fibTutorial.cpp
#define _CRT_SECURE_NO_DEPRECATE // to keep the VS compiler happy with TBB
#include <cnc/cnc.h>
typedef unsigned long long fib_type;
struct fib_context;
struct fib_step
{
int execute( const int & tag, fib_context & c ) const;
};
{
fib_context();
};
fib_context::fib_context()
:
CnC::context< fib_context >(),
m_steps( *this ),
m_fibs( *this ),
m_tags( *this )
{
}
int fib_step::execute( const int & tag, fib_context & ctxt ) const
{
switch( tag ) {
case 0 : ctxt.m_fibs.put( tag, 0 ); break;
case 1 : ctxt.m_fibs.put( tag, 1 ); break;
default :
fib_type f_1; ctxt.m_fibs.get( tag - 1, f_1 );
fib_type f_2; ctxt.m_fibs.get( tag - 2, f_2 );
ctxt.m_fibs.put( tag, f_1 + f_2 );
}
}
int main( int argc, char* argv[] )
{
int n = 42;
if( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " n\nUsing default value " << n << std::endl;
} else n = atol( argv[1] );
fib_context ctxt;
for( int i = 0; i <= n; ++i ) ctxt.m_tags.put( i );
ctxt.wait();
fib_type res2;
ctxt.m_fibs.get( n, res2 );
std::cout << "fib (" << n << "): " << res2 << std::endl;
return 0;
}
samples/fib/fib_trace/fib_trace.cpp
#define _CRT_SECURE_NO_DEPRECATE // to keep the VS compiler happy with TBB
typedef unsigned long long fib_type;
#include "fib.h"
int fib_step::execute( const int & tag, fib_context & ctxt ) const
{
switch( tag ) {
case 0 : ctxt.m_fibs.put( tag, 0 ); break;
case 1 : ctxt.m_fibs.put( tag, 1 ); break;
default :
fib_type f_1; ctxt.m_fibs.get( tag - 1, f_1 );
fib_type f_2; ctxt.m_fibs.get( tag - 2, f_2 );
ctxt.m_fibs.put( tag, f_1 + f_2 );
}
}
int main( int argc, char* argv[] )
{
int n = 42;
if( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " n\nUsing default value " << n << std::endl;
} else n = atol( argv[1] );
fib_context ctxt;
for( int i = 0; i <= n; ++i ) ctxt.m_tags.put( i );
ctxt.wait();
fib_type res2;
ctxt.m_fibs.get( n, res2 );
std::cout << "fib (" << n << "): " << res2 << std::endl;
return 0;
}
samples/fib/fib_trace/fib.h
#ifndef fib_H_ALREADY_INCLUDED
#define fib_H_ALREADY_INCLUDED
#include <cnc/cnc.h>
#include <cnc/debug.h>
struct fib_context;
struct fib_step
{
int execute( const int & t, fib_context & c ) const;
};
{
fib_context()
:
CnC::context< fib_context >(),
m_steps( *this, "fib_step" ),
m_fibs( *this, "fibs" ),
m_tags( *this, "tags" )
{
}
};
#endif // fib_H_ALREADY_INCLUDED
samples/fib/fib_stats/fib_stats.cpp
#define _CRT_SECURE_NO_DEPRECATE // to keep the VS compiler happy with TBB
typedef unsigned long long fib_type;
#include "fib.h"
int fib_step::execute( const int & tag, fib_context & ctxt ) const
{
switch( tag ) {
case 0 : ctxt.m_fibs.put( tag, 0 ); break;
case 1 : ctxt.m_fibs.put( tag, 1 ); break;
default :
fib_type f_1; ctxt.m_fibs.get( tag - 1, f_1 );
fib_type f_2; ctxt.m_fibs.get( tag - 2, f_2 );
ctxt.m_fibs.put( tag, f_1 + f_2 );
}
}
int main( int argc, char* argv[] )
{
int n = 42;
if( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " n\nUsing default value " << n << std::endl;
} else n = atol( argv[1] );
fib_context ctxt;
for( int i = 0; i <= n; ++i ) ctxt.m_tags.put( i );
ctxt.wait();
fib_type res2;
ctxt.m_fibs.get( n, res2 );
std::cout << "fib (" << n << "): " << res2 << std::endl;
return 0;
}
samples/fib/fib_stats/fib.h
#ifndef fib_H_ALREADY_INCLUDED
#define fib_H_ALREADY_INCLUDED
#include <cnc/cnc.h>
#include <cnc/debug.h>
struct fib_context;
struct fib_step
{
int execute( const int & t, fib_context & c ) const;
};
{
fib_context()
:
CnC::context< fib_context >(),
m_steps( *this, "fib_step" ),
m_fibs( *this, "fibs" ),
m_tags( *this, "tags" )
{
}
};
#endif // fib_H_ALREADY_INCLUDED
samples/fib/fib_tuner/fib_tuner.cpp
#define _CRT_SECURE_NO_DEPRECATE // to keep the VS compiler happy with TBB
typedef unsigned long long fib_type;
#include "cnc/cnc.h"
struct fib_context;
{
template< class dependency_consumer >
void depends(
const int & tag, fib_context & c, dependency_consumer & dC )
const;
};
#include "fib.h"
template< class dependency_consumer >
void fib_tuner::depends( const int & tag, fib_context & c, dependency_consumer & dC ) const
{
if( tag > 1 ) {
dC.depends( c.m_fibs, tag - 1 );
dC.depends( c.m_fibs, tag - 2 );
}
}
int fib_step::execute( const int & tag, fib_context & ctxt ) const
{
switch( tag ) {
case 0 : ctxt.m_fibs.put( tag, 0 ); break;
case 1 : ctxt.m_fibs.put( tag, 1 ); break;
default :
fib_type f_1; ctxt.m_fibs.get( tag - 1, f_1 );
fib_type f_2; ctxt.m_fibs.get( tag - 2, f_2 );
ctxt.m_fibs.put( tag, f_1 + f_2 );
}
}
int main( int argc, char* argv[] )
{
int n = 42;
if( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " n\nUsing default value " << n << std::endl;
} else n = atol( argv[1] );
fib_context ctxt;
for( int i = 0; i <= n; ++i ) ctxt.m_tags.put( i );
ctxt.wait();
fib_type res2;
ctxt.m_fibs.get( n, res2 );
std::cout << "fib (" << n << "): " << res2 << std::endl;
return 0;
}
samples/fib/fib_preschedule/fib_preschedule.cpp
#define _CRT_SECURE_NO_DEPRECATE // to keep the VS compiler happy with TBB
typedef unsigned long long fib_type;
#include "cnc/cnc.h"
struct fib_context;
{
};
#include "fib.h"
int fib_step::execute( const int & tag, fib_context & ctxt ) const
{
switch( tag ) {
case 0 : ctxt.m_fibs.put( tag, 0 ); break;
case 1 : ctxt.m_fibs.put( tag, 1 ); break;
default :
fib_type f_1; ctxt.m_fibs.get( tag - 1, f_1 );
fib_type f_2; ctxt.m_fibs.get( tag - 2, f_2 );
ctxt.m_fibs.put( tag, f_1 + f_2 );
}
}
int main( int argc, char* argv[] )
{
int n = 42;
if( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " n\nUsing default value " << n << std::endl;
} else n = atol( argv[1] );
fib_context ctxt;
for( int i = 0; i <= n; ++i ) ctxt.m_tags.put( i );
ctxt.wait();
fib_type res2;
ctxt.m_fibs.get( n, res2 );
std::cout << "fib (" << n << "): " << res2 << std::endl;
return 0;
}
samples/fib/fib_getcount/fib_getcount.cpp
#define _CRT_SECURE_NO_DEPRECATE // to keep the VS compiler happy with TBB
#include <cnc/cnc.h>
typedef unsigned long long fib_type;
struct fib_context;
{
template< class dependency_consumer >
void depends(
const int & tag, fib_context & c, dependency_consumer & dC )
const;
};
{
int get_count( const int & tag ) const;
};
#include "fib.h"
template< class dependency_consumer >
void fib_tuner::depends( const int & tag, fib_context & c, dependency_consumer & dC ) const
{
if( tag > 1 ) {
dC.depends( c.m_fibs, tag - 1 );
dC.depends( c.m_fibs, tag - 2 );
}
}
int item_tuner::get_count( const int & tag ) const
{
return tag > 0 ? 2 : 1;
}
int fib_step::execute( const int & tag, fib_context & ctxt ) const
{
switch( tag ) {
case 0 : ctxt.m_fibs.put( tag, 0 ); break;
case 1 : ctxt.m_fibs.put( tag, 1 ); break;
default :
fib_type f_1; ctxt.m_fibs.get( tag - 1, f_1 );
fib_type f_2; ctxt.m_fibs.get( tag - 2, f_2 );
ctxt.m_fibs.put( tag, f_1 + f_2 );
}
}
int main( int argc, char* argv[] )
{
int n = 42;
if( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " n\nUsing default value " << n << std::endl;
} else n = atol( argv[1] );
fib_context ctxt;
for( int i = 0; i <= n; ++i ) ctxt.m_tags.put( i );
ctxt.wait();
fib_type res2;
ctxt.m_fibs.get( n, res2 );
std::cout << "fib (" << n << "): " << res2 << std::endl;
return 0;
}
samples/fib/fib_getcount/fib.h
#ifndef fib_H_ALREADY_INCLUDED
#define fib_H_ALREADY_INCLUDED
#include <cnc/cnc.h>
#include <cnc/debug.h>
struct fib_context;
struct fib_step
{
int execute( const int & t, fib_context & c ) const;
};
{
fib_context()
:
CnC::context< fib_context >(),
m_steps( *this, "fib_step" ),
m_fibs( *this, "fibs" ),
m_tags( *this, "tags" )
{
}
};
#endif // fib_H_ALREADY_INCLUDED
samples/primes/primes_range/primes_range.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tbb/tick_count.h>
#ifdef _DIST_
#include <cnc/dist_cnc.h>
#include <cnc/internal/dist/distributor.h>
#else
#include <cnc/cnc.h>
#endif
struct my_context;
struct FindPrimes
{
int execute( int n, my_context & c ) const;
};
{
int compute_on( const int & p, my_context & ) const
{
return ( 1 + p / ( 1000000 / 20 ) ) % numProcs();
}
};
{
my_context()
:
CnC::context< my_context >(),
m_steps( *this ),
m_tags( *this ),
m_primes( *this )
{
}
};
int FindPrimes::execute( int n, my_context & c ) const
{
int factor = 3;
while ( n % factor ) factor += 2;
if (factor == n) c.m_primes.put(n, n);
}
int main(int argc, char* argv[])
{
#ifdef _DIST_
#endif
bool verbose = false;
int n = 0;
int number_of_primes = 0;
if (argc == 2)
{
n = atoi(argv[1]);
}
else if (argc == 3 && 0 == strcmp("-v", argv[1]))
{
n = atoi(argv[2]);
verbose = true;
}
else
{
fprintf(stderr,"Usage: primes [-v] n\n");
return -1;
}
my_context c;
printf("Determining primes from 1-%d \n",n);
tbb::tick_count t0 = tbb::tick_count::now();
c.m_tags.put_range( CnC::Internal::strided_range< int >( 3, n, 2 ) );
c.wait();
tbb::tick_count t1 = tbb::tick_count::now();
number_of_primes = (int)c.m_primes.size() + 1;
printf("Found %d primes in %g seconds\n", number_of_primes, (t1-t0).seconds());
if (verbose)
{
printf("%d\n", 2);
for (cii = c.m_primes.begin(); cii != c.m_primes.end(); cii++)
{
printf("%d\n", cii->first);
}
}
}
samples/primes/primes_parfor/primes_parfor.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tbb/tick_count.h>
#include <cnc/cnc.h>
#include <cnc/debug.h>
struct my_context;
struct FindPrimes
{
int operator()( int n ) const;
};
{
my_context()
:
CnC::context< my_context >(),
m_primes( *this )
{
}
};
my_context g_c;
int FindPrimes::operator()( int n ) const
{
int factor = 3;
while ( n % factor ) factor += 2;
if (factor == n) g_c.m_primes.put(n, n);
}
int main(int argc, char* argv[])
{
bool verbose = false;
int n = 0;
int number_of_primes = 0;
if (argc == 2)
{
n = atoi(argv[1]);
}
else if (argc == 3 && 0 == strcmp("-v", argv[1]))
{
n = atoi(argv[2]);
verbose = true;
}
else
{
fprintf(stderr,"Usage: primes [-v] n\n");
return -1;
}
printf("Determining primes from 1-%d \n",n);
tbb::tick_count t0 = tbb::tick_count::now();
tbb::tick_count t1 = tbb::tick_count::now();
number_of_primes = (int)g_c.m_primes.size() + 1;
printf("Found %d primes in %g seconds\n", number_of_primes, (t1-t0).seconds());
if (verbose)
{
printf("%d\n", 2);
{
printf("%d\n", cii->first);
}
}
}
samples/blackscholes/blackscholes/blackscholes.h
#ifndef blackscholes_H_ALREADY_INCLUDED
#define blackscholes_H_ALREADY_INCLUDED
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <vector>
#include <memory>
typedef std::shared_ptr< std::vector< OptionData > > option_vector_type;
typedef std::shared_ptr< std::vector< fptype > > price_vector_type;
struct blackscholes_context;
struct Compute
{
int execute( const int &, blackscholes_context & ) const;
};
{
int compute_on( const int tag ) const {
return tag % numProcs();
}
int compute_on( const int tag, blackscholes_context & ) const {
return compute_on( tag );
}
int consumed_by( const int tag ) const {
return tag;
}
int consumed_on( const int tag ) const {
return compute_on( consumed_by( tag ) );
}
int getcount( const int tag ) {
return 1;
}
};
struct blackscholes_context :
public CnC::context< blackscholes_context >
{
int m_vs;
blackscholes_context( int vs = 0)
:
CnC::context< blackscholes_context >(),
compute( *this ),
opt_data( *this ),
prices( *this ),
tags( *this ),
m_vs( vs )
{
}
#ifdef _DIST_
{
ser & m_vs;
if( ser.is_unpacking() ) {
}
}
#endif
};
#endif // blackscholes_H_ALREADY_INCLUDED
samples/cholesky/cholesky/cholesky.h
#ifndef cholesky_H_ALREADY_INCLUDED
#define cholesky_H_ALREADY_INCLUDED
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <memory>
struct cholesky_context;
struct S1_compute
{
int execute( const int & t, cholesky_context & c ) const;
};
struct S2_compute
{
int execute( const pair & t, cholesky_context & c ) const;
};
struct S3_compute
{
int execute( const triple & t, cholesky_context & c ) const;
};
static void mark( int p, bool * d )
{
if( d[p] == false ) {
d[p] = true;
}
}
{
cholesky_tuner( cholesky_context & c, int p = 0, int n = 0, dist_type dt = BLOCKED_ROWS )
: m_context( c ), m_p( p ), m_n( n ),
m_div( (((p*p) / 2) + 1) / numProcs() ),
m_dt( dt )
{
if( myPid() == 0 ) {
switch( dt ) {
default:
case BLOCKED_ROWS :
std::cerr << "Distributing BLOCKED_ROWS\n";
break;
case ROW_CYCLIC :
std::cerr << "Distributing ROW_CYCLIC\n";
break;
case COLUMN_CYCLIC :
std::cerr << "Distributing COLUMN_CYCLIC\n";
break;
case BLOCKED_CYCLIC :
std::cerr << "Distributing BLOCKED_CYCLICS\n";
break;
}
}
}
inline static int compute_on( const dist_type dt, const int i, const int j, const int n, const int s )
{
switch( dt ) {
default:
case BLOCKED_ROWS :
return ( ((j*j)/2 + 1 + i ) / s ) % numProcs();
break;
case ROW_CYCLIC :
return j % numProcs();
break;
case COLUMN_CYCLIC :
return i % numProcs();
break;
case BLOCKED_CYCLIC :
return ( (i/2) * n + (j/2) ) % numProcs();
break;
}
}
int compute_on( const int tag, cholesky_context & ) const
{
return compute_on( m_dt, tag, tag, m_n, m_div );
}
int compute_on( const pair & tag, cholesky_context & ) const
{
return compute_on( m_dt, tag.first, tag.second, m_p, m_div );
}
int compute_on( const triple & tag, cholesky_context & ) const
{
return compute_on( m_dt, tag[2], tag[1], m_p, m_div );
}
typedef triple tag_type;
int get_count( const tag_type & tag ) const
{
int _k = tag[0], _i = tag[2];
return ( _k > 0 && _k > _i ) ? ( m_p - _k ) : 1;
}
std::vector< int > consumed_on( const tag_type & tag ) const
{
int _k = tag[0], _j = tag[1], _i = tag[2];
if( _i == _j ) {
if( _i == _k ) return std::vector< int >( 1, compute_on( _k, m_context ) );
if( _k == m_p ) return std::vector< int >( 1, 0 );
}
if( _i == _k ) return std::vector< int >( 1, compute_on( pair( _k, _j ), m_context ) );
bool * _d;
_d = new bool[numProcs()];
memset( _d, 0, numProcs() * sizeof( *_d ) );
if( _i == _k-1 ) {
if( _i == _j ) {
for( int j = _k; j < m_p; ++j ) {
mark( compute_on( pair( _k - 1, j ), m_context ), _d );
}
} else {
for( int j = _j; j < m_p; ++j ) {
for( int i = _k; i <= _j; ++i ) {
mark( compute_on( triple( _k-1, j, i ), m_context ), _d );
}
}
}
}
mark( compute_on( triple( _k, _j, _i ), m_context ), _d );
std::vector< int > _v;
_v.reserve( numProcs()/2 );
if( _d[myPid()] ) _v.push_back( myPid() );
for( int i = 0; i < numProcs(); ++i ) {
if( _d[i] && i != myPid() ) _v.push_back( i );
}
delete [] _d;
return _v;
}
#ifdef _DIST_
{
ser & m_p & m_div & m_n & m_dt;
}
#endif
private:
cholesky_context & m_context;
int m_p;
int m_n;
int m_div;
dist_type m_dt;
};
struct cholesky_context :
public CnC::context< cholesky_context >
{
cholesky_tuner tuner;
int p,b;
cholesky_context( int _b = 0, int _p = 0, int _n = 0, dist_type dt = BLOCKED_ROWS )
:
CnC::context< cholesky_context >(),
tuner( *this, _p, _n, dt ),
sc_s1_compute( *this, tuner, "Cholesky" ),
sc_s2_compute( *this, tuner, "Trisolve" ),
sc_s3_compute( *this, tuner, "Update" ),
Lkji( *this, "Lkji", tuner ),
p( _p ),
b( _b ),
control_S1( *this, "S1" ),
control_S2( *this, "S2" ),
control_S3( *this, "S3" )
{
#if 0
#endif
}
#ifdef _DIST_
{
ser & p & b & tuner;
}
#endif
};
#endif // cholesky_H_ALREADY_INCLUDED
samples/count_words/count_words/count_words.cpp
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <cnc/reduce.h>
#include <cassert>
#include <string>
#include <sstream>
#include <fstream>
typedef std::pair< int, std::string > tag_type;
struct cw_context;
struct counter
{
int execute( const tag_type & t, cw_context & ctxt ) const;
};
{
cw_context()
: tags( *this, "tags" ),
blocks( *this, "blocks" ),
counts_per_block( *this, "counts_per_block" ),
counts( *this, "counts" ),
red_counts( *this, "red_counts" ),
steps( *this, "counter" ),
reduce( NULL )
{
"reduce",
counts_per_block,
red_counts,
counts,
std::plus<size_type>(),
size_type(0),
[]( const tag_type & t, std::string & _s )->bool{_s=t.second;return true;} );
}
~cw_context()
{
delete reduce;
}
};
int counter::execute( const tag_type & t, cw_context & ctxt ) const
{
std::string _str;
ctxt.blocks.get( t.first, _str );
const size_type _sz = _str.size();
size_type _pos = -1;
size_type _cnt = 0;
while( ( _pos = _str.find( t.second, _pos+1 ) ) < _sz ) ++_cnt;
ctxt.counts_per_block.put( t, _cnt );
return 0;
}
int main( int argc, char * argv[])
{
#ifdef _DIST_
#endif
if( argc < 3 ) {
std::cerr << "expected arguments: <file> <word1> [<word2>...]\n";
exit(1);
}
cw_context ctxt;
std::ifstream _file( argv[1] );
std::string _block;
int _id = 0;
while( std::getline( _file, _block ) ) {
ctxt.blocks.put( _id, _block );
int i = 1;
while( ++i < argc ) {
ctxt.tags.put( std::make_pair( _id, argv[i] ) );
}
++_id;
}
int i = 1;
while( ++i < argc ) ctxt.red_counts.put( argv[i], _id );
ctxt.wait();
std::cout << "done" << std::endl;
std::cout << ctxt.counts.size() << " " << ctxt.blocks.size() << std::endl;
for( auto i = ctxt.counts.begin(); i != ctxt.counts.end(); ++i ) {
std::cout << i->first << " \t " << *i->second << std::endl;
}
ctxt.wait();
std::cout << ctxt.counts.size() << " " << ctxt.blocks.size() << std::endl;
return 0;
}
samples/count_all_words/count_all_words/count_all_words.cpp
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <cnc/reduce.h>
#include <cassert>
#include <string>
#include <sstream>
#include <algorithm>
#include <fstream>
typedef long long int id_type;
typedef std::pair< id_type, const std::string > tag_type;
struct cw_context;
struct counter
{
int execute( const int & t, cw_context & ctxt ) const;
};
{
template< typename Tag >
int get_count( const Tag & ) const
{
return 0;
}
};
{
cw_context()
: tags( *this, "tags" ),
blocks( *this, "blocks" ),
counts_per_block( *this, "counts_per_block" ),
cnt( *this, "cnt" ),
counts( *this, "counts" ),
steps( *this, "counter" ),
reduce( NULL )
{
counts_per_block,
cnt,
counts,
std::plus<size_type>(),
size_type(0),
[]( const tag_type & t, std::string& _s )->bool{_s=t.second;return true;} );
}
~cw_context()
{
delete reduce;
}
};
int counter::execute( const int & t, cw_context & ctxt ) const
{
std::string _str;
ctxt.blocks.get( t, _str );
std::istringstream iss( _str );
std::string _word;
id_type _id = (t << 16);
while( iss >> _word ) {
std::transform(_word.begin(), _word.end(), _word.begin(), ::tolower);
ctxt.counts_per_block.put( tag_type(_id, _word), 1 );
++_id;
}
return 0;
}
int main( int argc, char * argv[])
{
#ifdef _DIST_
#endif
if( argc < 2 ) {
std::cerr << "expected arguments: <file>\n";
exit(1);
}
cw_context ctxt;
std::ifstream _file( argv[1] );
std::string _block;
int _id = 0;
tbb::tick_count startTime = tbb::tick_count::now();
while( std::getline( _file, _block ) ) {
ctxt.blocks.put( _id, _block );
ctxt.tags.put( _id );
++_id;
}
ctxt.wait();
ctxt.reduce->flush();
ctxt.wait();
tbb::tick_count endTime = tbb::tick_count::now();
std::cout << ctxt.counts.size() << std::endl;
for( auto i = ctxt.counts.begin(); i != ctxt.counts.end(); ++i ) {
if( *i->second > 999 )
std::cout << i->first << " \t " << *i->second << std::endl;
}
std::cout << "Time: " << (endTime-startTime).seconds() << "s.\n";
return 0;
}
samples/count_all_words/mapreduce/mapreduce.h
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <cnc/reduce.h>
#include <cassert>
#include <string>
#include <sstream>
#include <algorithm>
#include <fstream>
#include <cwctype>
template< typename MapOp, typename ReduceOp >
struct mapreduce_context :
public CnC::context< mapreduce_context< MapOp, ReduceOp > >
{
typedef std::pair< const std::string, long long int > map_tag_type;
typedef typename MapOp::result_type result_type;
typedef typename MapOp::key_type key_type;
typedef std::string char_ptr_type;
struct mapper
{
int execute( const map_tag_type & t, mapreduce_context< MapOp, ReduceOp > & ctxt ) const;
};
struct reader
{
int execute( const std::string & file, mapreduce_context< MapOp, ReduceOp > & ctxt ) const;
};
template< int GC >
{
template< typename Tag >
int get_count( const Tag & ) const
{
return GC;
}
template< typename Tag >
int consumed_on( const Tag & ) const
{
}
template< typename Tag >
int produced_on( const Tag & ) const
{
}
};
{
int compute_on( const std::string & file, mapreduce_context< MapOp, ReduceOp > & ) const
{
auto _col = file.rfind( ':' );
if( _col == std::string::npos ) {
return _x;
}
const char * _p = file.c_str() + _col + 1;
int _x = 0;
while( *_p >= '0' && *_p <= '9' ) {
_x = ( _x * 10 ) + ( *_p - '0' );
++_p;
}
}
};
{
int compute_on( const map_tag_type &, mapreduce_context< MapOp, ReduceOp > & ) const
{
}
};
MapOp m_mapOp;
ReduceOp m_reduceOp;
mapreduce_context()
: reduce( NULL ),
m_mapOp(),
m_reduceOp()
{
}
mapreduce_context( const MapOp & mo, const ReduceOp & ro )
: mapreduce_context< MapOp, ReduceOp >()
{
m_mapOp = mo;
m_reduceOp = ro;
init_reduce();
}
void init_reduce()
{
delete reduce;
map_out,
cnt,
results,
m_reduceOp,
size_type(0),
[]( const std::string & t, std::string& _s )->bool{_s=t;return true;} );
}
~mapreduce_context()
{
delete reduce;
}
void wait()
{
}
#ifdef _DIST_
{
ser & m_mapOp & m_reduceOp;
if( ser.is_unpacking() ) init_reduce();
}
#endif
};
template< typename MapOp, typename ReduceOp >
mapreduce_context< MapOp, ReduceOp > * make_mapreduce( const MapOp & mo, const ReduceOp & ro )
{
return new mapreduce_context< MapOp, ReduceOp >( mo, ro );
}
template< typename MapOp, typename ReduceOp >
int mapreduce_context< MapOp, ReduceOp >::mapper::execute( const map_tag_type & t, mapreduce_context< MapOp, ReduceOp > & ctxt ) const
{
char_ptr_type _str;
ctxt.blocks.get( t, _str );
std::istringstream iss( _str );
ctxt.m_mapOp( iss, ctxt.map_out );
return 0;
}
template< typename MapOp, typename ReduceOp >
int mapreduce_context< MapOp, ReduceOp >::reader::execute( const std::string & file, mapreduce_context< MapOp, ReduceOp > & ctxt ) const
{
const int MIN_BLK_SZ = 1024;
std::string _fn( file );
auto _col = file.rfind( ':' );
if( _col != std::string::npos ) _fn.resize( _col );
std::ifstream _file( _fn );
if( ! _file ) {
std::cerr << "Could not open file " << _fn << std::endl;
}
long long int _id = 0;
int _first = 0;
char_ptr_type _block;
_block.resize( MIN_BLK_SZ );
do {
char * _b = const_cast< char * >( _block.c_str() );
_file.read( _b + _first, MIN_BLK_SZ );
int _cnt = _first + _file.gcount();
_block.resize( _cnt );
if( _cnt > 0 ) {
auto _last = _block.find_last_of( " \t\n" );
_first = _cnt - _last - 1;
std::string _tmp;
if( _file ) {
_tmp.resize( MIN_BLK_SZ + _first );
if( _first > 0 ) _tmp.replace( 0, _first, _block, _last + 1, _first );
}
_block.resize( _last );
auto _btag = std::make_pair( file, _id );
ctxt.blocks.put( _btag, _block );
ctxt.map_tags.put( _btag );
_block = _tmp;
++_id;
}
} while( _file );
return 0;
}
samples/count_all_words/mapreduce/mapreduce.cpp
#include "mapreduce.h"
namespace std {
template< typename T >
}
}
struct count
{
typedef std::string key_type;
typedef size_type result_type;
template< typename IStream, typename OutCollection >
inline void operator()( IStream & iss, OutCollection & out ) const
{
std::string _word;
while( iss >> _word ) {
std::transform(_word.begin(), _word.end(), _word.begin(), ::tolower);
}
}
};
int main( int argc, char * argv[])
{
typedef mapreduce_context< count, std::plus<size_type> > caw_context;
#ifdef _DIST_
#endif
if( argc < 2 ) {
std::cerr << "expected arguments: <file1>[ <file2> ...]\n";
exit(1);
}
caw_context * mapred = make_mapreduce( count(), std::plus<size_type>() );
tbb::tick_count startTime = tbb::tick_count::now();
for( int i = 1; i<argc; ++i ) {
mapred->read_tags.put( argv[i] );
}
mapred->wait();
tbb::tick_count endTime = tbb::tick_count::now();
std::cout << mapred->results.size() << std::endl;
for( auto i = mapred->results.begin(); i != mapred->results.end(); ++i ) {
std::cout << i->first << " \t " << *i->second << std::endl;
}
delete mapred;
std::cout << "Time: " << (endTime-startTime).seconds() << "s.\n";
return 0;
}
samples/reduce_2d/reduce_2d/reduce_2d.cpp
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <cnc/reduce.h>
#include <cassert>
const int N = 32;
const int MX = 24;
typedef std::pair< int, int > tag_type;
struct selector
{
template< typename T, typename S, typename R >
bool operator()( const std::pair< T, S > & t, R & r ) const {
if( t.first >= MX ) return false;
r = t.second;
return true;
}
template< typename T, typename R >
bool operator()( const T & t, R & r ) const {
r = 0;
return true;
}
};
struct putter
{
template< typename T, typename C >
int execute( const T & t, C & ctxt ) const
{
ctxt.a.put( t, 1 );
if( t.first >= MX && t.first == t.second ) ctxt.cnt1.put( t.first, MX );
return 0;
}
};
struct reduce_context :
public CnC::context< reduce_context >
{
reduce_context()
: tags( *this, "tags" ),
a( *this, "a" ),
cnt1( *this, "cnt1" ),
cnt2( *this, "cnt2" ),
sum1( *this, "sum1" ),
sum2( *this, "sum2" ),
sc( *this, "step" ),
red1( NULL ),
red2( NULL )
{
a,
cnt1,
sum1,
std::plus<int>(),
0,
selector() );
sum1,
cnt2,
sum2,
std::plus<int>(),
0,
selector() );
#ifdef _CNC_TESTING_
#endif
}
~reduce_context()
{
delete red1;
}
};
int main()
{
#ifdef _DIST_
#endif
reduce_context ctxt;
for( int i = 2; i < MX; ++i ) ctxt.cnt1.put( i, MX );
for( int i = 0; i < N; ++i ) {
for( int j = N-1; j >= 0; --j ) ctxt.tags.put( tag_type( i, j ) );
}
#ifdef _CNC_TESTING_
ctxt.wait();
#endif
ctxt.cnt1.put( 0, MX );
ctxt.cnt2.put(0,N);
#ifdef _CNC_TESTING_
ctxt.wait();
#endif
ctxt.cnt1.put( 1, MX );
ctxt.wait();
auto _sz = ctxt.sum1.size();
if( _sz != N ) {
std::cerr << "#reductions is " << _sz << ", expected " << N << std::endl;
return 1239;
}
for( auto i = ctxt.sum1.begin(); i != ctxt.sum1.end(); ++i ) {
if( *i->second != MX ) {
std::cerr << "cnt1 of " << i->first << " is " << *i->second << ", expected " << MX << std::endl;
return 1234;
}
}
int n = 0;
ctxt.sum2.get(0, n );
if( n != N*MX ) {
std::cerr << "reduce count is " << n << ", expected " << N*MX << std::endl;
return 1236;
}
std::cout << "Success with " << n << std::endl;
return 0;
}
samples/hidden_graph/hidden_graph/hidden_graph.cpp
#ifdef _DIST_
# include <cnc/dist_cnc.h>
#else
# include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
#include <cassert>
#include <ctime>
#include <tbb/concurrent_queue.h>
#include <thread>
#include <chrono>
template< typename IC_IN, typename IC_OUT, typename TC_OUT >
{
private:
typedef tbb::concurrent_bounded_queue< typename IC_IN::data_type > blocking_queue;
struct on_data : public IC_IN::callback_type
{
on_data( blocking_queue & q ) : m_q(q) {}
void on_put( const typename IC_IN::tag_type & , const typename IC_IN::data_type & val )
{
m_q.push( val );
};
blocking_queue & m_q;
};
struct observe_and_compute {
void operator()( blocking_queue * queue, IC_OUT * dataout, TC_OUT * tagout, const hidden_graph< IC_IN, IC_OUT, TC_OUT > * graph )
{
typename IC_IN::data_type _item;
do {
queue->pop( _item );
int _tm = rand() % 1111;
std::this_thread::sleep_for( std::chrono::milliseconds(_tm) );
if( _tm % 4 ) {
dataout->put( _tag, _item + _tm );
tagout->put( _tag );
++_tag;
}
graph->enter_quiescence();
CnC::Internal::Speaker oss;
oss << "done observe_and_compute";
}
};
public:
template< typename Ctxt >
hidden_graph(
CnC::context< Ctxt > & ctxt,
const std::string & name, IC_IN & ic1, IC_OUT & ic2, TC_OUT & tc )
:
CnC::graph( ctxt, name ),
m_input( ic1 ),
m_dataout( ic2 ),
m_tagout( tc ),
m_queue(),
m_thread( observe_and_compute(), &m_queue, &m_dataout, &m_tagout, this )
{
this->leave_quiescence();
m_input.on_put( new on_data( m_queue ) );
}
virtual ~hidden_graph()
{
m_thread.join();
}
private:
IC_IN & m_input;
IC_OUT & m_dataout;
TC_OUT & m_tagout;
blocking_queue m_queue;
std::thread m_thread;
};
template< typename Ctxt, typename IC_IN, typename IC_OUT, typename TC_OUT >
hidden_graph< IC_IN, IC_OUT, TC_OUT > * make_hgraph(
CnC::context< Ctxt > & ctxt,
const std::string & name, IC_IN & ic1, IC_OUT & ic2, TC_OUT & tc )
{
return new hidden_graph< IC_IN, IC_OUT, TC_OUT >( ctxt, name, ic1, ic2, tc );
}
struct hg_context;
struct consume
{
int execute( const int tag, hg_context & ctxt ) const;
};
{
int consumed_on( const int & tag ) const
{
return tag % numProcs();
}
};
{
hg_context()
: consumer( *this, "consumer" ),
input_data( *this, "input_data" ),
processed_data( *this, "processed_data" ),
result_data( *this, "result_data" ),
consumer_tags( *this, "consumer_tags" )
{
hgraph = make_hgraph( *this, "hidden_graph", input_data, processed_data, consumer_tags );
}
};
int consume::execute( const int tag, hg_context & ctxt ) const
{
int _val;
ctxt.processed_data.get( tag, _val );
ctxt.result_data.put( tag+tag, _val*_val );
return 0;
}
int main()
{
srand( 11 );
#ifdef _DIST_
#endif
hg_context _ctxt;
for( int i = 0; i < 444; ++i ) {
_ctxt.input_data.put( i, rand() );
}
_ctxt.wait();
std::cerr <<
"Error: expected " << (7 *
CnC::tuner_base::numProcs()) <<
" items, found " << _ctxt.result_data.size() << std::endl;
exit(11);
}
return 0;
}
samples/mpicnc/mpicnc/mpicnc.cpp
#include <mpi.h>
#ifdef _DIST_
#include <cnc/dist_cnc.h>
#else
#include <cnc/cnc.h>
#endif
#include <cnc/debug.h>
struct my_context;
int rank = 0;
struct MyStep
{
int execute( int n, my_context & c ) const;
};
const int N = 480;
const int F = 6;
#include "mpicnc.h"
{
my_context()
:
CnC::context< my_context >(),
m_steps( *this ),
m_tags( *this ),
m_items( *this )
{
}
};
int MyStep::execute( int t, my_context & c ) const
{
int item = 11;
if( t ) c.m_items.get( t/F, item );
c.m_items.put( t, t+item*item );
}
void cnc_phase( MPI_Comm mc, bool dist_env )
{
#ifdef _DIST_
#endif
std::cout << "Let's go\n";
int numranks = 0;
MPI_Comm_rank(mc,&rank);
MPI_Comm_size(mc,&numranks);
if( rank == 0 || dist_env ) {
my_context c;
if( dist_env ) MPI_Barrier( mc );
int s = rank;
int inc = dist_env ? numranks : 1;
for (int number = s; number < N; number += inc) {
c.m_tags.put(number);
}
c.wait();
std::cout << "done\n";
}
}
int main( int argc, char *argv[] )
{
int numranks;
int p;
MPI_Init_thread( 0, NULL, MPI_THREAD_MULTIPLE, &p );
if( p != MPI_THREAD_MULTIPLE ) std::cerr << "Warning: not MPI_THREAD_MULTIPLE (" << MPI_THREAD_MULTIPLE << "), but " << p << std::endl;
MPI_Comm_size(MPI_COMM_WORLD,&numranks);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if( rank == 0 ) {
system("ldd /home/fschlimb/cnc/trunk/distro/tests_runtime/tests-linux-intel64/distmpicnc");
}
MPI_Comm newcomm;
int color = rank%2;
MPI_Comm_split(MPI_COMM_WORLD, color, rank, &newcomm);
for( int i = 0; i < 2; ++i ) {
cnc_phase( newcomm, color == 1 );
int res;
MPI_Allreduce(&color, &res, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
}
MPI_Finalize();
if( rank == 0 ) std::cerr << "\n\nFinalized and out.\nThis should be the last message.\n";
}
matrix_inverse/matrix_inverse_distenv/matrix_inverse.cpp
#ifdef _DIST_
#include <mpi.h>
#include <cnc/dist_cnc.h>
#include <cnc/internal/dist/distributor.h>
#else
#include <cnc/cnc.h>
#endif
#include "cnc/debug.h"
#include <utility>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <cassert>
#include <memory>
#ifdef WIN32
#include <windows.h>
#include <psapi.h>
#else
#include <sys/resource.h>
#endif
#include "tbb/tick_count.h"
#include "tbb/atomic.h"
#include "../tile.h"
class tile_array;
struct tile_tag {
int m_i0, m_i1, m_i2, m_dim;
tile_tag( int dim, int i0, int i1, int i2 ) :
m_i0(i0), m_i1(i1), m_i2(i2), m_dim(dim) {};
bool operator==( const tile_tag & t ) const {
return m_dim == t.m_dim &&
m_i0 == t.m_i0 && m_i1 == t.m_i1 && m_i2 == t.m_i2;
}
#ifdef _DIST_
tile_tag()
: m_i0( -1 ), m_i1( -1 ), m_i2( -1 ), m_dim( 0 )
{}
{
ser & m_i0 & m_i1 & m_i2 & m_dim;
}
#endif
};
template <>
{
size_t operator()(const tile_tag& tt) const
{
unsigned int h = (int)tt.m_dim;
unsigned int high = h & 0xf8000000;
h = h << 5;
h = h ^ (high >> 27);
h = h ^ tt.m_i0;
unsigned int high1 = h & 0xf8000000;
h = h << 5;
h = h ^ (high1 >> 27);
h = h ^ tt.m_i1;
unsigned int high2 = h & 0xf8000000;
h = h << 5;
h = h ^ (high2 >> 27);
h = h ^ tt.m_i2;
return size_t(h);
}
};
namespace std {
std::ostream & cnc_format( std::ostream& os, const tile_tag &tt )
{
return os << "(" << tt.m_dim << ":"
<< tt.m_i0 << "," << tt.m_i1 << "," << tt.m_i2 << ")";
}
}
struct my_context;
struct compute_inverse
{
int execute( const tile_tag & t, my_context & c ) const;
};
{
typedef tile_tag tag_type;
int PROC_FOR_TILE( int _x, int _y ) const { return ( ( ( ( (_y) * m_tnx + 31 ) + (_x) ) ) % m_nP ); }
int COMPUTE_ON( int _i, int _j ) const { return ( PROC_FOR_TILE( (_i) / m_tsx, (_j) / m_tsy ) ); }
template< class dependency_consumer >
void depends( const tile_tag & tag, my_context & c, dependency_consumer & dC ) const;
my_tuner( int ntiles = 0 );
int compute_on( const tile_tag & tag, my_context & ) const;
int get_count( const tag_type & tag ) const;
#ifdef NO_CONSUMED_ON
#else
const std::vector< int > & consumed_on( const tile_tag & tag ) const;
#endif
int produced_on( const tile_tag & tag ) const;
int m_nP;
int m_tnx, m_tny, m_tsx, m_tsy;
std::vector< std::vector< int > > m_rows, m_cols, m_rowcols, m_procs;
std::vector< int > m_all;
{
ser & m_nP & m_tnx & m_tny & m_tsx & m_tsy
& m_rows & m_cols & m_rowcols & m_procs & m_all;
assert( m_nP > 0 && m_nP == (int)m_procs.size() );
}
};
typedef std::shared_ptr< const tile > const_tile_type;
typedef std::shared_ptr< tile > tile_type;
{
my_tuner m_tuner;
my_context( int nt = 0 )
m_tuner( nt ),
m_steps( *this, "mi", compute_inverse(), m_tuner ),
m_tiles( *this, m_tuner ),
m_tags( *this )
{
#if 0
#endif
}
{
ser & m_tuner;
}
};
#ifdef _DIST_
# define FOR_ME( _c, _r, _x, _y ) ((_r) == _c.m_tuner.COMPUTE_ON( _x, _y ))
# define FOR_ME_OR_0( _c, _r, _x, _y ) (((_r)==0) || FOR_ME( _c, _r, _x, _y ))
#else
# define FOR_ME( _c, _r, _x, _y ) true
# define FOR_ME_OR_0( _c, _r, _x, _y ) true
#endif
class tile_array
{
int m_dim;
int m_size;
const_tile_type * m_tiles;
public:
int dim() const { return m_dim; }
int size() const { return m_size; }
tile_array( int size = 0 ) :
m_dim((size + TILESIZE - 1)/TILESIZE),
m_size(size),
m_tiles( NULL )
{
if( m_dim ) m_tiles = new const_tile_type[m_dim*m_dim];
}
~tile_array()
{
delete[] m_tiles;
}
tile_array(const tile_array& t)
{
m_size = t.m_size;
m_dim = t.m_dim;
int sz = m_dim*m_dim;
m_tiles = new const_tile_type[sz];
for( int i = 0; i < sz; ++i ) {
m_tiles[i] = t.m_tiles[i];
}
}
tile_array& operator=(const tile_array& t)
{
if (this != &t) {
int sz = t.m_dim*t.m_dim;
if( m_dim != t.m_dim ) {
delete[] m_tiles;
m_tiles = new const_tile_type[sz];
m_size = t.m_size;
m_dim = t.m_dim;
}
for( int i = 0; i < sz; ++i ) {
m_tiles[i] = t.m_tiles[i];
}
}
return *this;
}
void dump( double epsilon = 1e-12 ) const {
for (int i = 0; i < m_dim; i++ ) {
for (int j = 0; j < m_dim; j++ ) {
std::cout << "(" << i << "," << j << ")" << std::endl;
m_tiles[m_dim*i+j]->dump(epsilon);
}
std::cout << std::endl;
}
}
int generate_matrix( int dimension, my_context & c )
{
#ifdef _DIST_
int rank;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
#endif
printf("Floating point elements per matrix: %i x %i\n", dimension, dimension);
printf("Floating point elements per tile: %i x %i\n", TILESIZE, TILESIZE);
if( m_size != dimension ) {
delete[] m_tiles;
m_size = dimension;
m_dim = (m_size + TILESIZE - 1)/TILESIZE;
m_tiles = new const_tile_type[m_dim*m_dim];
}
printf("tiles per matrix: %i x %i\n", m_dim, m_dim);
int dim = m_dim;
int size = m_size;
std::cout << "dim(" << dim << ") size(" << size << ")" << std::endl;
double e = 0.0;
for (int I = 0; I < dim; I++) {
for (int J = 0; J < dim; J++) {
if( FOR_ME_OR_0( c, rank, I, J ) ) {
srand( I*m_dim+J );
int ii = I * TILESIZE;;
tile_type _tile = std::make_shared< tile >();
for (int i = 0; i < TILESIZE; i++) {
int jj = J * TILESIZE;
for (int j = 0; j < TILESIZE; j++) {
if ((ii < size)&(jj < size)) e = double(rand())/RAND_MAX;
else if (ii == jj) e = 1;
else e = 0;
_tile->set(i,j,e);
jj++;
}
ii++;
}
m_tiles[dim*I + J] = _tile;
}
}
}
return m_dim;
}
int identity_check( double epsilon = MINPIVOT ) const
{
int ecount = 0;
for (int i = 0; i < m_dim; i++ ) {
for (int j = 0; j < m_dim; j++ ) {
int tcount = 0;
const_tile_type t = m_tiles[m_dim*i+j];
tcount = (i == j) ? t->identity_check(epsilon) : t->zero_check(epsilon);
if (tcount == 0 ) continue;
std::cout << "problem in tile(" << i << "," << j << ")" << std::endl;
ecount += tcount;
}
}
return ecount;
}
bool equal( const tile_array &b ) const
{
if (b.m_dim != m_dim) return false;
for (int i = 0; i < m_dim; i++ ) {
for (int j = 0; j < m_dim; j++ ) {
const_tile_type t = m_tiles[m_dim*i+j];
if (!t->equal( *b.m_tiles[m_dim*i+j] )) return false;
}
}
return true;
}
tile_array multiply(const tile_array &b) const
{
tile_array c(m_size);
for (int i = 0; i < m_dim; i++) {
for (int j = 0; j < m_dim; j++) {
tile_type t = std::make_shared< tile >();
t->zero();
for (int k = 0; k < m_dim; k++) {
t->multiply_add_in_place(*m_tiles[m_dim*i+k], *b.m_tiles[m_dim*k+j]);
}
c.m_tiles[m_dim*i+j] = t;
}
}
return c;
}
tile_array inverse()
{
tile_array b = *this;
int dim = m_dim;
for (int n = 0; n < dim; n++) {
const_tile_type pivot_inverse = std::make_shared< const tile >( C_INVERSE, *b.m_tiles[dim*n+n] );
b.m_tiles[dim*n+n] = pivot_inverse;
for (int j = 0; j < dim; j++) {
if (j == n) continue;
const tile& tnj = *b.m_tiles[dim*n+j];
b.m_tiles[dim*n+j] = std::make_shared< const tile >( C_MULTIPLY, *pivot_inverse, tnj );
}
for (int i = 0; i < dim; i++) {
if (i == n) continue;
const_tile_type tin = b.m_tiles[dim*i+n];
b.m_tiles[dim*i+n] = std::make_shared< const tile >( C_MULTIPLY_NEGATE, *tin, *pivot_inverse );
for (int j = 0; j < dim; j++) {
if (j == n) continue;
const_tile_type tnj = b.m_tiles[dim*n+j];
tile_type tmp = std::make_shared< tile >( *b.m_tiles[dim*i+j] );
tmp->multiply_subtract_in_place(*tin, *tnj);
b.m_tiles[dim*i+j] = tmp;
}
}
}
return b;
}
tile_array inverse_cnc( my_context & c )
{
int rank = 0;
#ifdef _DIST_
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
#endif
for (int i = 0; i < m_dim; i++) {
for (int j = 0; j < m_dim; j++) if( FOR_ME( c, rank, i, j ) ) {
tile_tag t( m_dim, 0, i, j);
c.m_tiles.put( t, m_tiles[m_dim*i+j] );
assert( m_tiles[m_dim*i+j].get() );
}
}
for (int i = 0; i < m_dim; i++) {
for (int j = 0; j < m_dim; j++) if( FOR_ME( c, rank, i, j ) ) {
c.m_tags.put( tile_tag( m_dim, 0, i, j) );
}
}
c.wait();
tile_array b(m_size);
for (int i = 0; i < m_dim; i++) {
for (int j = 0; j < m_dim; j++) if( FOR_ME_OR_0( c, rank, i, j ) ) {
const_tile_type _tmp;
c.m_tiles.get( tile_tag( m_dim, m_dim, i, j), _tmp );
b.m_tiles[m_dim*i+j] = _tmp;
}
}
return b;
}
};
int compute_inverse::execute( const tile_tag & tag, my_context & c ) const
{
int n = tag.m_i0;
int i = tag.m_i1;
int j = tag.m_i2;
tile_tag out_tag( tag.m_dim, n+1, i, j );
if (i == n && j == n )
{
const_tile_type tnn;
c.m_tiles.get( tag, tnn );
c.m_tiles.put( out_tag, std::make_shared< const tile >( C_INVERSE, *tnn ) );
}
else if ( i == n )
{
const_tile_type tnj;
c.m_tiles.get( tag, tnj );
assert( tnj.get() );
const_tile_type tn1nn;
c.m_tiles.get( tile_tag( tag.m_dim, n+1, n, n ), tn1nn );
c.m_tiles.put( out_tag, std::make_shared< const tile >( C_MULTIPLY, *tn1nn, *tnj ) );
}
else if ( j == n )
{
const_tile_type tin;
c.m_tiles.get( tag, tin );
const_tile_type tn1nn;
c.m_tiles.get( tile_tag( tag.m_dim, n+1, n, n ), tn1nn );
c.m_tiles.put( out_tag, std::make_shared< const tile >( C_MULTIPLY_NEGATE, *tin, *tn1nn ) );
}
else
{
const_tile_type tij;
c.m_tiles.get( tag, tij );
const_tile_type tnin;
c.m_tiles.get( tile_tag( tag.m_dim, n, i, n ), tnin );
const_tile_type tn1nj;
c.m_tiles.get( tile_tag( tag.m_dim, n+1, n, j ), tn1nj );
tile_type tmp = std::make_shared< tile >( *tij );
tmp->multiply_subtract_in_place( *tnin, *tn1nj );
assert( tmp.get() );
c.m_tiles.put( out_tag, tmp );
}
if ( (n+1) < tag.m_dim )
{
c.m_tags.put( out_tag );
}
}
int my_tuner::get_count( const tag_type & tt ) const
{
int dim = tt.m_dim;
int n = tt.m_i0;
int i = tt.m_i1;
int j = tt.m_i2;
int count = 1;
if (i == (n-1) && j == (n-1)) count += (dim-1) + (dim-1);
if (i == (n-1) && !(j == n-1)) count += dim-1;
if (j == n && !(i == n)) count += dim-1;
return count;
}
my_tuner::my_tuner( int ntiles )
: m_tnx( 0 ),
m_tny( 0 ),
m_tsx( 1 ),
m_tsy( 1 ),
m_rows(),
m_cols(),
m_rowcols(),
m_procs(),
{
m_nP = numProcs();
#ifdef _DIST_
int _np = m_nP * 1;
assert( _np == 1 || ( ntiles * ntiles ) % _np == 0 );
if( _np > 1 && ntiles ) {
m_tnx = 2, m_tny = _np / 2;
while( m_tnx < m_tny && m_tny % 2 == 0 ) {
m_tnx *= 2;
m_tny = _np / m_tnx;
}
assert( m_tnx * m_tny == _np );
m_tsx = ntiles / m_tnx;
m_tsy = ntiles / m_tny;
std::cerr << m_tnx << "x" << m_tny << " tiles of " << m_tsx << "x" << m_tsy << std::endl;
assert( m_tnx * m_tsx == ntiles && m_tny * m_tsy == ntiles );
#ifndef NO_CONSUMED_ON
m_rows.resize( m_tny );
m_cols.resize( m_tnx );
m_rowcols.resize( m_tnx * m_tny );
for( int i = 0; i < m_tnx; ++i ) {
m_cols[i].resize( m_tny );
for( int j = 0; j < m_tny; ++j ) {
m_rowcols[j*m_tnx+i].resize( m_tnx+m_tny );
}
}
for( int j = 0; j < m_tny; ++j ) {
m_rows[j].resize( m_tnx );
for( int i = 0; i < m_tnx; ++i ) {
m_rows[j][i] = m_cols[i][j] = PROC_FOR_TILE( i, j );
for( int x = 0; x < m_tnx; ++x ) m_rowcols[j*m_tnx+i][x] = PROC_FOR_TILE( x, j );
for( int y = 0; y < m_tny; ++y ) m_rowcols[j*m_tnx+i][m_tnx+y] = PROC_FOR_TILE( i, y );
m_rowcols[j*m_tnx+i][i] = m_rowcols[j*m_tnx+i].back();
m_rowcols[j*m_tnx+i].pop_back();
}
}
m_procs.resize( m_nP );
for(
int i = 0; i < m_nP; ++i ) m_procs[i].
resize( 1, i );
assert( m_nP > 0 && (int)m_procs.size() == m_nP );
#endif
}
#endif
}
int my_tuner::compute_on( const tile_tag & tag, my_context & ) const
{
return COMPUTE_ON( tag.m_i1, tag.m_i2 );
}
int my_tuner::produced_on( const tile_tag & tag ) const
{
return ( tag.m_i0 > 0 ? COMPUTE_ON( tag.m_i1, tag.m_i2 ) : 0 );
}
template< class dependency_consumer >
void my_tuner::depends( const tile_tag & tag, my_context & c, dependency_consumer & dC ) const
{
int n = tag.m_i0;
int i = tag.m_i1;
int j = tag.m_i2;
dC.depends( c.m_tiles, tag );
if (i == n && j == n ) {
} else if ( i == n ) {
dC.depends( c.m_tiles, tile_tag( tag.m_dim, n+1, n, n ) );
} else if ( j == n ) {
dC.depends( c.m_tiles, tile_tag( tag.m_dim, n+1, n, n ) );
} else {
dC.depends( c.m_tiles, tile_tag( tag.m_dim, n, i, n ) );
dC.depends( c.m_tiles, tile_tag( tag.m_dim, n+1, n, j ) );
}
}
#ifndef NO_CONSUMED_ON
const std::vector< int > & my_tuner::consumed_on( const tile_tag & tag ) const
{
assert( 0 < m_procs.size() );
int n = tag.m_i0;
int i = tag.m_i1;
int j = tag.m_i2;
if( n - 1 == i && ( i == j || n == j ) ) {
return m_rowcols[(j/m_tsy)*m_tnx+(i/m_tsx)];
} else if( n - 1 == i ) {
return m_rows[j/m_tsy];
} else if( n == j ) {
return m_cols[i/m_tsx];
}
return m_procs[COMPUTE_ON( i, j )];
}
#endif
void report_memory()
{
std:: cout << "tiles created " << tiles_created << " tiles deleted " << tiles_deleted << " tiles remaining " << tiles_created - tiles_deleted << std::endl;
tiles_created = 0;
tiles_deleted = 0;
static int lastr = 0;
#ifdef WIN32
HANDLE self;
PROCESS_MEMORY_COUNTERS pmc;
SIZE_T resident = 0;
self = GetCurrentProcess();
if (GetProcessMemoryInfo(self, &pmc, sizeof(pmc))) {
resident = pmc.WorkingSetSize;
}
CloseHandle(self);
#else
FILE *f = fopen("/proc/self/statm", "r");
int total, resident, share, trs, drs, lrs, dt;
if( fscanf(f,"%d %d %d %d %d %d %d", &total, &resident, &share, &trs, &drs, &lrs, &dt) != 7 ) std::cerr << "error reading /proc/self/statm\n";
#endif
std:: cout << "resident memory MB " << double(resident*4096)/1000000 << " increment MB " << double((resident-lastr)*4096)/1000000 << std::endl;
lastr = resident;
}
void report_time( const char * mode, int msz, double time )
{
std::cout << mode << " Total Time: " << time << " sec" << std::endl;
float Gflops = ((float)2*msz*msz*msz)/((float)1000000000);
if (Gflops >= .000001) printf("Floating-point operations executed: %f billion\n", Gflops);
if (time >= .001) printf("Floating-point operations executed per unit time: %6.2f billions/sec\n", Gflops/time);
}
int main(int argc, char *argv[])
{
if (!(argc == 2 && 0 != atoi(argv[1]))) {
std::cout << "Usage: matrix_inverse dim" << std::endl;
return -1;
}
int sz = atoi(argv[1]);
int tdim = (sz + TILESIZE - 1)/TILESIZE;
#ifdef _DIST_
int p;
MPI_Init_thread( 0, NULL, MPI_THREAD_MULTIPLE, &p );
if( p != MPI_THREAD_MULTIPLE ) std::cerr << "Warning: not MPI_THREAD_MULTIPLE (" << MPI_THREAD_MULTIPLE << "), but " << p << std::endl;
int rank = 0;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
{
{
#endif
tile_array in_array;
struct my_context c( tdim );
std::cout << "Generating matrix of size " << argv[1] << std::endl;
tdim = in_array.generate_matrix(sz, c);
report_memory();
{
std::cout << "Invert serially" << std::endl;
tbb::tick_count t0 = tbb::tick_count::now();
#ifndef _DIST_
tile_array out_array = in_array.inverse();
#endif
tbb::tick_count t1 = tbb::tick_count::now();
report_time( "Serial", sz, (t1-t0).seconds() );
report_memory();
#ifndef _DIST_
tile_array test = in_array.multiply(out_array);
test.identity_check(1e-5);
#endif
}
#ifdef _DIST_
MPI_Barrier( MPI_COMM_WORLD );
#endif
report_memory();
{
std::cout << "Invert CnC steps" << std::endl;
tbb::tick_count t2 = tbb::tick_count::now();
tile_array out_array2 = in_array.inverse_cnc(c);
tbb::tick_count t3 = tbb::tick_count::now();
report_time( "CnC", out_array2.size(), (t3-t2).seconds() );
report_memory();
#ifdef _DIST_
if( rank == 0 )
#endif
{
tile_array test2 = in_array.multiply(out_array2);
test2.identity_check(1e-5);
}
}
report_memory();
#ifdef _DIST_
MPI_Barrier( MPI_COMM_WORLD );
}
}
MPI_Finalize();
#endif
return 0;
}
samples/db/mysql_simple/mysql_simple.cpp
#include <cnc/cnc.h>
#include "mysql_tuner.h"
struct my_context;
struct my_sqlstep
{
int execute( int, my_context & ctxt ) const;
};
{
sql_tuner m_tuner;
my_context()
: m_tuner( {"tcp://127.0.0.1:3306",
"cnc", "cnc",
"test",
"DROP TABLE IF EXISTS items;",
"CREATE TABLE If NOT EXISTS items (id INT, value INT);",
"SELECT id, value FROM items;",
"DELETE * FROM items;",
"SELECT value FROM items WHERE id=?;",
"INSERT INTO items( id, value ) VALUES ( ?, ? );",
"DELETE FROM items WHERE id=?;",
}),
m_tags( *this, "tags" ),
m_items( *this, "items", m_tuner ),
m_steps( *this, "steps" )
{
}
};
int my_sqlstep::execute( int t, my_context & ctxt ) const
{
int r;
ctxt.m_items.get( t-1, r );
ctxt.m_items.put( t, t+r );
return 0;
}
int main(void)
{
my_context _ctxt;
_ctxt.m_items.put( -1, -1 );
for( int i = 0; i<100; ++i ) {
_ctxt.m_tags.put( i );
}
_ctxt.wait();
for( int i = 0; i<10; ++i ) {
int _ir = -1;
_ctxt.m_items.get( i, _ir );
std::cout << _ir << " for " << i << std::endl;
}
return 0;
}