<commit_before>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, in source and binary forms, with or
without modification, are permitted, provided that the following
conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
CONTRIBUTORS ``AS IS''  AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

// $Id: bd_rigid_updater_test.cc 2594 2010-01-08 21:53:43Z joaander $
// $URL: http://codeblue.umich.edu/hoomd-blue/svn/branches/rigid-bodies/test/unit/bd_rigid_updater_test.cc $

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include <iostream>

//! name the boost unit test module
#define BOOST_TEST_MODULE BDRigidUpdaterTests
#include "boost_utf_configure.h"

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>

#include "TwoStepBDNVT.h"
#include "TwoStepBDNVTRigid.h"
#ifdef ENABLE_CUDA
#include "TwoStepBDNVTRigidGPU.h"
#include "TwoStepBDNVTGPU.h"
#endif

#include "IntegratorTwoStep.h"

#include "BoxResizeUpdater.h"

#include "AllPairPotentials.h"
#include "BinnedNeighborList.h"
#include "Initializers.h"

#ifdef ENABLE_CUDA
#include "BinnedNeighborListGPU.h"
#endif

#include "FENEBondForceCompute.h"

#ifdef ENABLE_CUDA
#include "FENEBondForceComputeGPU.h"
#endif

#include "saruprng.h"
#include <math.h>
#include <time.h>
#include <fstream>
#include <vector>

using namespace std;
using namespace boost;

/*! \file nve_rigid_updater_test.cc
    \brief Implements unit tests for NVERigidUpdater
    \ingroup unit_tests
*/

//! Tolerance for floating point comparisons
#ifdef SINGLE_PRECISION
const Scalar tolerance = Scalar(1e-2);
#else
const Scalar tolerance = Scalar(1e-3);
#endif

struct AtomInfo
{
    int type, localidx, body;
    double mass;
    double x, y, z;
};

struct BondInfo
{
    char type[50];
    int localidxi, localidxj;
    double kappa, R0, sigma, epsilon;
};

struct BuildingBlock
{
    std::vector<AtomInfo> atoms;
    std::vector<BondInfo> bonds;
    double spacing_x, spacing_y, spacing_z;
};

//! Typedef'd TwoStepBDNVTRigid class factory
typedef boost::function<shared_ptr<TwoStepBDNVTRigid> (shared_ptr<SystemDefinition> sysdef,
                            shared_ptr<ParticleGroup> group, Scalar T, unsigned int seed)> bdnvtup_creator;

void bd_updater_lj_tests(bdnvtup_creator bdup_creator, const ExecutionConfiguration& exec_conf)
    {
#ifdef ENABLE_CUDA
    g_gpu_error_checking = true;
#endif

    unsigned int nbodies = 800;
    unsigned int nparticlesperbuildingblock = 5;
    unsigned int nbondsperbuildingblock;
    unsigned int body_size = 5;
    unsigned int natomtypes = 2;
    unsigned int nbondtypes = 1;

    unsigned int N = nbodies * nparticlesperbuildingblock;
    Scalar box_length = 24.0814;
    shared_ptr<SystemDefinition> sysdef(new SystemDefinition(N, BoxDim(box_length), natomtypes, nbondtypes, 0, 0, 0, exec_conf));
    shared_ptr<ParticleData> pdata = sysdef->getParticleData();

    shared_ptr<ParticleSelector> selector_all(new ParticleSelectorTag(sysdef, 0, pdata->getN()-1));
    shared_ptr<ParticleGroup> group_all(new ParticleGroup(sysdef, selector_all));

    BoxDim box = pdata->getBox();

    // setup a simple initial state
    unsigned int ibody = 0;
    unsigned int iparticle = 0;
    Scalar x0 = box.xlo + 0.01;
    Scalar y0 = box.ylo + 0.01;
    Scalar z0 = box.zlo + 0.01;
    Scalar xspacing = 7.0f;
    Scalar yspacing = 1.0f;
    Scalar zspacing = 2.0f;

    BuildingBlock buildingBlock;
    buildingBlock.spacing_x = 6.0;
    buildingBlock.spacing_y = 6.0;
    buildingBlock.spacing_z = 2.0;

    AtomInfo atomi;
    int num_atoms = 5;
    for (int atom_n = 0; atom_n < num_atoms; atom_n++)
        {
        //Add Atom
        atomi.localidx = atom_n;
        atomi.x = Scalar(atom_n);
        atomi.y = 0.0;
        atomi.z = 0.0;
        atomi.body = 1;
        atomi.type = 1;
        atomi.mass = 1.0;
        buildingBlock.atoms.push_back(atomi);
        }

    nparticlesperbuildingblock = buildingBlock.atoms.size();
    nbondsperbuildingblock = buildingBlock.bonds.size();

    unsigned int seed = 258719;
    boost::shared_ptr<Saru> random = boost::shared_ptr<Saru>(new Saru(seed));
    Scalar temperature = 1.4;
    Scalar KE = Scalar(0.0);
    Scalar PE = Scalar(0.0);
    Scalar AvgT = Scalar(0);

    ParticleDataArrays arrays = pdata->acquireReadWrite();

    // initialize bodies in a cubic lattice with some velocity profile
    for (unsigned int i = 0; i < nbodies; i++)
        {
        for (unsigned int j = 0; j < nparticlesperbuildingblock; j++)
            {
            arrays.x[iparticle] = x0 + buildingBlock.atoms[j].x;
            arrays.y[iparticle] = y0 + buildingBlock.atoms[j].y;
            arrays.z[iparticle] = z0 + buildingBlock.atoms[j].z;

            arrays.vx[iparticle] = random->d();
            arrays.vy[iparticle] = random->d();
            arrays.vz[iparticle] = random->d();

            KE += Scalar(0.5) * (arrays.vx[iparticle]*arrays.vx[iparticle] + arrays.vy[iparticle]*arrays.vy[iparticle] + arrays.vz[iparticle]*arrays.vz[iparticle]);

            arrays.type[iparticle] = buildingBlock.atoms[j].type;

            if (buildingBlock.atoms[j].body > 0)
                arrays.body[iparticle] = ibody;

            unsigned int head = i * nparticlesperbuildingblock;
            for (unsigned int j = 0; j < nbondsperbuildingblock; j++)
                {
                unsigned int particlei = head + buildingBlock.bonds[j].localidxi;
                unsigned int particlej = head + buildingBlock.bonds[j].localidxj;

                sysdef->getBondData()->addBond(Bond(0, particlei, particlej));
                }

            iparticle++;
            }

        x0 += xspacing;
        if (x0 + xspacing >= box.xhi)
            {
            x0 = box.xlo + 0.01;

            y0 += yspacing;
            if (y0 + yspacing >= box.yhi)
                {
                y0 = box.ylo + 0.01;

                z0 += zspacing;
                if (z0 + zspacing >= box.zhi)
                    z0 = box.zlo + 0.01;
                }
            }

        ibody++;
        }

    assert(iparticle == N);

    pdata->release();

    Scalar deltaT = Scalar(0.005);
    shared_ptr<TwoStepBDNVTRigid> two_step_bdnvt = bdup_creator(sysdef, group_all, temperature, 453034);

    shared_ptr<IntegratorTwoStep> bdnvt_up(new IntegratorTwoStep(sysdef, deltaT));
    bdnvt_up->addIntegrationMethod(two_step_bdnvt);

    shared_ptr<NeighborList> nlist(new NeighborList(sysdef, Scalar(2.5), Scalar(0.8)));
    shared_ptr<PotentialPairLJ> fc(new PotentialPairLJ(sysdef, nlist));
    fc->setRcut(0, 0, Scalar(1.122));
    fc->setRcut(0, 1, Scalar(1.122));
    fc->setRcut(1, 1, Scalar(1.122));

    // setup some values for alpha and sigma
    Scalar epsilon = Scalar(1.0);
    Scalar sigma = Scalar(1.0);
    Scalar alpha = Scalar(1.0);
    Scalar lj1 = Scalar(4.0) * epsilon * pow(sigma, Scalar(12.0));
    Scalar lj2 = alpha * Scalar(4.0) * epsilon * pow(sigma, Scalar(6.0));

    // specify the force parameters
    fc->setParams(0,0,make_scalar2(lj1,lj2));
    fc->setParams(0,1,make_scalar2(lj1,lj2));
    fc->setParams(1,1,make_scalar2(lj1,lj2));

    bdnvt_up->addForceCompute(fc);

    unsigned int nrigid_dof, nnonrigid_dof;
    Scalar current_temp;

    shared_ptr<RigidData> rdata = sysdef->getRigidData();

    unsigned int start_step = 0;
    unsigned int steps = 5000;
    unsigned int sampling = 100;
    unsigned int averaging_delay = 1000;

    // Initialize rigid bodies
    rdata->initializeData();

    nrigid_dof = rdata->getNumDOF();
    nnonrigid_dof = 3 * (N - body_size * nbodies);

    // Rescale particle velocities to desired temperature:
    current_temp = 2.0 * KE / (nrigid_dof + nnonrigid_dof);
    Scalar factor = sqrt(temperature / current_temp);

    arrays = pdata->acquireReadWrite();
    for (unsigned int j = 0; j < N; j++)
        {
        arrays.vx[j] *= factor;
        arrays.vy[j] *= factor;
        arrays.vz[j] *= factor;
        }

    pdata->release();

    // Production: turn on LJ interactions between rods
    fc->setRcut(1, 1, Scalar(2.5));

    for (unsigned int i = start_step; i <= start_step + steps; i++)
        {

        bdnvt_up->update(i);

        if (i % sampling == 0)
            {

            arrays = pdata->acquireReadWrite();
            KE = Scalar(0.0);
            for (unsigned int j = 0; j < N; j++)
                KE += Scalar(0.5) * (arrays.vx[j]*arrays.vx[j] + arrays.vy[j]*arrays.vy[j] + arrays.vz[j]*arrays.vz[j]);
            PE = fc->calcEnergySum();

            current_temp = 2.0 * KE / (nrigid_dof + nnonrigid_dof);
            if (i > averaging_delay)
                AvgT += current_temp;

            pdata->release();

            }
        }

    AvgT /= Scalar((steps-averaging_delay)/sampling);
    //Test to see if the temperature has equilibrated to where its been set.
    MY_BOOST_CHECK_CLOSE(AvgT, 1.4, 2.5);
    }

#ifdef ENABLE_CUDA
//! TwoStepBDNVTRigidGPU factory for the unit tests
shared_ptr<TwoStepBDNVTRigid> gpu_bdnvt_creator(shared_ptr<SystemDefinition> sysdef, shared_ptr<ParticleGroup> group, Scalar T, unsigned int seed)
    {
    shared_ptr<VariantConst> T_variant(new VariantConst(T));
    return shared_ptr<TwoStepBDNVTRigid>(new TwoStepBDNVTRigidGPU(sysdef, group, T_variant, seed, false));
    }
#endif

#ifdef ENABLE_CUDA

//! Test of Rigid Rods
BOOST_AUTO_TEST_CASE( BDRigidGPU_rod_tests )
    {
    bdnvtup_creator bdnvt_creator_gpu = bind(gpu_bdnvt_creator, _1, _2, _3, _4);
    bd_updater_lj_tests(bdnvt_creator_gpu, ExecutionConfiguration());
    }
#endif

#ifdef WIN32
#pragma warning( pop )
#endif

<commit_msg>test_bd_rigid_updater now compiles<commit_after>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, in source and binary forms, with or
without modification, are permitted, provided that the following
conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
CONTRIBUTORS ``AS IS''  AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

// $Id: bd_rigid_updater_test.cc 2594 2010-01-08 21:53:43Z joaander $
// $URL: http://codeblue.umich.edu/hoomd-blue/svn/branches/rigid-bodies/test/unit/bd_rigid_updater_test.cc $

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include <iostream>

//! name the boost unit test module
#define BOOST_TEST_MODULE BDRigidUpdaterTests
#include "boost_utf_configure.h"

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>

#include "TwoStepBDNVT.h"
#include "TwoStepBDNVTRigid.h"
#ifdef ENABLE_CUDA
#include "TwoStepBDNVTRigidGPU.h"
#include "TwoStepBDNVTGPU.h"
#endif

#include "IntegratorTwoStep.h"

#include "BoxResizeUpdater.h"

#include "AllPairPotentials.h"
#include "BinnedNeighborList.h"
#include "Initializers.h"

#ifdef ENABLE_CUDA
#include "BinnedNeighborListGPU.h"
#endif

#include "FENEBondForceCompute.h"

#ifdef ENABLE_CUDA
#include "FENEBondForceComputeGPU.h"
#endif

#include "saruprng.h"
#include <math.h>
#include <time.h>
#include <fstream>
#include <vector>

using namespace std;
using namespace boost;

/*! \file nve_rigid_updater_test.cc
    \brief Implements unit tests for NVERigidUpdater
    \ingroup unit_tests
*/

//! Tolerance for floating point comparisons
#ifdef SINGLE_PRECISION
const Scalar tolerance = Scalar(1e-2);
#else
const Scalar tolerance = Scalar(1e-3);
#endif

struct AtomInfo
{
    int type, localidx, body;
    double mass;
    double x, y, z;
};

struct BondInfo
{
    char type[50];
    int localidxi, localidxj;
    double kappa, R0, sigma, epsilon;
};

struct BuildingBlock
{
    std::vector<AtomInfo> atoms;
    std::vector<BondInfo> bonds;
    double spacing_x, spacing_y, spacing_z;
};

//! Typedef'd TwoStepBDNVTRigid class factory
typedef boost::function<shared_ptr<TwoStepBDNVTRigid> (shared_ptr<SystemDefinition> sysdef,
                            shared_ptr<ParticleGroup> group, Scalar T, unsigned int seed)> bdnvtup_creator;

void bd_updater_lj_tests(bdnvtup_creator bdup_creator, boost::shared_ptr<ExecutionConfiguration> exec_conf)
    {
    unsigned int nbodies = 800;
    unsigned int nparticlesperbuildingblock = 5;
    unsigned int nbondsperbuildingblock;
    unsigned int body_size = 5;
    unsigned int natomtypes = 2;
    unsigned int nbondtypes = 1;

    unsigned int N = nbodies * nparticlesperbuildingblock;
    Scalar box_length = 24.0814;
    shared_ptr<SystemDefinition> sysdef(new SystemDefinition(N, BoxDim(box_length), natomtypes, nbondtypes, 0, 0, 0, exec_conf));
    shared_ptr<ParticleData> pdata = sysdef->getParticleData();

    shared_ptr<ParticleSelector> selector_all(new ParticleSelectorTag(sysdef, 0, pdata->getN()-1));
    shared_ptr<ParticleGroup> group_all(new ParticleGroup(sysdef, selector_all));

    BoxDim box = pdata->getBox();

    // setup a simple initial state
    unsigned int ibody = 0;
    unsigned int iparticle = 0;
    Scalar x0 = box.xlo + 0.01;
    Scalar y0 = box.ylo + 0.01;
    Scalar z0 = box.zlo + 0.01;
    Scalar xspacing = 7.0f;
    Scalar yspacing = 1.0f;
    Scalar zspacing = 2.0f;

    BuildingBlock buildingBlock;
    buildingBlock.spacing_x = 6.0;
    buildingBlock.spacing_y = 6.0;
    buildingBlock.spacing_z = 2.0;

    AtomInfo atomi;
    int num_atoms = 5;
    for (int atom_n = 0; atom_n < num_atoms; atom_n++)
        {
        //Add Atom
        atomi.localidx = atom_n;
        atomi.x = Scalar(atom_n);
        atomi.y = 0.0;
        atomi.z = 0.0;
        atomi.body = 1;
        atomi.type = 1;
        atomi.mass = 1.0;
        buildingBlock.atoms.push_back(atomi);
        }

    nparticlesperbuildingblock = buildingBlock.atoms.size();
    nbondsperbuildingblock = buildingBlock.bonds.size();

    unsigned int seed = 258719;
    boost::shared_ptr<Saru> random = boost::shared_ptr<Saru>(new Saru(seed));
    Scalar temperature = 1.4;
    Scalar KE = Scalar(0.0);
    Scalar PE = Scalar(0.0);
    Scalar AvgT = Scalar(0);

    ParticleDataArrays arrays = pdata->acquireReadWrite();

    // initialize bodies in a cubic lattice with some velocity profile
    for (unsigned int i = 0; i < nbodies; i++)
        {
        for (unsigned int j = 0; j < nparticlesperbuildingblock; j++)
            {
            arrays.x[iparticle] = x0 + buildingBlock.atoms[j].x;
            arrays.y[iparticle] = y0 + buildingBlock.atoms[j].y;
            arrays.z[iparticle] = z0 + buildingBlock.atoms[j].z;

            arrays.vx[iparticle] = random->d();
            arrays.vy[iparticle] = random->d();
            arrays.vz[iparticle] = random->d();

            KE += Scalar(0.5) * (arrays.vx[iparticle]*arrays.vx[iparticle] + arrays.vy[iparticle]*arrays.vy[iparticle] + arrays.vz[iparticle]*arrays.vz[iparticle]);

            arrays.type[iparticle] = buildingBlock.atoms[j].type;

            if (buildingBlock.atoms[j].body > 0)
                arrays.body[iparticle] = ibody;

            unsigned int head = i * nparticlesperbuildingblock;
            for (unsigned int j = 0; j < nbondsperbuildingblock; j++)
                {
                unsigned int particlei = head + buildingBlock.bonds[j].localidxi;
                unsigned int particlej = head + buildingBlock.bonds[j].localidxj;

                sysdef->getBondData()->addBond(Bond(0, particlei, particlej));
                }

            iparticle++;
            }

        x0 += xspacing;
        if (x0 + xspacing >= box.xhi)
            {
            x0 = box.xlo + 0.01;

            y0 += yspacing;
            if (y0 + yspacing >= box.yhi)
                {
                y0 = box.ylo + 0.01;

                z0 += zspacing;
                if (z0 + zspacing >= box.zhi)
                    z0 = box.zlo + 0.01;
                }
            }

        ibody++;
        }

    assert(iparticle == N);

    pdata->release();

    Scalar deltaT = Scalar(0.005);
    shared_ptr<TwoStepBDNVTRigid> two_step_bdnvt = bdup_creator(sysdef, group_all, temperature, 453034);

    shared_ptr<IntegratorTwoStep> bdnvt_up(new IntegratorTwoStep(sysdef, deltaT));
    bdnvt_up->addIntegrationMethod(two_step_bdnvt);

    shared_ptr<NeighborList> nlist(new NeighborList(sysdef, Scalar(2.5), Scalar(0.8)));
    shared_ptr<PotentialPairLJ> fc(new PotentialPairLJ(sysdef, nlist));
    fc->setRcut(0, 0, Scalar(1.122));
    fc->setRcut(0, 1, Scalar(1.122));
    fc->setRcut(1, 1, Scalar(1.122));

    // setup some values for alpha and sigma
    Scalar epsilon = Scalar(1.0);
    Scalar sigma = Scalar(1.0);
    Scalar alpha = Scalar(1.0);
    Scalar lj1 = Scalar(4.0) * epsilon * pow(sigma, Scalar(12.0));
    Scalar lj2 = alpha * Scalar(4.0) * epsilon * pow(sigma, Scalar(6.0));

    // specify the force parameters
    fc->setParams(0,0,make_scalar2(lj1,lj2));
    fc->setParams(0,1,make_scalar2(lj1,lj2));
    fc->setParams(1,1,make_scalar2(lj1,lj2));

    bdnvt_up->addForceCompute(fc);

    unsigned int nrigid_dof, nnonrigid_dof;
    Scalar current_temp;

    shared_ptr<RigidData> rdata = sysdef->getRigidData();

    unsigned int start_step = 0;
    unsigned int steps = 5000;
    unsigned int sampling = 100;
    unsigned int averaging_delay = 1000;

    // Initialize rigid bodies
    rdata->initializeData();

    nrigid_dof = rdata->getNumDOF();
    nnonrigid_dof = 3 * (N - body_size * nbodies);

    // Rescale particle velocities to desired temperature:
    current_temp = 2.0 * KE / (nrigid_dof + nnonrigid_dof);
    Scalar factor = sqrt(temperature / current_temp);

    arrays = pdata->acquireReadWrite();
    for (unsigned int j = 0; j < N; j++)
        {
        arrays.vx[j] *= factor;
        arrays.vy[j] *= factor;
        arrays.vz[j] *= factor;
        }

    pdata->release();

    // Production: turn on LJ interactions between rods
    fc->setRcut(1, 1, Scalar(2.5));

    for (unsigned int i = start_step; i <= start_step + steps; i++)
        {

        bdnvt_up->update(i);

        if (i % sampling == 0)
            {

            arrays = pdata->acquireReadWrite();
            KE = Scalar(0.0);
            for (unsigned int j = 0; j < N; j++)
                KE += Scalar(0.5) * (arrays.vx[j]*arrays.vx[j] + arrays.vy[j]*arrays.vy[j] + arrays.vz[j]*arrays.vz[j]);
            PE = fc->calcEnergySum();

            current_temp = 2.0 * KE / (nrigid_dof + nnonrigid_dof);
            if (i > averaging_delay)
                AvgT += current_temp;

            pdata->release();

            }
        }

    AvgT /= Scalar((steps-averaging_delay)/sampling);
    //Test to see if the temperature has equilibrated to where its been set.
    MY_BOOST_CHECK_CLOSE(AvgT, 1.4, 2.5);
    }

#ifdef ENABLE_CUDA
//! TwoStepBDNVTRigidGPU factory for the unit tests
shared_ptr<TwoStepBDNVTRigid> gpu_bdnvt_creator(shared_ptr<SystemDefinition> sysdef, shared_ptr<ParticleGroup> group, Scalar T, unsigned int seed)
    {
    shared_ptr<VariantConst> T_variant(new VariantConst(T));
    return shared_ptr<TwoStepBDNVTRigid>(new TwoStepBDNVTRigidGPU(sysdef, group, T_variant, seed, false));
    }
#endif

#ifdef ENABLE_CUDA

//! Test of Rigid Rods
BOOST_AUTO_TEST_CASE( BDRigidGPU_rod_tests )
    {
    bdnvtup_creator bdnvt_creator_gpu = bind(gpu_bdnvt_creator, _1, _2, _3, _4);
    bd_updater_lj_tests(bdnvt_creator_gpu, boost::shared_ptr<ExecutionConfiguration>(new ExecutionConfiguration(ExecutionConfiguration::GPU)));
    }
#endif

#ifdef WIN32
#pragma warning( pop )
#endif

<|endoftext|>


<commit_before>#ifndef RBX_UTIL_CONFIGURATION_HPP
#define RBX_UTIL_CONFIGURATION_HPP

#include <list>
#include "string.h"
#include "inttypes.h"

namespace config {
  class ConfigItem;

  typedef std::list<ConfigItem*> Items;

  class Configuration {
    Items items_;

  public:
    void add_item(ConfigItem* item) {
      items_.push_back(item);
    }

    void import(const char* key, const char* val);
    void print();
  };

  class ConfigItem {
  public:
    const char* name_;
    bool set_;

    ConfigItem(Configuration* config, const char* name)
      : name_(name)
    {
      config->add_item(this);
    }

    virtual ~ConfigItem() {}

    virtual void set(const char* str) = 0;
    virtual void print_value() = 0;

    bool set_maybe(const char* key, const char* val) {
      if(strcmp(name_, key) != 0) return false;

      set_ = true;
      set(val);
      return true;
    }

    const char* name() {
      return name_;
    }

    bool set_p() {
      return set_;
    }
  };

  class Integer : public ConfigItem {
  public:
    long value;

    Integer(Configuration* config, const char* name, int def = 0)
      : ConfigItem(config, name)
      , value(def)
    {}

    virtual void set(const char* str) {
      value = strtol(str, NULL, 0);
    }

    virtual void print_value() {
      std::cout << value;
    }

    operator long() {
      return value;
    }
  };

  class String : public ConfigItem {
  public:
    std::string value;

    String(Configuration* config, const char* name)
      : ConfigItem(config, name)
      , value("")
    {}

    virtual void set(const char* str) {
      value = std::string(str);
    }

    virtual void print_value() {
      std::cout << value;
    }

    operator const char*() {
      return value.c_str();
    }
  };

  class Bool : public ConfigItem {
  public:
    bool value;

    Bool(Configuration* config, const char* name)
      : ConfigItem(config, name)
      , value(false)
    {}

    static bool convert(const char* str) {
      if(*str == '0'           ||
         !strcmp(str, "no")    ||
         !strcmp(str, "NO")    ||
         !strcmp(str, "false") ||
         !strcmp(str, "FALSE")) return false;

      return true;
    }

    virtual void set(const char* str) {
      value = convert(str);
    }

    virtual void print_value() {
      std::cout << (value ? "true" : "false");
    }

    operator bool() {
      return value;
    }
  };

  inline void Configuration::import(const char* key, const char* val) {
    for(Items::iterator i = items_.begin();
        i != items_.end();
        i++) {
      ConfigItem* item = *i;
      if(item->set_maybe(key, val)) return;
    }
  }

  inline void Configuration::print() {
    for(Items::iterator i = items_.begin();
        i != items_.end();
        i++) {
      ConfigItem* item = *i;
      std::cout << item->name() << ": ";
      item->print_value();
      std::cout << "\n";
    }
  }
}

#endif
<commit_msg>More include fixes for linux<commit_after>#ifndef RBX_UTIL_CONFIGURATION_HPP
#define RBX_UTIL_CONFIGURATION_HPP

#include <list>
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>

namespace config {
  class ConfigItem;

  typedef std::list<ConfigItem*> Items;

  class Configuration {
    Items items_;

  public:
    void add_item(ConfigItem* item) {
      items_.push_back(item);
    }

    void import(const char* key, const char* val);
    void print();
  };

  class ConfigItem {
  public:
    const char* name_;
    bool set_;

    ConfigItem(Configuration* config, const char* name)
      : name_(name)
    {
      config->add_item(this);
    }

    virtual ~ConfigItem() {}

    virtual void set(const char* str) = 0;
    virtual void print_value() = 0;

    bool set_maybe(const char* key, const char* val) {
      if(strcmp(name_, key) != 0) return false;

      set_ = true;
      set(val);
      return true;
    }

    const char* name() {
      return name_;
    }

    bool set_p() {
      return set_;
    }
  };

  class Integer : public ConfigItem {
  public:
    long value;

    Integer(Configuration* config, const char* name, int def = 0)
      : ConfigItem(config, name)
      , value(def)
    {}

    virtual void set(const char* str) {
      value = strtol(str, NULL, 0);
    }

    virtual void print_value() {
      std::cout << value;
    }

    operator long() {
      return value;
    }
  };

  class String : public ConfigItem {
  public:
    std::string value;

    String(Configuration* config, const char* name)
      : ConfigItem(config, name)
      , value("")
    {}

    virtual void set(const char* str) {
      value = std::string(str);
    }

    virtual void print_value() {
      std::cout << value;
    }

    operator const char*() {
      return value.c_str();
    }
  };

  class Bool : public ConfigItem {
  public:
    bool value;

    Bool(Configuration* config, const char* name)
      : ConfigItem(config, name)
      , value(false)
    {}

    static bool convert(const char* str) {
      if(*str == '0'           ||
         !strcmp(str, "no")    ||
         !strcmp(str, "NO")    ||
         !strcmp(str, "false") ||
         !strcmp(str, "FALSE")) return false;

      return true;
    }

    virtual void set(const char* str) {
      value = convert(str);
    }

    virtual void print_value() {
      std::cout << (value ? "true" : "false");
    }

    operator bool() {
      return value;
    }
  };

  inline void Configuration::import(const char* key, const char* val) {
    for(Items::iterator i = items_.begin();
        i != items_.end();
        i++) {
      ConfigItem* item = *i;
      if(item->set_maybe(key, val)) return;
    }
  }

  inline void Configuration::print() {
    for(Items::iterator i = items_.begin();
        i != items_.end();
        i++) {
      ConfigItem* item = *i;
      std::cout << item->name() << ": ";
      item->print_value();
      std::cout << "\n";
    }
  }
}

#endif
<|endoftext|>


<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.    Released under a BSD (revised)
license as described in the file LICENSE.
*/
#include <string>
#include "gd.h"
#include "vw.h"

using namespace std;
using namespace LEARNER;

struct update_data {
    struct OjaNewton *ON;
    float g;
    float sketch_cnt;
    float norm2_x;
    float *Zx;
    float *AZx;
    float *delta;
    float bdelta;
    float prediction;
};

struct OjaNewton {
    vw* all;
    int m;
    int epoch_size;
    float alpha;
    int cnt;
    int t;

    float *ev;
    float *b;
    double *D;
    double **A;
    double **K;

    example **buffer;
    float *weight_buffer;
    struct update_data data;

    float learning_rate_cnt;

    void initialize_Z()
    {
        size_t stride_shift = all->reg.stride_shift;
        weight* weights = all->reg.weight_vector;

        for (int i = 1; i <= m; i++)
            weights[(i << stride_shift) + i] = 1;
    }

    void compute_AZx()
    {
        for (int i = 1; i <= m; i++) {
            data.AZx[i] = 0;
            for (int j = 1; j <= i; j++) {
                data.AZx[i] += A[i][j] * data.Zx[j];
            }
        }
    }

    void update_eigenvalues()
    {
        for (int i = 1; i <= m; i++) {
            double gamma = fmin(learning_rate_cnt * i / t, .1);
            double tmp = data.AZx[i] * data.sketch_cnt;

            if (t == 1) {
                ev[i] = gamma * tmp * tmp;
            }
            else {
                ev[i] = (1 - gamma) * t * ev[i] / (t - 1) + gamma * t * tmp * tmp;
            }
        }
    }

    void compute_delta()
    {
        data.bdelta = 0;
        for (int i = 1; i <= m; i++) {
            double gamma = fmin(learning_rate_cnt * i / t, .1);

            data.delta[i] = gamma * data.AZx[i] * data.sketch_cnt;
            for (int j = 1; j < i; j++) {
                data.delta[i] -= A[i][j] * data.delta[j];
            }
            data.delta[i] /= A[i][i];
            printf("delta[%d] = %f\n", i, data.delta[i]);
            data.bdelta += data.delta[i] * b[i];
        }
    }

    void update_K()
    {
        float tmp = data.norm2_x * data.sketch_cnt * data.sketch_cnt;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= m; j++) {
                K[i][j] += data.delta[i] * data.Zx[j] * data.sketch_cnt;
                K[i][j] += data.delta[j] * data.Zx[i] * data.sketch_cnt;
                K[i][j] += data.delta[i] * data.delta[j] * tmp;
                printf("K[%d][%d] = %f\n", i, j, K[i][j]);
            }
        }
    }

    void update_A()
    {
        float *zv = calloc_or_die<float>(m+1);
        float *vv = calloc_or_die<float>(m+1);

        for (int i = 1; i <= m; i++) {

            for (int j = 1; j < i; j++) {
                zv[j] = 0;
                for (int k = 1; k <= i; k++) {
                    zv[j] += A[i][k] * K[k][j];
                }
            }

            for (int j = 1; j < i; j++) {
                vv[j] = 0;
                for (int k = 1; k <= j; k++) {
                    vv[j] += A[j][k] * zv[k];
                }
            }

            for (int j = 1; j < i; j++) {
                for (int k = j; k < i; k++) {
                    A[i][j] -= vv[k] * A[k][j];
                }
            }

            double norm = 0;
            for (int j = 1; j <= i; j++) {
	        double temp = 0;
                for (int k = 1; k <= i; k++) {
                    temp += K[j][k] * A[i][k];
                    //cout << "K = " << K[j][k] << endl;
                    //cout << "A = " << A[i][k] << endl;
                }
                norm += A[i][j]*temp;
            }
            //cout << norm << endl;
            norm = sqrt(norm);

            for (int j = 1; j <= i; j++) {
                A[i][j] /= norm;
                printf("A[%d][%d] = %f\n", i, j, A[i][j]);
            }
        }

        free(zv);
        free(vv);
    }

    void update_b()
    {
        for (int j = 1; j <= m; j++) {
            float tmp = 0;
            for (int i = j; i <= m; i++) {
                tmp += ev[i] * data.AZx[i] * A[i][j] / (alpha * (alpha + ev[i]));
            }
            b[j] += tmp * data.g;
        }
    }

    void update_D()
    {
        for (int j = 1; j <= m; j++) {
            float scale = fabs(A[j][j]);
            for (int i = j+1; i <= m; i++)
                scale = fmin(fabs(A[i][j]), scale);
            cout << "scale = " << scale << endl;
            if (scale < 1e-10) continue;
            for (int i = 1; i <= m; i++) {
                A[i][j] /= scale;
                K[j][i] *= scale;
                K[i][j] *= scale;
            }
            b[j] /= scale;
            D[j] *= scale;
            printf("D[%d] = %f\n", j, D[j]);
        }
    }
};

void keep_example(vw& all, OjaNewton& ON, example& ec) {
    output_and_account_example(all, ec);
}

void make_pred(update_data& data, float x, float& wref) {
    int m = data.ON->m;
    float* w = &wref;

    data.prediction += w[0] * x;
    for (int i = 1; i <= m; i++) {
        data.prediction += w[i] * x * data.ON->D[i] * data.ON->b[i];
    }
}

void predict(OjaNewton& ON, base_learner&, example& ec) {
    ON.data.prediction = 0;
    GD::foreach_feature<update_data, make_pred>(*ON.all, ec, ON.data);
    ec.partial_prediction = ON.data.prediction;
    ec.pred.scalar = GD::finalize_prediction(ON.all->sd, ec.partial_prediction);
}

void update_Z_and_wbar(update_data& data, float x, float& wref) {
    float* w = &wref;
    float s = data.sketch_cnt * x;
    int m = data.ON->m;

    for (int i = 1; i <= m; i++) {
        w[i] += data.delta[i] * s / data.ON->D[i];
    }
    w[0] -= s * data.bdelta;
}

void compute_Zx_and_norm(update_data& data, float x, float& wref) {
    float* w = &wref;

    for (int i = 1; i <= data.ON->m; i++) {
        data.Zx[i] += w[i] * x * data.ON->D[i];
    }
    data.norm2_x += x * x;
}

void update_wbar_and_Zx(update_data& data, float x, float& wref) {
    float* w = &wref;
    float g = data.g * x;

    for (int i = 1; i <= data.ON->m; i++) {
        data.Zx[i] += w[i] * x * data.ON->D[i];
    }
    w[0] -= g / data.ON->alpha;
}

void learn(OjaNewton& ON, base_learner& base, example& ec) {
    assert(ec.in_use);

    // predict
    predict(ON, base, ec);

    update_data& data = ON.data;
    data.g = ON.all->loss->first_derivative(ON.all->sd, ec.pred.scalar, ec.l.simple.label)*ec.l.simple.weight;
    data.g /= 2; // for half square loss...

    ON.buffer[ON.cnt] = &ec;
    ON.weight_buffer[ON.cnt++] = data.g / 2;

    if (ON.cnt == ON.epoch_size) {
        for (int k = 0; k < ON.epoch_size; k++, ON.t++) {
            example& ex = *(ON.buffer[k]);
            data.sketch_cnt = ON.weight_buffer[k];

            data.norm2_x = 0;
            memset(data.Zx, 0, sizeof(float)* (ON.m+1));
            GD::foreach_feature<update_data, compute_Zx_and_norm>(*ON.all, ex, data);
            ON.compute_AZx();

            ON.update_eigenvalues();
            ON.compute_delta();

            ON.update_K();

            GD::foreach_feature<update_data, update_Z_and_wbar>(*ON.all, ex, data);
        }

        ON.update_A();
        if (ON.t % (ON.epoch_size * 100) == 0) ON.update_D();
    }

    memset(data.Zx, 0, sizeof(float)* (ON.m+1));
    GD::foreach_feature<update_data, update_wbar_and_Zx>(*ON.all, ec, data);
    ON.compute_AZx();

    ON.update_b();

    if (ON.cnt == ON.epoch_size) {
        ON.cnt = 0;
        for (int k = 0; k < ON.epoch_size; k++) {
            VW::finish_example(*ON.all, ON.buffer[k]);
        }
    }
}

void save_load(OjaNewton& ON, io_buf& model_file, bool read, bool text) {
    vw* all = ON.all;
    if (read) {
        initialize_regressor(*all);
        ON.initialize_Z();
    }

    if (model_file.files.size() > 0) {
        bool resume = all->save_resume;
        char buff[512];
        uint32_t text_len = sprintf(buff, ":%d\n", resume);
        bin_text_read_write_fixed(model_file, (char *)&resume, sizeof (resume), "", read, buff, text_len, text);

        if (resume)
            GD::save_load_online_state(*all, model_file, read, text);
        else
            GD::save_load_regressor(*all, model_file, read, text);
    }
}

base_learner* OjaNewton_setup(vw& all) {
    if (missing_option(all, false, "OjaNewton", "Online Newton with Oja's Sketch"))
        return nullptr;

    new_options(all, "OjaNewton options")
        ("sketch_size", po::value<int>(), "size of sketch")
        ("epoch_size", po::value<int>(), "size of epoch")
        ("alpha", po::value<float>(), "mutiplicative constant for indentiy")
        ("learning_rate_cnt", po::value<float>(), "constant for the learning rate 1/t");
    add_options(all);

    po::variables_map& vm = all.vm;

    OjaNewton& ON = calloc_or_die<OjaNewton>();
    ON.all = &all;

    if (vm.count("sketch_size"))
        ON.m = vm["sketch_size"].as<int>();
    else
        ON.m = 10;

    if (vm.count("epoch_size"))
        ON.epoch_size = vm["epoch_size"].as<int>();
    else
        ON.epoch_size = 1;

    if (vm.count("alpha"))
        ON.alpha = vm["alpha"].as<float>();
    else
        ON.alpha = 1.0;

    if (vm.count("learning_rate_cnt"))
        ON.learning_rate_cnt = vm["learning_rate_cnt"].as<float>();
    else
        ON.learning_rate_cnt = 10;

    ON.cnt = 0;
    ON.t = 1;

    ON.ev = calloc_or_die<float>(ON.m+1);
    ON.b = calloc_or_die<float>(ON.m+1);
    ON.D = calloc_or_die<double>(ON.m+1);
    ON.A = calloc_or_die<double*>(ON.m+1);
    ON.K = calloc_or_die<double*>(ON.m+1);
    for (int i = 1; i <= ON.m; i++) {
        ON.A[i] = calloc_or_die<double>(ON.m+1);
        ON.K[i] = calloc_or_die<double>(ON.m+1);
        ON.A[i][i] = 1;
        ON.K[i][i] = 1;
        ON.D[i] = 1;
    }

    ON.buffer = calloc_or_die<example*>(ON.epoch_size);
    ON.weight_buffer = calloc_or_die<float>(ON.epoch_size);

    ON.data.ON = &ON;
    ON.data.Zx = calloc_or_die<float>(ON.m+1);
    ON.data.AZx = calloc_or_die<float>(ON.m+1);
    ON.data.delta = calloc_or_die<float>(ON.m+1);

    all.reg.stride_shift = ceil(log2(ON.m + 1));

    learner<OjaNewton>& l = init_learner(&ON, learn, 1 << all.reg.stride_shift);

    l.set_predict(predict);
    l.set_save_load(save_load);
    l.set_finish_example(keep_example);
    return make_base(l);
}
<commit_msg>float -> double<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.    Released under a BSD (revised)
license as described in the file LICENSE.
*/
#include <string>
#include "gd.h"
#include "vw.h"

using namespace std;
using namespace LEARNER;

struct update_data {
    struct OjaNewton *ON;
    double g;
    double sketch_cnt;
    double norm2_x;
    double *Zx;
    double *AZx;
    double *delta;
    double bdelta;
    double prediction;
};

struct OjaNewton {
    vw* all;
    int m;
    int epoch_size;
    double alpha;
    int cnt;
    int t;

    double *ev;
    double *b;
    double *D;
    double **A;
    double **K;

    example **buffer;
    double *weight_buffer;
    struct update_data data;

    double learning_rate_cnt;

    void initialize_Z()
    {
        size_t stride_shift = all->reg.stride_shift;
        weight* weights = all->reg.weight_vector;

        for (int i = 1; i <= m; i++)
            weights[(i << stride_shift) + i] = 1;
    }

    void compute_AZx()
    {
        for (int i = 1; i <= m; i++) {
            data.AZx[i] = 0;
            for (int j = 1; j <= i; j++) {
                data.AZx[i] += A[i][j] * data.Zx[j];
            }
        }
    }

    void update_eigenvalues()
    {
        for (int i = 1; i <= m; i++) {
            double gamma = fmin(learning_rate_cnt * i / t, .1);
            double tmp = data.AZx[i] * data.sketch_cnt;

            if (t == 1) {
                ev[i] = gamma * tmp * tmp;
            }
            else {
                ev[i] = (1 - gamma) * t * ev[i] / (t - 1) + gamma * t * tmp * tmp;
            }
        }
    }

    void compute_delta()
    {
        data.bdelta = 0;
        for (int i = 1; i <= m; i++) {
            double gamma = fmin(learning_rate_cnt * i / t, .1);

            data.delta[i] = gamma * data.AZx[i] * data.sketch_cnt;
            for (int j = 1; j < i; j++) {
                data.delta[i] -= A[i][j] * data.delta[j];
            }
            data.delta[i] /= A[i][i];
            printf("delta[%d] = %f\n", i, data.delta[i]);
            data.bdelta += data.delta[i] * b[i];
        }
    }

    void update_K()
    {
        double tmp = data.norm2_x * data.sketch_cnt * data.sketch_cnt;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= m; j++) {
                K[i][j] += data.delta[i] * data.Zx[j] * data.sketch_cnt;
                K[i][j] += data.delta[j] * data.Zx[i] * data.sketch_cnt;
                K[i][j] += data.delta[i] * data.delta[j] * tmp;
                printf("K[%d][%d] = %f\n", i, j, K[i][j]);
            }
        }
    }

    void update_A()
    {
        double *zv = calloc_or_die<double>(m+1);
        double *vv = calloc_or_die<double>(m+1);

        for (int i = 1; i <= m; i++) {

            for (int j = 1; j < i; j++) {
                zv[j] = 0;
                for (int k = 1; k <= i; k++) {
                    zv[j] += A[i][k] * K[k][j];
                }
            }

            for (int j = 1; j < i; j++) {
                vv[j] = 0;
                for (int k = 1; k <= j; k++) {
                    vv[j] += A[j][k] * zv[k];
                }
            }

            for (int j = 1; j < i; j++) {
                for (int k = j; k < i; k++) {
                    A[i][j] -= vv[k] * A[k][j];
                }
            }

            double norm = 0;
            for (int j = 1; j <= i; j++) {
	        double temp = 0;
                for (int k = 1; k <= i; k++) {
                    temp += K[j][k] * A[i][k];
                    //cout << "K = " << K[j][k] << endl;
                    //cout << "A = " << A[i][k] << endl;
                }
                norm += A[i][j]*temp;
            }
            //cout << norm << endl;
            norm = sqrt(norm);

            for (int j = 1; j <= i; j++) {
                A[i][j] /= norm;
                printf("A[%d][%d] = %f\n", i, j, A[i][j]);
            }
        }

        free(zv);
        free(vv);
    }

    void update_b()
    {
        for (int j = 1; j <= m; j++) {
            double tmp = 0;
            for (int i = j; i <= m; i++) {
                tmp += ev[i] * data.AZx[i] * A[i][j] / (alpha * (alpha + ev[i]));
            }
            b[j] += tmp * data.g;
        }
    }

    void update_D()
    {
        for (int j = 1; j <= m; j++) {
            double scale = fabs(A[j][j]);
            for (int i = j+1; i <= m; i++)
                scale = fmin(fabs(A[i][j]), scale);
            cout << "scale = " << scale << endl;
            if (scale < 1e-10) continue;
            for (int i = 1; i <= m; i++) {
                A[i][j] /= scale;
                K[j][i] *= scale;
                K[i][j] *= scale;
            }
            b[j] /= scale;
            D[j] *= scale;
            printf("D[%d] = %f\n", j, D[j]);
        }
    }
};

void keep_example(vw& all, OjaNewton& ON, example& ec) {
    output_and_account_example(all, ec);
}

void make_pred(update_data& data, float x, float& wref) {
    int m = data.ON->m;
    float* w = &wref;

    data.prediction += w[0] * x;
    for (int i = 1; i <= m; i++) {
        data.prediction += w[i] * x * data.ON->D[i] * data.ON->b[i];
    }
}

void predict(OjaNewton& ON, base_learner&, example& ec) {
    ON.data.prediction = 0;
    GD::foreach_feature<update_data, make_pred>(*ON.all, ec, ON.data);
    ec.partial_prediction = ON.data.prediction;
    ec.pred.scalar = GD::finalize_prediction(ON.all->sd, ec.partial_prediction);
}

void update_Z_and_wbar(update_data& data, float x, float& wref) {
    float* w = &wref;
    double s = data.sketch_cnt * x;
    int m = data.ON->m;

    for (int i = 1; i <= m; i++) {
        w[i] += data.delta[i] * s / data.ON->D[i];
    }
    w[0] -= s * data.bdelta;
}

void compute_Zx_and_norm(update_data& data, float x, float& wref) {
    float* w = &wref;

    for (int i = 1; i <= data.ON->m; i++) {
        data.Zx[i] += w[i] * x * data.ON->D[i];
    }
    data.norm2_x += x * x;
}

void update_wbar_and_Zx(update_data& data, float x, float& wref) {
    float* w = &wref;
    double g = data.g * x;

    for (int i = 1; i <= data.ON->m; i++) {
        data.Zx[i] += w[i] * x * data.ON->D[i];
    }
    w[0] -= g / data.ON->alpha;
}

void learn(OjaNewton& ON, base_learner& base, example& ec) {
    assert(ec.in_use);

    // predict
    predict(ON, base, ec);

    update_data& data = ON.data;
    data.g = ON.all->loss->first_derivative(ON.all->sd, ec.pred.scalar, ec.l.simple.label)*ec.l.simple.weight;
    data.g /= 2; // for half square loss...

    ON.buffer[ON.cnt] = &ec;
    ON.weight_buffer[ON.cnt++] = data.g / 2;

    if (ON.cnt == ON.epoch_size) {
        for (int k = 0; k < ON.epoch_size; k++, ON.t++) {
            example& ex = *(ON.buffer[k]);
            data.sketch_cnt = ON.weight_buffer[k];

            data.norm2_x = 0;
            memset(data.Zx, 0, sizeof(double)* (ON.m+1));
            GD::foreach_feature<update_data, compute_Zx_and_norm>(*ON.all, ex, data);
            ON.compute_AZx();

            ON.update_eigenvalues();
            ON.compute_delta();

            ON.update_K();

            GD::foreach_feature<update_data, update_Z_and_wbar>(*ON.all, ex, data);
        }

        ON.update_A();
        if (ON.t % (ON.epoch_size * 100) == 0) ON.update_D();
    }

    memset(data.Zx, 0, sizeof(double)* (ON.m+1));
    GD::foreach_feature<update_data, update_wbar_and_Zx>(*ON.all, ec, data);
    ON.compute_AZx();

    ON.update_b();

    if (ON.cnt == ON.epoch_size) {
        ON.cnt = 0;
        for (int k = 0; k < ON.epoch_size; k++) {
            VW::finish_example(*ON.all, ON.buffer[k]);
        }
    }
}

void save_load(OjaNewton& ON, io_buf& model_file, bool read, bool text) {
    vw* all = ON.all;
    if (read) {
        initialize_regressor(*all);
        ON.initialize_Z();
    }

    if (model_file.files.size() > 0) {
        bool resume = all->save_resume;
        char buff[512];
        uint32_t text_len = sprintf(buff, ":%d\n", resume);
        bin_text_read_write_fixed(model_file, (char *)&resume, sizeof (resume), "", read, buff, text_len, text);

        if (resume)
            GD::save_load_online_state(*all, model_file, read, text);
        else
            GD::save_load_regressor(*all, model_file, read, text);
    }
}

base_learner* OjaNewton_setup(vw& all) {
    if (missing_option(all, false, "OjaNewton", "Online Newton with Oja's Sketch"))
        return nullptr;

    new_options(all, "OjaNewton options")
        ("sketch_size", po::value<int>(), "size of sketch")
        ("epoch_size", po::value<int>(), "size of epoch")
        ("alpha", po::value<double>(), "mutiplicative constant for indentiy")
        ("learning_rate_cnt", po::value<double>(), "constant for the learning rate 1/t");
    add_options(all);

    po::variables_map& vm = all.vm;

    OjaNewton& ON = calloc_or_die<OjaNewton>();
    ON.all = &all;

    if (vm.count("sketch_size"))
        ON.m = vm["sketch_size"].as<int>();
    else
        ON.m = 10;

    if (vm.count("epoch_size"))
        ON.epoch_size = vm["epoch_size"].as<int>();
    else
        ON.epoch_size = 1;

    if (vm.count("alpha"))
        ON.alpha = vm["alpha"].as<double>();
    else
        ON.alpha = 1.0;

    if (vm.count("learning_rate_cnt"))
        ON.learning_rate_cnt = vm["learning_rate_cnt"].as<double>();
    else
        ON.learning_rate_cnt = 10;

    ON.cnt = 0;
    ON.t = 1;

    ON.ev = calloc_or_die<double>(ON.m+1);
    ON.b = calloc_or_die<double>(ON.m+1);
    ON.D = calloc_or_die<double>(ON.m+1);
    ON.A = calloc_or_die<double*>(ON.m+1);
    ON.K = calloc_or_die<double*>(ON.m+1);
    for (int i = 1; i <= ON.m; i++) {
        ON.A[i] = calloc_or_die<double>(ON.m+1);
        ON.K[i] = calloc_or_die<double>(ON.m+1);
        ON.A[i][i] = 1;
        ON.K[i][i] = 1;
        ON.D[i] = 1;
    }

    ON.buffer = calloc_or_die<example*>(ON.epoch_size);
    ON.weight_buffer = calloc_or_die<double>(ON.epoch_size);

    ON.data.ON = &ON;
    ON.data.Zx = calloc_or_die<double>(ON.m+1);
    ON.data.AZx = calloc_or_die<double>(ON.m+1);
    ON.data.delta = calloc_or_die<double>(ON.m+1);

    all.reg.stride_shift = ceil(log2(ON.m + 1));

    learner<OjaNewton>& l = init_learner(&ON, learn, 1 << all.reg.stride_shift);

    l.set_predict(predict);
    l.set_save_load(save_load);
    l.set_finish_example(keep_example);
    return make_base(l);
}
<|endoftext|>


<commit_before>#pragma once
#ifndef WTL_DEBUG_HPP_
#define WTL_DEBUG_HPP_

#include <cstdio>
#include <cstring>
#include <cerrno>
#include <iostream>
#include <string>

#define CERR(...) std::cerr << "\033[1;30m" << __VA_ARGS__ << "\033[0m"

#ifndef NDEBUG
#  define DCERR(...) CERR(__VA_ARGS__)
#  define DPRINTF(...) std::fprintf(stderr, __VA_ARGS__)
#else
#  define DCERR(...)
#  define DPRINTF(...)
#endif // NDEBUG

#define FILE_LINE_PRETTY __FILE__<<':'<<__LINE__<<':'<<__PRETTY_FUNCTION__
#define FLPF CERR(FILE_LINE_PRETTY << std::endl)
#define HERE DCERR(FILE_LINE_PRETTY << std::endl)

#define DQUOTE(s) # s
#define CONCATENATE(x, y) x ## y

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
namespace wtl {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////

inline const char* strerror(const std::string& msg="") {
    if (msg.empty()) {
        return std::strerror(errno);
    } else {
        static const std::string s(msg + ": " + std::strerror(errno));
        return s.c_str();
    }
}

// std::cerr << std::strerror(errno);
// overloaded to receive an additional message in std:string
inline void perror(const std::string& msg="") {
    std::perror(msg.empty() ? nullptr : std::string("\nERROR:\n"+msg).c_str());
}

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
} // namespace wtl
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////

#endif // WTL_DEBUG_HPP_
<commit_msg>:fire: Remove errno functions<commit_after>#pragma once
#ifndef WTL_DEBUG_HPP_
#define WTL_DEBUG_HPP_

#include <cstdio>
#include <iostream>

#define CERR(...) std::cerr << "\033[1;30m" << __VA_ARGS__ << "\033[0m"

#ifndef NDEBUG
#  define DCERR(...) CERR(__VA_ARGS__)
#  define DPRINTF(...) std::fprintf(stderr, __VA_ARGS__)
#else
#  define DCERR(...)
#  define DPRINTF(...)
#endif // NDEBUG

#define FILE_LINE_PRETTY __FILE__<<':'<<__LINE__<<':'<<__PRETTY_FUNCTION__
#define FLPF CERR(FILE_LINE_PRETTY << std::endl)
#define HERE DCERR(FILE_LINE_PRETTY << std::endl)

#endif // WTL_DEBUG_HPP_
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/* Here is the version string - update before a public release */
/* --- IMPORTANT!  THE FORMAT OF THE VERSION STRING IS VERY STRICT
   BECAUSE IT IS PARSED AT RUNTIME.  DO NOT ALTER THE FORMAT OR ENTER
   ANYTHING EXTRA BEFORE THE DATE.  IF YOU WISH TO ADD EXTRA INFORMATION,
   DO SO _AFTER_ THE DATE AND BEFORE THE TRAILING '$' CHARACTER.
   EXAMPLES:
       $CondorVersion: 6.1.11 " __DATE__ " WinNTPreview $    [OK]
	   $CondorVersion: 6.1.11 WinNTPreview " __DATE__ " $	 [WRONG!!!]
   Any questions?  See Todd or Derek.  Note: if you mess it up, DaemonCore
   will EXCEPT at startup time.
*/

static char* CondorVersionString = "$CondorVersion: 6.9.4 " __DATE__ " PRE-RELEASE-UWCS $";

/*
   This is some wisdom from Cygnus's web page.  If you just try to use
   the "stringify" operator on a preprocessor directive, you'd get
   "PLATFORM", not "Intel Linux" (or whatever the value of PLATFORM
   is).  That's because the stringify operator is a special case, and
   the preprocessor isn't allowed to expand things that are passed to
   it.  However, by defining two layers of macros, you get the right
   behavior, since the first pass converts:

   xstr(PLATFORM) -> str(Intel Linux)

   and the next pass gives:

   str(Intel Linux) -> "Intel Linux"

   This is exactly what we want, so we use it.  -Derek Wright and Jeff
   Ballard, 12/2/99

   Also, because the NT build system is totally different, we have to
   define the correct platform string right in here. :( -Derek 12/3/99
*/

#if defined(WIN32)
#define PLATFORM INTEL-WINNT50
#endif

#define xstr(s) str(s)
#define str(s) #s

/* Here is the platform string.  You don't need to edit this */
static char* CondorPlatformString = "$CondorPlatform: " xstr(PLATFORM) " $";

extern "C" {

const char*
CondorVersion( void )
{
	return CondorVersionString;
}

const char*
CondorPlatform( void )
{
	return CondorPlatformString;
}

} /* extern "C" */

<commit_msg>Now that the V6_9_4-branch exists, the trunk is for the 6.9.5 pre-release<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/* Here is the version string - update before a public release */
/* --- IMPORTANT!  THE FORMAT OF THE VERSION STRING IS VERY STRICT
   BECAUSE IT IS PARSED AT RUNTIME.  DO NOT ALTER THE FORMAT OR ENTER
   ANYTHING EXTRA BEFORE THE DATE.  IF YOU WISH TO ADD EXTRA INFORMATION,
   DO SO _AFTER_ THE DATE AND BEFORE THE TRAILING '$' CHARACTER.
   EXAMPLES:
       $CondorVersion: 6.1.11 " __DATE__ " WinNTPreview $    [OK]
	   $CondorVersion: 6.1.11 WinNTPreview " __DATE__ " $	 [WRONG!!!]
   Any questions?  See Todd or Derek.  Note: if you mess it up, DaemonCore
   will EXCEPT at startup time.
*/

static char* CondorVersionString = "$CondorVersion: 6.9.5 " __DATE__ " PRE-RELEASE-UWCS $";

/*
   This is some wisdom from Cygnus's web page.  If you just try to use
   the "stringify" operator on a preprocessor directive, you'd get
   "PLATFORM", not "Intel Linux" (or whatever the value of PLATFORM
   is).  That's because the stringify operator is a special case, and
   the preprocessor isn't allowed to expand things that are passed to
   it.  However, by defining two layers of macros, you get the right
   behavior, since the first pass converts:

   xstr(PLATFORM) -> str(Intel Linux)

   and the next pass gives:

   str(Intel Linux) -> "Intel Linux"

   This is exactly what we want, so we use it.  -Derek Wright and Jeff
   Ballard, 12/2/99

   Also, because the NT build system is totally different, we have to
   define the correct platform string right in here. :( -Derek 12/3/99
*/

#if defined(WIN32)
#define PLATFORM INTEL-WINNT50
#endif

#define xstr(s) str(s)
#define str(s) #s

/* Here is the platform string.  You don't need to edit this */
static char* CondorPlatformString = "$CondorPlatform: " xstr(PLATFORM) " $";

extern "C" {

const char*
CondorVersion( void )
{
	return CondorVersionString;
}

const char*
CondorPlatform( void )
{
	return CondorPlatformString;
}

} /* extern "C" */

<|endoftext|>


<commit_before>#include "read_private.h"

buffered_io::buffered_io(const logical_file_partition &partition_, long size,
		int node_id, int flags): io_interface(node_id), partition(
			partition_), fds(partition.get_num_files())
{
	this->flags = flags;
#ifdef STATISTICS
	read_time = 0;
	num_reads = 0;
#endif
	remote_reads = 0;
	this->size = size;

	for (int i = 0; i < partition.get_num_files(); i++)
		fds[i] = partition.get_fd(i);
}

int buffered_io::init() {
	return 0;
}

ssize_t buffered_io::access(char *buf, off_t offset, ssize_t size, int access_method) {
	int fd = get_fd(offset);
#ifdef STATISTICS
	if (access_method == READ)
		num_reads++;
	struct timeval start, end;
	gettimeofday(&start, NULL);
#endif
	ssize_t ret;
	if (access_method == WRITE)
		ret = pwrite(fd, buf, size, offset);
	else
		ret = pread(fd, buf, size, offset);
	if (ret < 0) {
		perror("pread");
		abort();
	}
#ifdef STATISTICS
	gettimeofday(&end, NULL);
	read_time += ((long) end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec;
#endif
	return ret;
}
<commit_msg>Fix a bug in buffered_io.<commit_after>#include "read_private.h"
#include "file_mapper.h"

buffered_io::buffered_io(const logical_file_partition &partition_, long size,
		int node_id, int flags): io_interface(node_id), partition(
			partition_), fds(partition.get_num_files())
{
	this->flags = flags;
#ifdef STATISTICS
	read_time = 0;
	num_reads = 0;
#endif
	remote_reads = 0;
	this->size = size;

	for (int i = 0; i < partition.get_num_files(); i++)
		fds[i] = partition.get_fd(i);
}

int buffered_io::init() {
	return 0;
}

ssize_t buffered_io::access(char *buf, off_t offset, ssize_t size, int access_method) {
	int fd;
	if (fds.size() == 1)
		fd = fds[0];
	else {
		struct block_identifier bid;
		partition.map(offset / PAGE_SIZE, bid);
		fd = fds[bid.idx];
		offset = bid.off * PAGE_SIZE;
	}
#ifdef STATISTICS
	if (access_method == READ)
		num_reads++;
	struct timeval start, end;
	gettimeofday(&start, NULL);
#endif
	ssize_t ret;
	if (access_method == WRITE)
		ret = pwrite(fd, buf, size, offset);
	else
		ret = pread(fd, buf, size, offset);
	if (ret < 0) {
		perror("pread");
		abort();
	}
#ifdef STATISTICS
	gettimeofday(&end, NULL);
	read_time += ((long) end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec;
#endif
	return ret;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <random>
#include <thread>

using std::cout;
using std::cin;
using std::random_device;
using std::mt19937_64;
using std::uniform_real_distribution;
using std::vector;
using std::thread;

#define SIZEF 500

typedef struct Info{
	int board[SIZEF][SIZEF];
	int x;
	int y;
} Info;

int size;

static const int iPasso[8] = { -2, -1,  1,  2,  2,  1, -1, -2 };
static const int jPasso[8] = {  1,  2,  2,  1, -1, -2, -2, -1 };

double Random(int n){
	//https://stackoverflow.com/questions/5008804/generating-random-integer-from-a-range
	random_device rd;
	mt19937_64 gen(rd());
	//http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
	uniform_real_distribution<> uni(0,n);
	return uni(gen);
}

void InitMatrix(Info &p, int x, int y){
	for (int i = 0; i < size; ++i){
		for (int j = 0; j < size; ++j){
			p.board[i][j] = 0;
		}
	}
	p.board[x][y] = 1;
}

void PrintBoard(int board[SIZEF][SIZEF]){
	for (int i = 0; i < size; ++i){
		for (int j = 0; j < size; ++j)
			cout << board[i][j] << "\t";
		cout << "\n\n";
	}
}

void populate(vector<Info> &p, int threads){
	int count = 0;

	while (count != threads){
		int flag = 1;
		Info tmp;
		tmp.x = Random(size-1);
		tmp.y = Random(size-1);

		for (unsigned int i = 0; i < p.size(); i++) {
			if (p[i].x == tmp.x && p[i].y == tmp.y) {
				flag = 0;
				break;
			}
		}

		if (flag) {
			InitMatrix(tmp, tmp.x, tmp.y);
			p.push_back(tmp);
			count ++;
		}
	}
}

bool Valid(Info p, int i){
  int x = (p.x) + iPasso[i];
  int y = (p.y) + jPasso[i];

  if( x >= 0 && x < size && y >= 0 && y < size && p.board[x][y] == 0 )
    return true;
  return false;
}

void SaveMove(Info &p, int i){
	// cout << "PRIMEIRO:"<<p.x << '\n';
  p.x+=iPasso[i];
	// cout << "segundo:"<<p.x << '\n';
  p.y+=jPasso[i];
}

int walk(Info &p){
	double random = Random(99.9);
	int pass = 0;

	while(1){
		// PrintBoard(p.board);
		random = fmod(random,100);
		if (0 <= random && random < 12.5) { // move 1
			if(Valid(p, 0)) {
				SaveMove(p, 0);
				return 0;
			}
			pass++;

		}else if (12.5 <= random && random < 25){ // move 2
			if(Valid(p, 1)) {
				SaveMove(p, 1);
				return 0;
			}
			pass++;

		}else if (25 <= random && random< 37.5){ // move 3
			if(Valid(p, 2)){
				SaveMove(p, 2);
					return 0;
			}
			pass++;

		}else if (37.5 <= random && random < 50){ // move 4
			if(Valid(p, 3)){
				SaveMove(p, 3);
				return 0;
			}
			pass++;

		}else if (50 <= random && random < 62.5){ // move 5
			if(Valid(p, 4)) {
				SaveMove(p, 4);
				return 0;
			}
			pass++;

		}else if (62.5 <= random && random < 75){ // move 6
			if(Valid(p, 5)) {
				SaveMove(p, 5);
				return 0;
			}
			pass++;

		}else if (75 <= random && random < 87.5){ // move 7
			if(Valid(p, 6)) {
				SaveMove(p, 6);
				return 0;
			}
			pass++;

		}else{
			if(Valid(p, 7)) {
				SaveMove(p, 7);
				return 0;
			}
			pass++;
		}

		random+=12.5;
		if (pass == 8)
			return 1;
	}
}

void Tour(Info p){
	int flag = 0, iter = 0,
			x0 = p.x, y0 = p.y;
	while (1) {
		InitMatrix(p, x0, y0);

		int count = 2;
		for (int k = 0; k < size*size; k++){
			int end = walk(p);

			if (end == 1) {
				flag = 0;

				for (int i = 0; i < size; i++) {
					for (int j = 0; j < size; j++) {
						if (p.board[i][j] == 0)
							flag++;
					}
				}

				if (flag == 0) {
					cout << "random is good! Iteration:"<< iter << '\n';
					PrintBoard(p.board);
				  return;
				}
				break;
			}

			p.board[p.x][p.y] = count;
			count++;
		}

		if(flag != 0){
			p.x=x0;
			p.y=y0;
		}
		iter++;
	}
}

int main(int argc, char const *argv[]){

	cin >> size;

	int nthreads;
	cin >> nthreads;

	vector<Info> p;
	populate(p,nthreads);

	for (unsigned int i = 0; i < p.size(); i++) {
	    cout << i << ": x=" << p[i].x << ", y=" << p[i].y << '\n';
			//   	PrintBoard(p[i].board);
	}

	thread t[nthreads];
  for (int i = 0; i < nthreads; i++)
      t[i] = thread(Tour, p[i]);
	cout << "Threads em execução" << '\n';
  for (int i = 0; i < nthreads; i++) {
		// cout << "Opa" << '\n';
    t[i].join();
  }
	return 0;
}
<commit_msg>modif<commit_after>#include <iostream>
#include <random>
#include <thread>
#include <chrono>

using std::cout;
using std::cin;
using std::random_device;
using std::mt19937_64;
using std::uniform_real_distribution;
using std::vector;
using std::thread;

#define SIZEF 500
#define MAX 1000

typedef struct Info{
	int board[SIZEF][SIZEF];
	int x;
	int y;
} Info;

int size;

static const int iPasso[8] = { -2, -1,  1,  2,  2,  1, -1, -2 };
static const int jPasso[8] = {  1,  2,  2,  1, -1, -2, -2, -1 };

double Random(int n){
	//https://stackoverflow.com/questions/5008804/generating-random-integer-from-a-range
	random_device rd;
	mt19937_64 gen(rd());
	//http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
	uniform_real_distribution<> uni(0,n);
	return uni(gen);
}

void InitMatrix(Info &p, int x, int y){
	for (int i = 0; i < size; ++i){
		for (int j = 0; j < size; ++j){
			p.board[i][j] = 0;
		}
	}
	p.board[x][y] = 1;
}

void PrintBoard(int board[SIZEF][SIZEF]){
	std::thread::id Tid = std::this_thread::get_id();
	cout << "\nId thread : " << Tid;
	cout << "\n";
	for (int i = 0; i < size; ++i){
		for (int j = 0; j < size; ++j)
			cout << board[i][j] << "\t";
		cout << "\n\n";
	}
}

void populate(vector<Info> &p, int threads){
	int count = 0;

	while (count != threads){
		int flag = 1;
		Info tmp;
		tmp.x = Random(size-1);
		tmp.y = Random(size-1);

		for (unsigned int i = 0; i < p.size(); i++) {
			if (p[i].x == tmp.x && p[i].y == tmp.y) {
				flag = 0;
				break;
			}
		}

		if (flag) {
			InitMatrix(tmp, tmp.x, tmp.y);
			p.push_back(tmp);
			count ++;
		}
	}
}

bool Valid(Info p, int i){
  int x = (p.x) + iPasso[i];
  int y = (p.y) + jPasso[i];

  if( x >= 0 && x < size && y >= 0 && y < size && p.board[x][y] == 0 )
    return true;
  return false;
}

void SaveMove(Info &p, int i){
	// cout << "PRIMEIRO:"<<p.x << '\n';
  p.x+=iPasso[i];
	// cout << "segundo:"<<p.x << '\n';
  p.y+=jPasso[i];
}

int walk(Info &p){
	double random = Random(99.9);
	int pass = 0;

	while(1){
		// PrintBoard(p.board);
		random = fmod(random,100);
		if (0 <= random && random < 12.5) { // move 1
			if(Valid(p, 0)) {
				SaveMove(p, 0);
				return 0;
			}
			pass++;

		}else if (12.5 <= random && random < 25){ // move 2
			if(Valid(p, 1)) {
				SaveMove(p, 1);
				return 0;
			}
			pass++;

		}else if (25 <= random && random< 37.5){ // move 3
			if(Valid(p, 2)){
				SaveMove(p, 2);
					return 0;
			}
			pass++;

		}else if (37.5 <= random && random < 50){ // move 4
			if(Valid(p, 3)){
				SaveMove(p, 3);
				return 0;
			}
			pass++;

		}else if (50 <= random && random < 62.5){ // move 5
			if(Valid(p, 4)) {
				SaveMove(p, 4);
				return 0;
			}
			pass++;

		}else if (62.5 <= random && random < 75){ // move 6
			if(Valid(p, 5)) {
				SaveMove(p, 5);
				return 0;
			}
			pass++;

		}else if (75 <= random && random < 87.5){ // move 7
			if(Valid(p, 6)) {
				SaveMove(p, 6);
				return 0;
			}
			pass++;

		}else{
			if(Valid(p, 7)) {
				SaveMove(p, 7);
				return 0;
			}
			pass++;
		}

		random+=12.5;
		if (pass == 8)
			return 1;
	}
}

int Tour(Info &p){
	int flag = 0, iter = 0,
			x0 = p.x, y0 = p.y;

	// while (1) {
	while(iter < MAX){
		InitMatrix(p, x0, y0);

		int count = 2;
		for (int k = 0; k < size*size; k++){
			int end = walk(p);

			if (end == 1) {
				flag = 0;

				for (int i = 0; i < size; i++) {
					for (int j = 0; j < size; j++) {
						if (p.board[i][j] == 0)
							flag++;
					}
				}

				if (flag == 0) {
					cout << "\nrandom is good! Iteration:"<< iter;

				  return 1;
				}
				break;
			}

			p.board[p.x][p.y] = count;
			count++;
		}

		if(flag != 0){
			p.x=x0;
			p.y=y0;
		}
		iter++;
	}
	return 0;
}

int KnightsTour(Info p){
	if (Tour(p)){
		PrintBoard(p.board);
	} else
		cout << "não foi dessa vez\n";
	return 0;
}

int main(int argc, char const *argv[]){

	cin >> size;

	int nthreads;
	cin >> nthreads;

	vector<Info> p;
	populate(p,nthreads);

	for (unsigned int i = 0; i < p.size(); i++) {
	    cout << i << ": x=" << p[i].x << ", y=" << p[i].y << '\n';
			//   	PrintBoard(p[i].board);
	}

	thread t[nthreads];
  for (int i = 0; i < nthreads; i++)
      t[i] = thread(KnightsTour, p[i]);

	cout << "\nThreads em execução\n";

  for (int i = 0; i < nthreads; i++) {
    // cout << "thread[" << i << "]\n";
    // if (t[i].joinable()){
    	t[i].join();
    	// break;}

  }

	return 0;
}
<|endoftext|>


<commit_before>#include <QtTest/QtTest>
#include <QProcess>
#include <QScreen>
#include <QPixmap>

#include "../cutehmi.dirs.hpp"

namespace cutehmi {
namespace daemon {

class test_cutehmi_view:
	public QObject
{
		Q_OBJECT

	private slots:
		void initTestCase();

		void helpOption();

		void versionOption();

		void screenshot();

	private:
		QString m_installDir;
		QString m_programPath;
		int m_windowDecorationsWidth;
		int m_windowDecorationsHeight;
};

void test_cutehmi_view::initTestCase()
{
	m_installDir = qEnvironmentVariable("CUTEHMI_INSTALL_DIR");
	QVERIFY(!m_installDir.isEmpty());

	QString toolsInstallSubdir = CUTEHMI_DIRS_TOOLS_INSTALL_SUBDIR;
	m_programPath = m_installDir;
	if (!toolsInstallSubdir.isEmpty())
		m_programPath += "/" + toolsInstallSubdir;
	m_programPath +=  "/cutehmi.view.2";
#ifndef CUTEHMI_NDEBUG
	m_programPath += ".debug";
#endif

	// Using helper window to calculate size of window decorations.
	QWindow helperWindow;
	helperWindow.show();
	m_windowDecorationsWidth = helperWindow.frameGeometry().width() - helperWindow.geometry().width();
	m_windowDecorationsHeight = helperWindow.frameGeometry().height() - helperWindow.geometry().height();
}

void test_cutehmi_view::helpOption()
{
	QList<QStringList> argumentsList;
	argumentsList << QStringList({"--help"})
			<< QStringList({"--h"});

	for (auto arguments : argumentsList) {
		QProcess process;
		process.start(m_programPath, arguments);
		process.waitForFinished(1000);
		QCOMPARE(process.error(), QProcess::UnknownError);
		QVERIFY(!process.readAllStandardError().contains("Unknown option"));
		QVERIFY(!process.readAllStandardOutput().isEmpty());
		QCOMPARE(process.exitStatus(), QProcess::NormalExit);
		QCOMPARE(process.exitCode(), EXIT_SUCCESS);
	}
}

void test_cutehmi_view::versionOption()
{
	QList<QStringList> argumentsList;
	argumentsList << QStringList({"--version"})
			<< QStringList({"--v"});

	for (auto arguments : argumentsList) {
		QProcess process;
		process.start(m_programPath, arguments);
		process.waitForFinished(1000);
		QCOMPARE(process.error(), QProcess::UnknownError);
		QVERIFY(!process.readAllStandardError().contains("Unknown option"));
		QVERIFY(!process.readAllStandardOutput().isEmpty());
		QCOMPARE(process.exitStatus(), QProcess::NormalExit);
		QCOMPARE(process.exitCode(), EXIT_SUCCESS);
	}
}

void test_cutehmi_view::screenshot()
{
	int width = 800;
	int height = 600;

	QStringList arguments;
	QString windowgeometryArg = QString::number(width) + "x" + QString::number(height) + "+0+0";
	arguments << "-qwindowgeometry" << windowgeometryArg << "--lang" << "en_EN";

	QString screenshotPath = m_installDir;
	if (screenshotPath.isEmpty())
		screenshotPath = QDir::temp().path();
	QString artifactsInstallSubdir = CUTEHMI_DIRS_ARTIFACTS_INSTALL_SUBDIR;
	if (!artifactsInstallSubdir.isEmpty())
		screenshotPath += "/" + artifactsInstallSubdir;
	screenshotPath += "/screenshots/" CUTEHMI_DIRS_PROJECT_RELATIVE_PATH "/doc/screenshot.png";
	const char * screenshotFormat = "PNG";

	QProcess process;
	process.start(m_programPath, arguments);
	process.waitForFinished(2500);	// This gives some time for the GUI to show up.

	QScreen * screen = QGuiApplication::primaryScreen();
	if (screen) {
		QPixmap screenshot = screen->grabWindow(0, 0, 0, width + m_windowDecorationsWidth, height + m_windowDecorationsHeight);
		QVERIFY(QDir().mkpath(QFileInfo(screenshotPath).dir().path()));
		QVERIFY(screenshot.save(screenshotPath, screenshotFormat));
	}

	process.terminate();
	process.waitForFinished();
}

}
}

QTEST_MAIN(cutehmi::daemon::test_cutehmi_view)
#include "test_cutehmi_view.moc"

//(c)C: Copyright © 2020, Michał Policht <michal@policht.pl>. All rights reserved.
//(c)C: This file is a part of CuteHMI.
//(c)C: CuteHMI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//(c)C: CuteHMI 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 Lesser General Public License for more details.
//(c)C: You should have received a copy of the GNU Lesser General Public License along with CuteHMI.  If not, see <https://www.gnu.org/licenses/>.
<commit_msg>Increase timeout.<commit_after>#include <QtTest/QtTest>
#include <QProcess>
#include <QScreen>
#include <QPixmap>

#include "../cutehmi.dirs.hpp"

namespace cutehmi {
namespace daemon {

class test_cutehmi_view:
	public QObject
{
		Q_OBJECT

	private slots:
		void initTestCase();

		void helpOption();

		void versionOption();

		void screenshot();

	private:
		QString m_installDir;
		QString m_programPath;
		int m_windowDecorationsWidth;
		int m_windowDecorationsHeight;
};

void test_cutehmi_view::initTestCase()
{
	m_installDir = qEnvironmentVariable("CUTEHMI_INSTALL_DIR");
	QVERIFY(!m_installDir.isEmpty());

	QString toolsInstallSubdir = CUTEHMI_DIRS_TOOLS_INSTALL_SUBDIR;
	m_programPath = m_installDir;
	if (!toolsInstallSubdir.isEmpty())
		m_programPath += "/" + toolsInstallSubdir;
	m_programPath +=  "/cutehmi.view.2";
#ifndef CUTEHMI_NDEBUG
	m_programPath += ".debug";
#endif

	// Using helper window to calculate size of window decorations.
	QWindow helperWindow;
	helperWindow.show();
	m_windowDecorationsWidth = helperWindow.frameGeometry().width() - helperWindow.geometry().width();
	m_windowDecorationsHeight = helperWindow.frameGeometry().height() - helperWindow.geometry().height();
}

void test_cutehmi_view::helpOption()
{
	QList<QStringList> argumentsList;
	argumentsList << QStringList({"--help"})
			<< QStringList({"--h"});

	for (auto arguments : argumentsList) {
		QProcess process;
		process.start(m_programPath, arguments);
		process.waitForFinished(1000);
		QCOMPARE(process.error(), QProcess::UnknownError);
		QVERIFY(!process.readAllStandardError().contains("Unknown option"));
		QVERIFY(!process.readAllStandardOutput().isEmpty());
		QCOMPARE(process.exitStatus(), QProcess::NormalExit);
		QCOMPARE(process.exitCode(), EXIT_SUCCESS);
	}
}

void test_cutehmi_view::versionOption()
{
	QList<QStringList> argumentsList;
	argumentsList << QStringList({"--version"})
			<< QStringList({"--v"});

	for (auto arguments : argumentsList) {
		QProcess process;
		process.start(m_programPath, arguments);
		process.waitForFinished(1000);
		QCOMPARE(process.error(), QProcess::UnknownError);
		QVERIFY(!process.readAllStandardError().contains("Unknown option"));
		QVERIFY(!process.readAllStandardOutput().isEmpty());
		QCOMPARE(process.exitStatus(), QProcess::NormalExit);
		QCOMPARE(process.exitCode(), EXIT_SUCCESS);
	}
}

void test_cutehmi_view::screenshot()
{
	int width = 800;
	int height = 600;

	QStringList arguments;
	QString windowgeometryArg = QString::number(width) + "x" + QString::number(height) + "+0+0";
	arguments << "-qwindowgeometry" << windowgeometryArg << "--lang" << "en_EN";

	QString screenshotPath = m_installDir;
	if (screenshotPath.isEmpty())
		screenshotPath = QDir::temp().path();
	QString artifactsInstallSubdir = CUTEHMI_DIRS_ARTIFACTS_INSTALL_SUBDIR;
	if (!artifactsInstallSubdir.isEmpty())
		screenshotPath += "/" + artifactsInstallSubdir;
	screenshotPath += "/screenshots/" CUTEHMI_DIRS_PROJECT_RELATIVE_PATH "/doc/screenshot.png";
	const char * screenshotFormat = "PNG";

	QProcess process;
	process.start(m_programPath, arguments);
	process.waitForFinished(3500);	// This gives some time for the GUI to show up.

	QScreen * screen = QGuiApplication::primaryScreen();
	if (screen) {
		QPixmap screenshot = screen->grabWindow(0, 0, 0, width + m_windowDecorationsWidth, height + m_windowDecorationsHeight);
		QVERIFY(QDir().mkpath(QFileInfo(screenshotPath).dir().path()));
		QVERIFY(screenshot.save(screenshotPath, screenshotFormat));
	}

	process.terminate();
	process.waitForFinished();
}

}
}

QTEST_MAIN(cutehmi::daemon::test_cutehmi_view)
#include "test_cutehmi_view.moc"

//(c)C: Copyright © 2020, Michał Policht <michal@policht.pl>. All rights reserved.
//(c)C: This file is a part of CuteHMI.
//(c)C: CuteHMI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//(c)C: CuteHMI 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 Lesser General Public License for more details.
//(c)C: You should have received a copy of the GNU Lesser General Public License along with CuteHMI.  If not, see <https://www.gnu.org/licenses/>.
<|endoftext|>


<commit_before>#include <Kokkos_Core.hpp>
#include <KokkosSparse_CrsMatrix.hpp>
#include <binGraph.h>
#include <mpi.h>
#include <stdio.h>
#include <engpar_support.h>

int main(int argc, char* argv[]) {

  MPI_Init(&argc,&argv);
  EnGPar_Initialize();
  if ( argc != 2 ) {
    if ( !PCU_Comm_Self() )
      printf("Usage: %s <binary_graph_file>",argv[0]);
    EnGPar_Finalize();
    MPI_Finalize();
    assert(false);
  }

  Kokkos::initialize(argc,argv);

  agi::Ngraph* g = agi::createBinGraph(argv[1]);

  agi::PNgraph* pg = g->publicize();

  const agi::lid_t numverts = pg->num_local_verts;

  const agi::lid_t numedges = pg->num_local_edges[0];  // Add support for multiple edge types

  const agi::lid_t* degree_list = pg->degree_list[0]; // ^

  const agi::lid_t* edge_list = pg->edge_list[0]; // ^

  // Create views for each part of the graph data-structure

  Kokkos::View<agi::lid_t*> degree_view ("degree_view",numverts);

  Kokkos::View<agi::lid_t*> edge_view ("edge_view",numedges);

  // Use parllel loops to fill the views

  Kokkos::parallel_for(numverts+1, KOKKOS_LAMBDA( const int i ) {
    degree_view(i) = degree_list[i];
  });

  Kokkos::parallel_for(numedges, KOKKOS_LAMBDA( const int i) {
    edge_view(i) = edge_list[i];
  });

  // KokkosKernels::KokkosSparse::CrsMatrix<const agi::lid_t, ?, device>(numverts,numverts,numedges,degree_view,edge_view);

  // KokkosKernelsHandle<const Kokkos::View<agi::lid_t,const Kokkos::View<agi::lid_t*>,const agi::lid_t> *kh = new KernelHandle;
  // kh.set_team_work_size(16);
  // kh.set_dynamic_scheduling(true);
  // kh.create_graph_coloring_handle(COLORING_SERIAL);
  //
  // kh->destroy_graph_coloring_handle();

  destroyGraph(g);
  PCU_Barrier();
  if (!PCU_Comm_Self())
    printf("\nAll tests passed\n");
  Kokkos::finalize();
  EnGPar_Finalize();
  MPI_Finalize();

  return 0;

}
<commit_msg>working kokkos coloring<commit_after>#include <Kokkos_Core.hpp>
#include <KokkosSparse_CrsMatrix.hpp>
#include <KokkosGraph_graph_color.hpp>
#include <KokkosKernels_Handle.hpp>
#include <binGraph.h>
#include <mpi.h>
#include <stdio.h>
#include <engpar_support.h>
#include <iostream>

int main(int argc, char* argv[]) {

  MPI_Init(&argc,&argv);
  EnGPar_Initialize();
  if ( argc != 2 ) {
    if ( !PCU_Comm_Self() )
      printf("Usage: %s <binary_graph_file>",argv[0]);
    EnGPar_Finalize();
    MPI_Finalize();
    assert(false);
  }

  Kokkos::initialize(argc,argv);

  agi::Ngraph* g = agi::createBinGraph(argv[1]);

  agi::PNgraph* pg = g->publicize();

  const agi::lid_t numverts = pg->num_local_verts;

  const agi::lid_t numedges = pg->num_local_edges[0];  // Add support for multiple edge types

  const agi::lid_t* degree_list = pg->degree_list[0]; // ^

  const agi::lid_t* edge_list = pg->edge_list[0]; // ^

  // Create views for each part of the graph data-structure

  Kokkos::View<agi::lid_t*> degree_view ("degree_view",numverts+1);

  Kokkos::View<agi::lid_t*> edge_view ("edge_view",numedges);

  Kokkos::View<agi::lid_t*> vals_view("vals_view",numedges);

  // Use parllel loops to fill the views

  Kokkos::parallel_for(numverts+1, KOKKOS_LAMBDA( const int i ) {
    degree_view(i) = degree_list[i];
  });

  Kokkos::parallel_for(numedges, KOKKOS_LAMBDA( const int i) {
    edge_view(i) = edge_list[i];
    vals_view(i) = 1;
  });

  KokkosSparse::CrsMatrix<agi::lid_t, agi::lid_t, Kokkos::Serial::device_type, void, int>("graph", numverts, numverts, numedges, vals_view, degree_view, edge_view);
//  KokkosSparse::CrsMatrix<agi::lid_t, agi::lid_t, Kokkos::Cuda::device_type, void, int>("graph", numverts-1, numverts-1, numedges, vals_view, degree_view, edge_view);

  typedef KokkosKernels::Experimental::KokkosKernelsHandle<agi::lid_t, agi::lid_t, agi::lid_t,
                                                           Kokkos::Serial::execution_space,
                                                           Kokkos::Serial::memory_space,
                                                           Kokkos::Serial::memory_space> KernelHandle;
//  typedef KokkosKernels::Experimental::KokkosKernelsHandle<agi::lid_t, agi::lid_t, agi::lid_t,
//                                                           Kokkos::Cuda::execution_space,
//                                                           Kokkos::Cuda::CudaSpace,
//                                                           Kokkos::Cuda::scratch_memory_space> KernelHandle;

  KernelHandle *kh = new KernelHandle();
  kh->set_team_work_size(16);
  kh->set_dynamic_scheduling(true);
  kh->create_graph_coloring_handle(KokkosGraph::COLORING_SERIAL);
//  kh->create_graph_coloring_handle(KokkosGraph::COLORING_DEFAULT);

  KokkosGraph::Experimental::graph_color_symbolic
	<KernelHandle, Kokkos::View<agi::lid_t*>, Kokkos::View<agi::lid_t*> >
	(kh, numverts, numverts, degree_view, edge_view);

  Kokkos::View<int*> vert_colors = kh->get_graph_coloring_handle()->get_vertex_colors();

  agi::checkValidity(g);
  agi::GraphTag* tag = g->createIntTag(-1);
  agi::GraphVertex* v;
  agi::VertexIterator* vitr = g->begin();

  // Assigning colors to the original graph
  int i=0;
  while ((v=g->iterate(vitr))) {
    g->setIntTag(tag,v,vert_colors(i++));
  }

  // Write the vtk files
  std::string filename = "kokkos_color";
//  agi::writeVTK(g,filename.c_str(),tag,-1);

  // Finalize & Delete
  kh->destroy_graph_coloring_handle();
  destroyGraph(g);
  PCU_Barrier();
  if (!PCU_Comm_Self())
    printf("\nAll tests passed\n");
  Kokkos::finalize();
  EnGPar_Finalize();
  MPI_Finalize();

  return 0;

}
<|endoftext|>


<commit_before>#include <Kokkos_Core.hpp>
#include <KokkosSparse_CrsMatrix.hpp>
#include <KokkosGraph_graph_color.hpp>
#include <KokkosKernels_Handle.hpp>
#include <binGraph.h>
#include <mpi.h>
#include <stdio.h>
#include <engpar_support.h>
#include <cstring>

#include <iostream>

bool Check_Directed(agi::Ngraph* g, agi::etype t=0) {

  agi::PNgraph* pg = g->publicize();

  const agi::lid_t numverts = pg->num_local_verts;

  const agi::lid_t* degree_list = pg->degree_list[t];

  const agi::lid_t* edge_list = pg->edge_list[t];

  for (int i=0; i<numverts; ++i) {
    for (int j=degree_list[i]; j<degree_list[i+1]; ++j) {
      bool back_edge = false;
      for (int k=degree_list[edge_list[j]]; k<degree_list[1+edge_list[j]]; ++k) {
        if (i == edge_list[k])
          back_edge = true;
      }
      if (!back_edge) {
        std::cout << "Directed graphs are not supported" << std::endl;
        return false;
      }
    }
  }
  return true;
}

void Color_Graph(agi::Ngraph* g, agi::etype t=0) {

  agi::PNgraph* pg = g->publicize();

  const agi::lid_t numverts = pg->num_local_verts;

  const agi::lid_t numedges = pg->num_local_edges[t];

  const agi::lid_t* degree_list = pg->degree_list[t];

  const agi::lid_t* edge_list = pg->edge_list[t];

  // Create views for each part of the graph data-structure

  Kokkos::View<agi::lid_t*> degree_view ("degree_view",numverts+1);

  Kokkos::View<agi::lid_t*> edge_view ("edge_view",numedges);

  // Use parllel loops to fill the views

  Kokkos::parallel_for(numverts+1, KOKKOS_LAMBDA( const int i ) {
    degree_view(i) = degree_list[i];
  });

  Kokkos::parallel_for(numedges, KOKKOS_LAMBDA( const int i) {
    edge_view(i) = edge_list[i];
  });

  typedef Kokkos::DefaultExecutionSpace exe_space;
  typedef KokkosSparse::CrsMatrix<agi::lid_t, agi::lid_t, Kokkos::Device<exe_space,exe_space::memory_space>, void, int> crsMat_t;
  typedef crsMat_t::StaticCrsGraphType graph_t;
  typedef graph_t::entries_type::non_const_type color_view_t;
  typedef graph_t::row_map_type lno_view_t;
  typedef graph_t::entries_type lno_nnz_view_t;
  typedef graph_t::entries_type::non_const_type  color_view_t;
  typedef KokkosKernels::Experimental::KokkosKernelsHandle <agi::lid_t, agi::lid_t, agi::lid_t,
            exe_space, exe_space::memory_space, exe_space::memory_space> KernelHandle;

  // Create kernel handle
  KernelHandle* kh = new KernelHandle();
  kh->set_team_work_size(16);
  kh->set_dynamic_scheduling(true);
  kh->create_graph_coloring_handle(KokkosGraph::COLORING_DEFAULT);

  // Run kokkos coloring
  KokkosGraph::Experimental::graph_color
	<KernelHandle, Kokkos::View<agi::lid_t*>, Kokkos::View<agi::lid_t*> >
	(kh, numverts, numverts, degree_view, edge_view);

  color_view_t vert_colors = kh->get_graph_coloring_handle()->get_vertex_colors();

  // ########## IMPL CHECK ##########
  assert( (0==KokkosKernels::Impl::kk_is_d1_coloring_valid <lno_view_t, lno_nnz_view_t, color_view_t, exe_space>
                (numverts, numverts, degree_view, edge_view, vert_colors)) );

  // Assign colors from kokkos graph to EnGPar graph
  agi::checkValidity(g);
  agi::GraphTag* tag = g->createIntTag(-1);
  agi::GraphVertex* v;
  agi::VertexIterator* vitr = g->begin();

  // Assigning colors to the original graph
  int i=0;
  while ((v=g->iterate(vitr))) {
    g->setIntTag(tag,v,vert_colors(i++));
  }

  // Check that coloring is valid
  agi::GraphEdge* e;
  agi::EdgeIterator* eitr = g->begin(0);
  int conflicts = 0;
  while ((e=g->iterate(eitr))) {
    int u = g->getIntTag(tag, g->u(e));
    int v = g->getIntTag(tag, g->v(e));
    if (u==v) ++conflicts;
  }
  g->destroy(eitr);
  assert(conflicts == 0);

  kh->destroy_graph_coloring_handle();

}

int main(int argc, char* argv[]) {

  MPI_Init(&argc,&argv);
  EnGPar_Initialize();
  if ( argc != 2 ) {
    if ( !PCU_Comm_Self() )
      printf("Usage: %s <binary_graph_file>",argv[0]);
    EnGPar_Finalize();
    MPI_Finalize();
    assert(false);
  }

  Kokkos::initialize(argc,argv);

  agi::Ngraph* g = agi::createBinGraph(argv[1]);

  assert(Check_Directed(g));

  Color_Graph(g);

  destroyGraph(g);
  PCU_Barrier();
  if (!PCU_Comm_Self())
    printf("\nAll tests passed\n");
  Kokkos::finalize();
  EnGPar_Finalize();
  MPI_Finalize();

  return 0;

}
<commit_msg>coloring: exec space, coloring time<commit_after>#include <Kokkos_Core.hpp>
#include <KokkosSparse_CrsMatrix.hpp>
#include <KokkosGraph_graph_color.hpp>
#include <KokkosKernels_Handle.hpp>
#include <binGraph.h>
#include <mpi.h>
#include <stdio.h>
#include <engpar_support.h>
#include <cstring>

#include <iostream>

bool Check_Directed(agi::Ngraph* g, agi::etype t=0) {

  agi::PNgraph* pg = g->publicize();

  const agi::lid_t numverts = pg->num_local_verts;

  const agi::lid_t* degree_list = pg->degree_list[t];

  const agi::lid_t* edge_list = pg->edge_list[t];

  for (int i=0; i<numverts; ++i) {
    for (int j=degree_list[i]; j<degree_list[i+1]; ++j) {
      bool back_edge = false;
      for (int k=degree_list[edge_list[j]]; k<degree_list[1+edge_list[j]]; ++k) {
        if (i == edge_list[k])
          back_edge = true;
      }
      if (!back_edge) {
        std::cout << "Directed graphs are not supported" << std::endl;
        return false;
      }
    }
  }
  return true;
}

void Color_Graph(agi::Ngraph* g, agi::etype t=0) {

  agi::PNgraph* pg = g->publicize();

  const agi::lid_t numverts = pg->num_local_verts;

  const agi::lid_t numedges = pg->num_local_edges[t];

  const agi::lid_t* degree_list = pg->degree_list[t];

  const agi::lid_t* edge_list = pg->edge_list[t];

  // Create views for each part of the graph data-structure

  Kokkos::View<agi::lid_t*> degree_view ("degree_view",numverts+1);

  Kokkos::View<agi::lid_t*> edge_view ("edge_view",numedges);

  // Use parllel loops to fill the views

  Kokkos::parallel_for(numverts+1, KOKKOS_LAMBDA( const int i ) {
    degree_view(i) = degree_list[i];
  });

  Kokkos::parallel_for(numedges, KOKKOS_LAMBDA( const int i) {
    edge_view(i) = edge_list[i];
  });

  typedef Kokkos::DefaultExecutionSpace exe_space;
  typedef KokkosSparse::CrsMatrix<agi::lid_t, agi::lid_t, Kokkos::Device<exe_space,exe_space::memory_space>, void, int> crsMat_t;
  typedef crsMat_t::StaticCrsGraphType graph_t;
  typedef graph_t::entries_type::non_const_type color_view_t;
  typedef graph_t::row_map_type lno_view_t;
  typedef graph_t::entries_type lno_nnz_view_t;
  typedef graph_t::entries_type::non_const_type  color_view_t;
  typedef KokkosKernels::Experimental::KokkosKernelsHandle <agi::lid_t, agi::lid_t, agi::lid_t,
            exe_space, exe_space::memory_space, exe_space::memory_space> KernelHandle;

  // sanity check to see execution space
  printf ("Execution space: %s \n", typeid (exe_space).name());

  // Create kernel handle
  KernelHandle* kh = new KernelHandle();
  kh->set_team_work_size(16);
  kh->set_dynamic_scheduling(true);
  kh->create_graph_coloring_handle(KokkosGraph::COLORING_DEFAULT);

  // Run kokkos coloring
  KokkosGraph::Experimental::graph_color
	<KernelHandle, Kokkos::View<agi::lid_t*>, Kokkos::View<agi::lid_t*> >
	(kh, numverts, numverts, degree_view, edge_view);

  color_view_t vert_colors = kh->get_graph_coloring_handle()->get_vertex_colors();

  // ########## IMPL CHECK ##########
  assert( (0==KokkosKernels::Impl::kk_is_d1_coloring_valid <lno_view_t, lno_nnz_view_t, color_view_t, exe_space>
                (numverts, numverts, degree_view, edge_view, vert_colors)) );

  // Assign colors from kokkos graph to EnGPar graph
  agi::checkValidity(g);
  agi::GraphTag* tag = g->createIntTag(-1);
  agi::GraphVertex* v;
  agi::VertexIterator* vitr = g->begin();

  // Assigning colors to the original graph
  int i=0;
  while ((v=g->iterate(vitr))) {
    g->setIntTag(tag,v,vert_colors(i++));
  }

  // Check that coloring is valid
  agi::GraphEdge* e;
  agi::EdgeIterator* eitr = g->begin(0);
  int conflicts = 0;
  while ((e=g->iterate(eitr))) {
    int u = g->getIntTag(tag, g->u(e));
    int v = g->getIntTag(tag, g->v(e));
    if (u==v) ++conflicts;
  }
  g->destroy(eitr);
  assert(conflicts == 0);

  kh->destroy_graph_coloring_handle();

}

int main(int argc, char* argv[]) {

  MPI_Init(&argc,&argv);
  EnGPar_Initialize();
  if ( argc != 2 ) {
    if ( !PCU_Comm_Self() )
      printf("Usage: %s <binary_graph_file>",argv[0]);
    EnGPar_Finalize();
    MPI_Finalize();
    assert(false);
  }

  Kokkos::initialize(argc,argv);

  agi::Ngraph* g = agi::createBinGraph(argv[1]);

  assert(Check_Directed(g));

  double t0 = PCU_Time();
  Color_Graph(g);
  std::cout << "Coloring time: " << PCU_Time()-t0 << std::endl;

  destroyGraph(g);
  PCU_Barrier();
  if (!PCU_Comm_Self())
    printf("\nAll tests passed\n");
  Kokkos::finalize();
  EnGPar_Finalize();
  MPI_Finalize();

  return 0;

}
<|endoftext|>