/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

#include "tbb/parallel_while.h"
#include "harness.h"

const int N = 200;

typedef int Element;

//! Representation of an array index with only those signatures required by parallel_while.
class MinimalArgumentType {
    void operator=( const MinimalArgumentType& );
    long my_value;
    enum {
        DEAD=0xDEAD,
        LIVE=0x2718,
        INITIALIZED=0x3141 
    } my_state;
public:
    ~MinimalArgumentType() {
        ASSERT( my_state==LIVE||my_state==INITIALIZED, NULL );
        my_state = DEAD;
    }
    MinimalArgumentType() {
        my_state = LIVE;
    }
    void set_value( long i ) {
        ASSERT( my_state==LIVE||my_state==INITIALIZED, NULL );
        my_value = i;
        my_state = INITIALIZED;
    }
    long get_value() const {
        ASSERT( my_state==INITIALIZED, NULL );
        return my_value;
    } 
};

class IntegerStream {
    long my_limit;
    long my_index;
public:
    IntegerStream( long n ) : my_limit(n), my_index(0) {}
    bool pop_if_present( MinimalArgumentType& v ) {
        if( my_index>=my_limit ) 
            return false;
        v.set_value( my_index );
        my_index+=2;
        return true;
    }
};

class MatrixMultiplyBody: NoAssign {
    Element (*a)[N];
    Element (*b)[N];
    Element (*c)[N];
    const int n;
    tbb::parallel_while<MatrixMultiplyBody>& my_while;
public:
    typedef MinimalArgumentType argument_type;
    void operator()( argument_type i_arg ) const {
        long i = i_arg.get_value();
        if( (i&1)==0 && i+1<N ) {
            MinimalArgumentType value;
            value.set_value(i+1);
            my_while.add( value );
        }
        for( int j=0; j<n; ++j )    
            c[i][j] = 0;
        for( int k=0; k<n; ++k ) {
            Element aik = a[i][k];
            for( int j=0; j<n; ++j )    
                c[i][j] += aik*b[k][j];
        }
    }
    MatrixMultiplyBody( tbb::parallel_while<MatrixMultiplyBody>& w, Element c_[N][N], Element a_[N][N], Element b_[N][N], int n_ ) :
        a(a_), b(b_), c(c_), n(n_),  my_while(w)
    {}
};

void WhileMatrixMultiply( Element c[N][N], Element a[N][N], Element b[N][N], int n ) {
    IntegerStream stream( N );
    tbb::parallel_while<MatrixMultiplyBody> w;
    MatrixMultiplyBody body(w,c,a,b,n);
    w.run( stream, body );
}

#include "tbb/tick_count.h"
#include <cstdlib>
#include <cstdio>
using namespace std;

static long Iterations = 5;

static void SerialMatrixMultiply( Element c[N][N], Element a[N][N], Element b[N][N], int n ) {
    for( int i=0; i<n; ++i ) {   
        for( int j=0; j<n; ++j )    
            c[i][j] = 0;
        for( int k=0; k<n; ++k ) {
            Element aik = a[i][k];
            for( int j=0; j<n; ++j )    
                c[i][j] += aik*b[k][j];
        }
    }
}

static void InitializeMatrix( Element x[N][N], int n, int salt ) {
    for( int i=0; i<n; ++i )
        for( int j=0; j<n; ++j )
            x[i][j] = (i*n+j)^salt;
}

static Element A[N][N], B[N][N], C[N][N], D[N][N];

static void Run( int nthread, int n ) {
    /* Initialize matrices */
    InitializeMatrix(A,n,5);
    InitializeMatrix(B,n,10);
    InitializeMatrix(C,n,0);
    InitializeMatrix(D,n,15);

    tbb::tick_count t0 = tbb::tick_count::now();
    for( long i=0; i<Iterations; ++i ) {
        WhileMatrixMultiply( C, A, B, n );
    }
    tbb::tick_count t1 = tbb::tick_count::now();
    SerialMatrixMultiply( D, A, B, n );

    // Check result
    for( int i=0; i<n; ++i )   
        for( int j=0; j<n; ++j )    
            ASSERT( C[i][j]==D[i][j], NULL );
    REMARK("time=%g\tnthread=%d\tn=%d\n",(t1-t0).seconds(),nthread,n);
}

#include "tbb/task_scheduler_init.h"
#include "harness_cpu.h"

int TestMain () {
    if( MinThread<1 ) {
        REPORT("number of threads must be positive\n");
        exit(1);
    }
    for( int p=MinThread; p<=MaxThread; ++p ) {
        tbb::task_scheduler_init init( p );
        for( int n=N/4; n<=N; n+=N/4 )
            Run(p,n);

        // Test that all workers sleep when no work
        TestCPUUserTime(p);
    }
    return Harness::Done;
}

