/*
    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.
*/

/*
    Evolution.cpp: implementation file for evolution classes; evolution 
                  classes do looped evolution of patterns in a defined 
                  2 dimensional space
*/

#include "Evolution.h"
#include "Board.h"

#ifdef USE_SSE
#define GRAIN_SIZE 14
#else
#define GRAIN_SIZE 4000
#endif
#define TIME_SLICE 330

/*
    Evolution
*/

/**
    Evolution::UpdateMatrix() - moves the calculated destination data 
    to the source data block. No destination zeroing is required since it will 
    be completely overwritten during the next calculation cycle.
**/
void Evolution::UpdateMatrix()
{
    memcpy(m_matrix->data, m_dest, m_size);
}

/*
    SequentialEvolution
*/

//! SequentialEvolution::Run - begins looped evolution
#ifndef _CONSOLE
void SequentialEvolution::Run()
{
#else
void SequentialEvolution::Run(double execution_time, int nthread)
{
    printf("Starting game (Sequential evolution)\n");
#endif

    m_nIteration = 0;
    m_serial_time = 0;
    tbb::tick_count t0 = tbb::tick_count::now();
    while (!m_done)
    {
        if( !is_paused ) 
        {
            tbb::tick_count t = tbb::tick_count::now();
            Step();
            tbb::tick_count t1 = tbb::tick_count::now();
            ++m_nIteration;
            double  work_time = (t1-t0).seconds();
#ifndef _CONSOLE
            if ( work_time * 1000 < TIME_SLICE )
                continue;
            m_serial_time += work_time;
            m_board->draw(m_nIteration);
#else
            m_serial_time += work_time;
#endif
        }
        //! Let the parallel algorithm work uncontended almost the same time
        //! as the serial one. See ParallelEvolution::Run() as well.
#ifndef _CONSOLE
        m_evt_start_parallel->Set();
        m_evt_start_serial->WaitOne();
        t0 = tbb::tick_count::now();
#else
        t0 = tbb::tick_count::now();
        if(m_serial_time > execution_time)
        {
            printf("iterations count = %d time = %g\n", m_nIteration, m_serial_time);
            break;
        }
#endif
    }
}

//! SequentialEvolution::Step() - override of step method
void SequentialEvolution::Step()
{
        if( !is_paused ) 
    {
#ifdef USE_SSE
    UpdateState(m_matrix, m_matrix->data, 0, m_matrix->height);
#else
    UpdateState(m_matrix, m_dest, 0, (m_matrix->width * m_matrix->height)-1);
    UpdateMatrix();
#endif
        }
}

/*
    ParallelEvolution
*/

//! SequentialEvolution::Run - begins looped evolution
#ifndef _CONSOLE
void ParallelEvolution::Run()
{
#else
void ParallelEvolution::Run(double execution_time, int nthread)
{
    if(nthread == tbb::task_scheduler_init::automatic)
        printf("Starting game (Parallel evolution for automatic number of thread(s))\n");
    else
        printf("Starting game (Parallel evolution for %d thread(s))\n", nthread);
#endif

    m_nIteration = 0;
    m_parallel_time = 0;

#ifndef _CONSOLE
    //! start task scheduler as necessary
    if (m_pInit == NULL)
    {
        m_pInit = new tbb::task_scheduler_init();
    }
    m_evt_start_parallel->WaitOne();
#else
    tbb::task_scheduler_init init(nthread);
#endif

    double  work_time = m_serial_time;
    tbb::tick_count t0 = tbb::tick_count::now();

    while (!m_done)
    {
        if( !is_paused ) 
        {
            tbb::tick_count t = tbb::tick_count::now();
            Step();
            tbb::tick_count t1 = tbb::tick_count::now();
            ++m_nIteration;
            double real_work_time = (t1-t0).seconds();
#ifndef _CONSOLE
            if ( real_work_time < work_time )
                continue;
            m_parallel_time += real_work_time;
            m_board->draw(m_nIteration); 
#else
            m_parallel_time += real_work_time;
#endif
        }
        //! Let the serial algorithm work the same time as the parallel one.
#ifndef _CONSOLE
        m_evt_start_serial->Set();
        m_evt_start_parallel->WaitOne();

        work_time = m_serial_time - m_parallel_time;
        t0 = tbb::tick_count::now();
#else
        t0 = tbb::tick_count::now();
        if(m_parallel_time > execution_time)
        {
            printf("iterations count = %d time = %g\n", m_nIteration, m_parallel_time);
            init.terminate();
            break;
        }
#endif
    }
}

/**
    class tbb_parallel_task
    
    TBB requires a class for parallel loop implementations. The actual 
    loop "chunks" are performed using the () operator of the class. 
    The blocked_range contains the range to calculate. Please see the 
    TBB documentation for more information.
**/
#ifndef _CONSOLE
public class tbb_parallel_task
#else
class tbb_parallel_task
#endif
{
public:
    static void set_values (Matrix* source, char* dest)
    {
        m_source = source;
        m_dest = dest;
        return;
    }

    void operator()( const tbb::blocked_range<size_t>& r ) const 
    {
        int begin = (int)r.begin();            //! capture lower range number for this chunk
        int end = (int)r.end();                //! capture upper range number for this chunk
        UpdateState(m_source, m_dest, begin, end);
    }

    tbb_parallel_task () {}

private:
    static Matrix* m_source;
    static char* m_dest;
};

Matrix* tbb_parallel_task::m_source;
char* tbb_parallel_task::m_dest;

//! ParallelEvolution::Step() - override of Step method
void ParallelEvolution::Step()
{
    size_t begin = 0;                   //! beginning cell position
#ifdef USE_SSE
    size_t end = m_matrix->height;      //! ending cell position
#else
    size_t end = m_size-1;              //! ending cell position
#endif

    //! set matrix pointers
    tbb_parallel_task::set_values(m_matrix, m_dest);

    //! do calculation loop
    parallel_for (tbb::blocked_range<size_t> (begin, end, GRAIN_SIZE), tbb_parallel_task());
    UpdateMatrix();
}
