<commit_before>#include <algorithm>
#include <map>
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

#include <fj_tool/fapp.h>
#include <fjcoll.h>

using namespace std;

#include "pearson-3d.h"

bool EXTEND_MISSION=false;
int T_MAX;
int T_MONITOR;
int mpi_my_rank;
const double PI=3.14159265358979323846;

float frand() {
  return rand() / float(RAND_MAX);
}

double wctime() {
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (double)tv.tv_sec + (double)tv.tv_usec*1e-6;
}
/*
void init() {
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
    for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
      for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
        double x = double(navi.offset_x + ix)/NX;
        double y = double(navi.offset_y + iy)/NY;
        double z = double(navi.offset_z + iz)/NZ;
        U[ix][iy][iz] = 1.0;
        V[ix][iy][iz] = 0.0;
        if (z > 0.49 && z < 0.51 && x > 0.4 && x < 0.6) {
          U[ix][iy][iz] = 0.5;
          V[ix][iy][iz] = 0.25;
        }
      }
    }
  }
}*/

typedef pair<int,pair<int,int> > Key;
void init() {
  map<Key ,double> seeds;
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
    for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
      for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
        Key k (ix/16, pair<int,int>(iy/16, iz/16));
        U[ix][iy][iz] = 1.0;
        V[ix][iy][iz] = 0.0;
        double s = seeds[k];
        if (s==0) {
          s = frand();
          seeds[k]=s;
        }
        if (s < 0.1 ) {
          U[ix][iy][iz] = 0.5;
          V[ix][iy][iz] = 0.25;
        }
      }
    }
  }
  }

void write_monitor() {
  printf("#%d: t = %d\n", mpi_my_rank, navi.time_step);

  int global_position[6];
  global_position[0] = navi.offset_x + navi.lower_x;
  global_position[1] = navi.offset_y + navi.lower_y;
  global_position[2] = navi.offset_z + navi.lower_z;
  global_position[3] = navi.upper_x - navi.lower_x;
  global_position[4] = navi.upper_y - navi.lower_y;
  global_position[5] = navi.upper_z - navi.lower_z;
  int x_size = navi.upper_x - navi.lower_x;
  int y_size = navi.upper_y - navi.lower_y;
  int z_size = navi.upper_z - navi.lower_z;

  if (navi.offset_x + navi.lower_x < navi.upper_x) {
    char fn[256];
    sprintf(fn, "out/monitorX-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int x=navi.lower_x + x_size/2;
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

  if (navi.offset_y + navi.lower_y < navi.upper_y) {
    char fn[256];
    sprintf(fn, "out/monitorY-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int y=navi.lower_y + y_size/2;
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

}

int main (int argc, char **argv) {
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);
  srand(time(NULL)+mpi_my_rank*65537);

  if (argc <= 1) {
    T_MAX=8192;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  if (argc <= 2) {
    T_MONITOR=8192;
  }else{
    sscanf(argv[2], "%d",  &T_MONITOR);
  }
  if (argc >= 4) {
    EXTEND_MISSION = true;
  }

  init();

  double t_begin = wctime(), t_end;

  int last_monitor_t = -T_MONITOR;
  char[256] benchmark_name;
  sprintf(benchmark_name,"main");
  for(;;){
    double t = wctime();
    bool monitor_flag = navi.time_step >= last_monitor_t + T_MONITOR;
    if(monitor_flag || navi.time_step <= 3 * T_MONITOR ) {
      printf("%d step @ %lf sec\n", navi.time_step, t-t_begin);
    }
    if(monitor_flag) {
      write_monitor();
    }
    if(monitor_flag) {
      last_monitor_t += T_MONITOR;
    }

    if (navi.time_step >= T_MAX) {
      if (EXTEND_MISSION){
        T_MAX*=2;
        T_MONITOR*=2;
        sprintf(benchmark_name,"extend-%d",T_MAX);
        start_collection(benchmark_name);
      }else{
        break;
      }

    }
    if (navi.time_step == 0) {
      t_begin = wctime();
      start_collection(benchmark_name);
    }

    Formura_Forward(&navi); // navi.time_step increases
    MPI_Barrier(MPI_COMM_WORLD); // TODO: test the effect of synchronization

    if (navi.time_step >= T_MAX) {
      t_end = wctime();
      stop_collection(benchmark_name);
    }
  }
  printf("wct = %lf sec\n",t_end - t_begin);

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
}
<commit_msg>Fix bug<commit_after>#include <algorithm>
#include <map>
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

#include <fj_tool/fapp.h>
#include <fjcoll.h>

using namespace std;

#include "pearson-3d.h"

bool EXTEND_MISSION=false;
int T_MAX;
int T_MONITOR;
int mpi_my_rank;
const double PI=3.14159265358979323846;

float frand() {
  return rand() / float(RAND_MAX);
}

double wctime() {
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (double)tv.tv_sec + (double)tv.tv_usec*1e-6;
}
/*
void init() {
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
    for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
      for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
        double x = double(navi.offset_x + ix)/NX;
        double y = double(navi.offset_y + iy)/NY;
        double z = double(navi.offset_z + iz)/NZ;
        U[ix][iy][iz] = 1.0;
        V[ix][iy][iz] = 0.0;
        if (z > 0.49 && z < 0.51 && x > 0.4 && x < 0.6) {
          U[ix][iy][iz] = 0.5;
          V[ix][iy][iz] = 0.25;
        }
      }
    }
  }
}*/

typedef pair<int,pair<int,int> > Key;
void init() {
  map<Key ,double> seeds;
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
    for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
      for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
        Key k (ix/16, pair<int,int>(iy/16, iz/16));
        U[ix][iy][iz] = 1.0;
        V[ix][iy][iz] = 0.0;
        double s = seeds[k];
        if (s==0) {
          s = frand();
          seeds[k]=s;
        }
        if (s < 0.1 ) {
          U[ix][iy][iz] = 0.5;
          V[ix][iy][iz] = 0.25;
        }
      }
    }
  }
  }

void write_monitor() {
  printf("#%d: t = %d\n", mpi_my_rank, navi.time_step);

  int global_position[6];
  global_position[0] = navi.offset_x + navi.lower_x;
  global_position[1] = navi.offset_y + navi.lower_y;
  global_position[2] = navi.offset_z + navi.lower_z;
  global_position[3] = navi.upper_x - navi.lower_x;
  global_position[4] = navi.upper_y - navi.lower_y;
  global_position[5] = navi.upper_z - navi.lower_z;
  int x_size = navi.upper_x - navi.lower_x;
  int y_size = navi.upper_y - navi.lower_y;
  int z_size = navi.upper_z - navi.lower_z;

  if (navi.offset_x + navi.lower_x < navi.upper_x) {
    char fn[256];
    sprintf(fn, "out/monitorX-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int x=navi.lower_x + x_size/2;
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

  if (navi.offset_y + navi.lower_y < navi.upper_y) {
    char fn[256];
    sprintf(fn, "out/monitorY-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int y=navi.lower_y + y_size/2;
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

}

int main (int argc, char **argv) {
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);
  srand(time(NULL)+mpi_my_rank*65537);

  if (argc <= 1) {
    T_MAX=8192;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  if (argc <= 2) {
    T_MONITOR=8192;
  }else{
    sscanf(argv[2], "%d",  &T_MONITOR);
  }
  if (argc >= 4) {
    EXTEND_MISSION = true;
  }

  init();

  double t_begin = wctime(), t_end;

  int last_monitor_t = -T_MONITOR;
  char benchmark_name[256];
  sprintf(benchmark_name,"main");
  for(;;){
    double t = wctime();
    bool monitor_flag = navi.time_step >= last_monitor_t + T_MONITOR;
    if(monitor_flag || navi.time_step <= 3 * T_MONITOR ) {
      printf("%d step @ %lf sec\n", navi.time_step, t-t_begin);
    }
    if(monitor_flag) {
      write_monitor();
    }
    if(monitor_flag) {
      last_monitor_t += T_MONITOR;
    }

    if (navi.time_step >= T_MAX) {
      if (EXTEND_MISSION){
        T_MAX*=2;
        T_MONITOR*=2;
        sprintf(benchmark_name,"extend-%d",T_MAX);
        start_collection(benchmark_name);
      }else{
        break;
      }

    }
    if (navi.time_step == 0) {
      t_begin = wctime();
      start_collection(benchmark_name);
    }

    Formura_Forward(&navi); // navi.time_step increases
    MPI_Barrier(MPI_COMM_WORLD); // TODO: test the effect of synchronization

    if (navi.time_step >= T_MAX) {
      t_end = wctime();
      stop_collection(benchmark_name);
    }
  }
  printf("wct = %lf sec\n",t_end - t_begin);

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Sjors Gielen, 2010
 * See LICENSE for license.
 */

#include "perlplugin.h"
#include "perl/embedperl.h"
#include "../config.h"
#include "pluginmanager.h"

#include <QtCore/QDebug>
#include <ircclient-qt/IrcBuffer>

// #define DEBUG

extern "C" {
  void perlplugin_emote_callback( const char *net, const char *recv, const char *body, void *data )
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->emoteCallback( net, recv, body );
  }
  void perlplugin_privmsg_callback( const char *net, const char *recv, const char *body, void *data )
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->privmsgCallback( net, recv, body );
  }
  const char* perlplugin_getProperty_callback( const char *net, const char *variable, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    return pp->getPropertyCallback(net, variable);
  }
  void perlplugin_setProperty_callback( const char *net, const char *variable, const char *value, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->setPropertyCallback(net, variable, value);
  }
  void perlplugin_unsetProperty_callback( const char *net, const char *variable, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->unsetPropertyCallback(net, variable);
  }
  void perlplugin_sendWhois_callback(const char *who, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->sendWhoisCallback(who);
  }
  void perlplugin_join_callback(const char *channel, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->joinCallback(channel);
  }
  void perlplugin_part_callback(const char *channel, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->partCallback(channel);
  }
  const char*perlplugin_getNick_callback( void *data )
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    return pp->getNickCallback();
  }
}

PerlPlugin::PerlPlugin( PluginManager *man )
: Plugin(man)
, whois_identified(false)
{
}

PerlPlugin::~PerlPlugin() {}

void PerlPlugin::init()
{
#ifdef DEBUG
  qDebug() << "PerlPlugin initialising.";
#endif
}

EmbedPerl *PerlPlugin::getNetworkEmbed( Network &net )
{
  if( ePerl.contains( net.config()->name ) )
    return ePerl.value( net.config()->name );

  EmbedPerl *newPerl = new EmbedPerl( net.config()->name.toLatin1() );
  newPerl->setCallbacks( perlplugin_emote_callback, perlplugin_privmsg_callback,
                         perlplugin_getProperty_callback, perlplugin_setProperty_callback,
                         perlplugin_unsetProperty_callback, perlplugin_sendWhois_callback,
                         perlplugin_join_callback, perlplugin_part_callback,
                         perlplugin_getNick_callback, this );
  newPerl->loadModule( "DazMessages" );
  newPerl->loadModule( "DazFactoids" );

  ePerl.insert( net.config()->name, newPerl );
  return newPerl;
}

void PerlPlugin::messageReceived( Network &net, const QString &origin, const QString &message,
                                  Irc::Buffer *buffer )
{
  getNetworkEmbed(net)->message( origin.toLatin1(), buffer->receiver().toLatin1(), message.toUtf8() );
}

void PerlPlugin::numericMessageReceived( Network &net, const QString &origin, uint code,
                                     const QStringList &args, Irc::Buffer *buf )
{
  if( code == 311 )
  {
    in_whois = args[1];
    Q_ASSERT( !whois_identified );
  }
#warning This will not work - should use CAP IDENTIFY_MSG for this:
  else if( code == 307 || code == 330 ) // 330 means "logged in as", but doesn't check whether nick is grouped.
  {
    whois_identified = true;
  }
  else if( code == 318 )
  {
    getNetworkEmbed(net)->whois( in_whois.toLatin1().constData(), whois_identified ? 1 : 0 );
    whois_identified = false;
    in_whois.clear();
  }
}

void PerlPlugin::emoteCallback( const char *network, const char *receiver, const char *body )
{
  Network *net = Network::getNetwork( network );
  Q_ASSERT( net != 0 );
  net->action( receiver, body );
}

void PerlPlugin::privmsgCallback( const char *network, const char *receiver, const char *body )
{
  Network *net = Network::getNetwork( network );
  Q_ASSERT( net != 0 );
  net->say( receiver, body );
}

const char *PerlPlugin::getPropertyCallback(const char *network, const char *variable)
{
  Q_UNUSED(network);

  QVariant value = get(variable);
#ifdef DEBUG
  qDebug() << "Get property: " << variable << "=" << value;
#endif
  if( value.isNull() )
    return 0;
  return value.toString().toUtf8().constData();
}

void PerlPlugin::setPropertyCallback(const char *network, const char *variable, const char *value)
{
  Q_UNUSED(network);

  set(Plugin::GlobalScope, variable, value);
#ifdef DEBUG
  qDebug() << "Set property: " << variable << "to:" << value;
#endif
}

void PerlPlugin::unsetPropertyCallback(const char *network, const char *variable)
{
  Q_UNUSED(network);

  set(Plugin::GlobalScope, variable, QVariant());
#ifdef DEBUG
  qDebug() << "Unset property: " << variable;
#endif
}

const char *PerlPlugin::getNickCallback()
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  return net->user()->nick().toUtf8().constData();
}

void PerlPlugin::sendWhoisCallback(const char *who)
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  net->sendWhois( who );
}

void PerlPlugin::joinCallback(const char *channel)
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  net->joinChannel( channel );
}

void PerlPlugin::partCallback(const char *channel)
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  net->leaveChannel( channel );
}

<commit_msg>Now also loading DazAuth, DazChannel, DazLoader during startup.<commit_after>/**
 * Copyright (c) Sjors Gielen, 2010
 * See LICENSE for license.
 */

#include "perlplugin.h"
#include "perl/embedperl.h"
#include "../config.h"
#include "pluginmanager.h"

#include <QtCore/QDebug>
#include <ircclient-qt/IrcBuffer>

// #define DEBUG

extern "C" {
  void perlplugin_emote_callback( const char *net, const char *recv, const char *body, void *data )
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->emoteCallback( net, recv, body );
  }
  void perlplugin_privmsg_callback( const char *net, const char *recv, const char *body, void *data )
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->privmsgCallback( net, recv, body );
  }
  const char* perlplugin_getProperty_callback( const char *net, const char *variable, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    return pp->getPropertyCallback(net, variable);
  }
  void perlplugin_setProperty_callback( const char *net, const char *variable, const char *value, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->setPropertyCallback(net, variable, value);
  }
  void perlplugin_unsetProperty_callback( const char *net, const char *variable, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->unsetPropertyCallback(net, variable);
  }
  void perlplugin_sendWhois_callback(const char *who, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->sendWhoisCallback(who);
  }
  void perlplugin_join_callback(const char *channel, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->joinCallback(channel);
  }
  void perlplugin_part_callback(const char *channel, void *data)
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    pp->partCallback(channel);
  }
  const char*perlplugin_getNick_callback( void *data )
  {
    PerlPlugin *pp = (PerlPlugin*) data;
    return pp->getNickCallback();
  }
}

PerlPlugin::PerlPlugin( PluginManager *man )
: Plugin(man)
, whois_identified(false)
{
}

PerlPlugin::~PerlPlugin() {}

void PerlPlugin::init()
{
#ifdef DEBUG
  qDebug() << "PerlPlugin initialising.";
#endif
}

EmbedPerl *PerlPlugin::getNetworkEmbed( Network &net )
{
  if( ePerl.contains( net.config()->name ) )
    return ePerl.value( net.config()->name );

  EmbedPerl *newPerl = new EmbedPerl( net.config()->name.toLatin1() );
  newPerl->setCallbacks( perlplugin_emote_callback, perlplugin_privmsg_callback,
                         perlplugin_getProperty_callback, perlplugin_setProperty_callback,
                         perlplugin_unsetProperty_callback, perlplugin_sendWhois_callback,
                         perlplugin_join_callback, perlplugin_part_callback,
                         perlplugin_getNick_callback, this );
  newPerl->loadModule( "DazAuth" );
  newPerl->loadModule( "DazChannel" );
  newPerl->loadModule( "DazLoader" );
  newPerl->loadModule( "DazMessages" );
  newPerl->loadModule( "DazFactoids" );

  ePerl.insert( net.config()->name, newPerl );
  return newPerl;
}

void PerlPlugin::messageReceived( Network &net, const QString &origin, const QString &message,
                                  Irc::Buffer *buffer )
{
  getNetworkEmbed(net)->message( origin.toLatin1(), buffer->receiver().toLatin1(), message.toUtf8() );
}

void PerlPlugin::numericMessageReceived( Network &net, const QString &origin, uint code,
                                     const QStringList &args, Irc::Buffer *buf )
{
  if( code == 311 )
  {
    in_whois = args[1];
    Q_ASSERT( !whois_identified );
  }
#warning This will not work - should use CAP IDENTIFY_MSG for this:
  else if( code == 307 || code == 330 ) // 330 means "logged in as", but doesn't check whether nick is grouped.
  {
    whois_identified = true;
  }
  else if( code == 318 )
  {
    getNetworkEmbed(net)->whois( in_whois.toLatin1().constData(), whois_identified ? 1 : 0 );
    whois_identified = false;
    in_whois.clear();
  }
}

void PerlPlugin::emoteCallback( const char *network, const char *receiver, const char *body )
{
  Network *net = Network::getNetwork( network );
  Q_ASSERT( net != 0 );
  net->action( receiver, body );
}

void PerlPlugin::privmsgCallback( const char *network, const char *receiver, const char *body )
{
  Network *net = Network::getNetwork( network );
  Q_ASSERT( net != 0 );
  net->say( receiver, body );
}

const char *PerlPlugin::getPropertyCallback(const char *network, const char *variable)
{
  Q_UNUSED(network);

  QVariant value = get(variable);
#ifdef DEBUG
  qDebug() << "Get property: " << variable << "=" << value;
#endif
  if( value.isNull() )
    return 0;
  return value.toString().toUtf8().constData();
}

void PerlPlugin::setPropertyCallback(const char *network, const char *variable, const char *value)
{
  Q_UNUSED(network);

  set(Plugin::GlobalScope, variable, value);
#ifdef DEBUG
  qDebug() << "Set property: " << variable << "to:" << value;
#endif
}

void PerlPlugin::unsetPropertyCallback(const char *network, const char *variable)
{
  Q_UNUSED(network);

  set(Plugin::GlobalScope, variable, QVariant());
#ifdef DEBUG
  qDebug() << "Unset property: " << variable;
#endif
}

const char *PerlPlugin::getNickCallback()
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  return net->user()->nick().toUtf8().constData();
}

void PerlPlugin::sendWhoisCallback(const char *who)
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  net->sendWhois( who );
}

void PerlPlugin::joinCallback(const char *channel)
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  net->joinChannel( channel );
}

void PerlPlugin::partCallback(const char *channel)
{
  Network *net = Network::getNetwork( manager()->context()->network );
  Q_ASSERT( net != 0 );
  net->leaveChannel( channel );
}

<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library 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 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library 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.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_CONSTRAINT_LINEARMOVEMENTCONSTRAINT_INL
#define SOFA_COMPONENT_CONSTRAINT_LINEARMOVEMENTCONSTRAINT_INL

#include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
#include <sofa/core/componentmodel/behavior/Constraint.inl>
#include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
#include <sofa/component/constraint/LinearMovementConstraint.h>
#include <sofa/helper/gl/template.h>
#include <sofa/defaulttype/RigidTypes.h>
#include <iostream>

#include <sofa/component/topology/PointSubset.h>

using std::cerr;
using std::endl;

namespace sofa
{

namespace component
{

namespace constraint
{

using namespace core::componentmodel::topology;

using namespace sofa::defaulttype;
using namespace sofa::helper;
using namespace sofa::core::componentmodel::behavior;

// Define TestNewPointFunction
template< class DataTypes>
bool LinearMovementConstraint<DataTypes>::FCTestNewPointFunction(int /*nbPoints*/, void* param, const sofa::helper::vector< unsigned int > &, const sofa::helper::vector< double >& )
{
    LinearMovementConstraint<DataTypes> *fc= (LinearMovementConstraint<DataTypes> *)param;
    if (fc)
    {
        return true;
    }
    else
    {
        return false;
    }
}

// Define RemovalFunction
template< class DataTypes>
void LinearMovementConstraint<DataTypes>::FCRemovalFunction(int pointIndex, void* param)
{
    LinearMovementConstraint<DataTypes> *fc= (LinearMovementConstraint<DataTypes> *)param;
    if (fc)
    {
        fc->removeIndex((unsigned int) pointIndex);
    }
    return;
}

template <class DataTypes>
LinearMovementConstraint<DataTypes>::LinearMovementConstraint()
    : core::componentmodel::behavior::Constraint<DataTypes>(NULL)
    , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
    , m_keyTimes(  initData(&m_keyTimes,"keyTimes","key times for the movements") )
    , m_keyMovements(  initData(&m_keyMovements,"movements","movements corresponding to the key times") )
{
    // default to indice 0
    m_indices.beginEdit()->push_back(0);
    m_indices.endEdit();

    //default valueEvent to 0
    m_keyTimes.beginEdit()->push_back( 0.0 );
    m_keyTimes.endEdit();
    m_keyMovements.beginEdit()->push_back( Deriv() );
    m_keyMovements.endEdit();
}

// Handle topological changes
template <class DataTypes> void LinearMovementConstraint<DataTypes>::handleTopologyChange()
{
    std::list<const TopologyChange *>::const_iterator itBegin=topology->firstChange();
    std::list<const TopologyChange *>::const_iterator itEnd=topology->lastChange();

    m_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize());

}

template <class DataTypes>
LinearMovementConstraint<DataTypes>::~LinearMovementConstraint()
{
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::clearIndices()
{
    m_indices.beginEdit()->clear();
    m_indices.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::addIndex(unsigned int index)
{
    m_indices.beginEdit()->push_back(index);
    m_indices.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::removeIndex(unsigned int index)
{
    removeValue(*m_indices.beginEdit(),index);
    m_indices.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::clearKeyMovements()
{
    m_keyTimes.beginEdit()->clear();
    m_keyTimes.endEdit();
    m_keyMovements.beginEdit()->clear();
    m_keyMovements.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::addKeyMovement(Real time, Deriv movement)
{
    m_keyTimes.beginEdit()->push_back( time );
    m_keyTimes.endEdit();
    m_keyMovements.beginEdit()->push_back( movement );
    m_keyMovements.endEdit();
}

// -- Constraint interface

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::init()
{
    this->core::componentmodel::behavior::Constraint<DataTypes>::init();

    topology = getContext()->getMeshTopology();

    // Initialize functions and parameters
    topology::PointSubset my_subset = m_indices.getValue();

    my_subset.setTestFunction(FCTestNewPointFunction);
    my_subset.setRemovalFunction(FCRemovalFunction);

    my_subset.setTestParameter( (void *) this );
    my_subset.setRemovalParameter( (void *) this );

    x0.resize(0);
    nextM = prevM = Deriv();

}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::projectResponse(VecDeriv& )
{

}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::projectVelocity(VecDeriv& dx)
{
    Real cT = (Real) this->getContext()->getTime();
    if(cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin())
    {
        const SetIndexArray & indices = m_indices.getValue().getArray();

        bool finished=false;

        typename helper::vector<Real>::const_iterator it_t = m_keyTimes.getValue().begin();
        typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin();

        //WARNING : we consider that the key-events are in chronological order
        //here we search between which keyTimes we are, to know which are the motion to interpolate
        while( it_t != m_keyTimes.getValue().end() && !finished)
        {
            if( *it_t <= cT)
            {
                prevT = *it_t;
                prevM = *it_m;
            }
            else
            {
                nextT = *it_t;
                nextM = *it_m;
                finished = true;
            }
            it_t++;
            it_m++;
        }

        //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation)
        if(finished)
        {
            Real dTsimu = (Real) this->getContext()->getDt();
            Real dt = (cT - prevT) / (nextT - prevT);
            Deriv m= (nextM-prevM)*dt;
            Deriv mPrev= (nextM-prevM)*(((cT-dTsimu) - prevT) / (nextT - prevT));

            //set the motion to the Dofs
            for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
            {
                dx[*it] = (m - mPrev) * (1/dTsimu);
            }
        }
    }
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::projectPosition(VecCoord& x)
{
    Real cT = (Real) this->getContext()->getTime();

    //initialize initial Dofs positions, if it's not done
    if (x0.size() == 0)
    {
        const SetIndexArray & indices = m_indices.getValue().getArray();
        x0.resize( x.size() );
        for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
            x0[*it] = x[*it];
    }

    //if we found 2 keyTimes, we have to interpolate a position (linear interpolation)
    if(cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin() && nextT!=prevT)
    {
        const SetIndexArray & indices = m_indices.getValue().getArray();

        Real dt = (cT - prevT) / (nextT - prevT);
        Deriv m = prevM + (nextM-prevM)*dt;

        //set the motion to the Dofs
        for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
        {
            x[*it] = x0[*it] + m ;
        }
    }
}

//display the path the constrained dofs will go through
template <class DataTypes>
void LinearMovementConstraint<DataTypes>::draw()
{
    if (!getContext()->
        getShowBehaviorModels()) return;
    glDisable (GL_LIGHTING);
    glPointSize(10);
    glColor4f (1,0.5,0.5,1);
    glBegin (GL_LINES);
    const SetIndexArray & indices = m_indices.getValue().getArray();
    for (unsigned int i=0 ; i<m_keyMovements.getValue().size()-1 ; i++)
    {
        for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
        {
            gl::glVertexT(x0[*it]+m_keyMovements.getValue()[i]);
            gl::glVertexT(x0[*it]+m_keyMovements.getValue()[i+1]);
        }
    }
    glEnd();
}

// Specialization for rigids
template <>
void LinearMovementConstraint<Rigid3dTypes >::draw();
template <>
void LinearMovementConstraint<Rigid3fTypes >::draw();

} // namespace constraint

} // namespace component

} // namespace sofa

#endif

<commit_msg>r3021/sofa-dev : Fix : little bug in LinearMovementConstraint<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library 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 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library 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.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_CONSTRAINT_LINEARMOVEMENTCONSTRAINT_INL
#define SOFA_COMPONENT_CONSTRAINT_LINEARMOVEMENTCONSTRAINT_INL

#include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
#include <sofa/core/componentmodel/behavior/Constraint.inl>
#include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
#include <sofa/component/constraint/LinearMovementConstraint.h>
#include <sofa/helper/gl/template.h>
#include <sofa/defaulttype/RigidTypes.h>
#include <iostream>

#include <sofa/component/topology/PointSubset.h>

using std::cerr;
using std::endl;

namespace sofa
{

namespace component
{

namespace constraint
{

using namespace core::componentmodel::topology;

using namespace sofa::defaulttype;
using namespace sofa::helper;
using namespace sofa::core::componentmodel::behavior;

// Define TestNewPointFunction
template< class DataTypes>
bool LinearMovementConstraint<DataTypes>::FCTestNewPointFunction(int /*nbPoints*/, void* param, const sofa::helper::vector< unsigned int > &, const sofa::helper::vector< double >& )
{
    LinearMovementConstraint<DataTypes> *fc= (LinearMovementConstraint<DataTypes> *)param;
    if (fc)
    {
        return true;
    }
    else
    {
        return false;
    }
}

// Define RemovalFunction
template< class DataTypes>
void LinearMovementConstraint<DataTypes>::FCRemovalFunction(int pointIndex, void* param)
{
    LinearMovementConstraint<DataTypes> *fc= (LinearMovementConstraint<DataTypes> *)param;
    if (fc)
    {
        fc->removeIndex((unsigned int) pointIndex);
    }
    return;
}

template <class DataTypes>
LinearMovementConstraint<DataTypes>::LinearMovementConstraint()
    : core::componentmodel::behavior::Constraint<DataTypes>(NULL)
    , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
    , m_keyTimes(  initData(&m_keyTimes,"keyTimes","key times for the movements") )
    , m_keyMovements(  initData(&m_keyMovements,"movements","movements corresponding to the key times") )
{
    // default to indice 0
    m_indices.beginEdit()->push_back(0);
    m_indices.endEdit();

    //default valueEvent to 0
    m_keyTimes.beginEdit()->push_back( 0.0 );
    m_keyTimes.endEdit();
    m_keyMovements.beginEdit()->push_back( Deriv() );
    m_keyMovements.endEdit();
}

// Handle topological changes
template <class DataTypes> void LinearMovementConstraint<DataTypes>::handleTopologyChange()
{
    std::list<const TopologyChange *>::const_iterator itBegin=topology->firstChange();
    std::list<const TopologyChange *>::const_iterator itEnd=topology->lastChange();

    m_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize());

}

template <class DataTypes>
LinearMovementConstraint<DataTypes>::~LinearMovementConstraint()
{
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::clearIndices()
{
    m_indices.beginEdit()->clear();
    m_indices.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::addIndex(unsigned int index)
{
    m_indices.beginEdit()->push_back(index);
    m_indices.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::removeIndex(unsigned int index)
{
    removeValue(*m_indices.beginEdit(),index);
    m_indices.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::clearKeyMovements()
{
    m_keyTimes.beginEdit()->clear();
    m_keyTimes.endEdit();
    m_keyMovements.beginEdit()->clear();
    m_keyMovements.endEdit();
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::addKeyMovement(Real time, Deriv movement)
{
    m_keyTimes.beginEdit()->push_back( time );
    m_keyTimes.endEdit();
    m_keyMovements.beginEdit()->push_back( movement );
    m_keyMovements.endEdit();
}

// -- Constraint interface

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::init()
{
    this->core::componentmodel::behavior::Constraint<DataTypes>::init();

    topology = getContext()->getMeshTopology();

    // Initialize functions and parameters
    topology::PointSubset my_subset = m_indices.getValue();

    my_subset.setTestFunction(FCTestNewPointFunction);
    my_subset.setRemovalFunction(FCRemovalFunction);

    my_subset.setTestParameter( (void *) this );
    my_subset.setRemovalParameter( (void *) this );

    x0.resize(0);
    nextM = prevM = Deriv();

}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::projectResponse(VecDeriv& )
{

}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::projectVelocity(VecDeriv& dx)
{
    Real cT = (Real) this->getContext()->getTime();
    if(m_keyTimes.getValue().size() != 0 && cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin())
    {
        const SetIndexArray & indices = m_indices.getValue().getArray();

        bool finished=false;

        typename helper::vector<Real>::const_iterator it_t = m_keyTimes.getValue().begin();
        typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin();

        //WARNING : we consider that the key-events are in chronological order
        //here we search between which keyTimes we are, to know which are the motion to interpolate
        while( it_t != m_keyTimes.getValue().end() && !finished)
        {
            if( *it_t <= cT)
            {
                prevT = *it_t;
                prevM = *it_m;
            }
            else
            {
                nextT = *it_t;
                nextM = *it_m;
                finished = true;
            }
            it_t++;
            it_m++;
        }

        //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation)
        if(finished)
        {
            Real dTsimu = (Real) this->getContext()->getDt();
            Real dt = (cT - prevT) / (nextT - prevT);
            Deriv m= (nextM-prevM)*dt;
            Deriv mPrev= (nextM-prevM)*(((cT-dTsimu) - prevT) / (nextT - prevT));

            //set the motion to the Dofs
            for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
            {
                dx[*it] = (m - mPrev) * (1/dTsimu);
            }
        }
    }
}

template <class DataTypes>
void LinearMovementConstraint<DataTypes>::projectPosition(VecCoord& x)
{
    Real cT = (Real) this->getContext()->getTime();

    //initialize initial Dofs positions, if it's not done
    if (x0.size() == 0)
    {
        const SetIndexArray & indices = m_indices.getValue().getArray();
        x0.resize( x.size() );
        for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
            x0[*it] = x[*it];
    }

    //if we found 2 keyTimes, we have to interpolate a position (linear interpolation)
    if(m_keyTimes.getValue().size() != 0 && cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin() && nextT!=prevT)
    {
        const SetIndexArray & indices = m_indices.getValue().getArray();

        Real dt = (cT - prevT) / (nextT - prevT);
        Deriv m = prevM + (nextM-prevM)*dt;

        //set the motion to the Dofs
        for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
        {
            x[*it] = x0[*it] + m ;
        }
    }
}

//display the path the constrained dofs will go through
template <class DataTypes>
void LinearMovementConstraint<DataTypes>::draw()
{
    if (!getContext()->getShowBehaviorModels() || m_keyTimes.getValue().size() == 0 ) return;
    glDisable (GL_LIGHTING);
    glPointSize(10);
    glColor4f (1,0.5,0.5,1);
    glBegin (GL_LINES);
    const SetIndexArray & indices = m_indices.getValue().getArray();
    for (unsigned int i=0 ; i<m_keyMovements.getValue().size()-1 ; i++)
    {
        for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
        {
            gl::glVertexT(x0[*it]+m_keyMovements.getValue()[i]);
            gl::glVertexT(x0[*it]+m_keyMovements.getValue()[i+1]);
        }
    }
    glEnd();
}

// Specialization for rigids
template <>
void LinearMovementConstraint<Rigid3dTypes >::draw();
template <>
void LinearMovementConstraint<Rigid3fTypes >::draw();

} // namespace constraint

} // namespace component

} // namespace sofa

#endif

<|endoftext|>


<commit_before>/*!
    \file string_encoding.cpp
    \brief Encoding utilities example
    \author Ivan Shynkarenka
    \date 13.08.2016
    \copyright MIT License
*/

#include "string/encoding.h"

#include <iostream>

#if defined(unix) || defined(__unix) || defined(__unix__)
#include <locale.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <fcntl.h>
#include <io.h>
#endif

int main(int argc, char** argv)
{
    // Allow the console to output Unicode strings using std::wcout
#if defined(unix) || defined(__unix) || defined(__unix__)
    setlocale(LC_ALL, "");
#elif defined(_WIN32) || defined(_WIN64)
    _setmode(_fileno(stdout), _O_U16TEXT);
#endif

    std::string utf8 = "\xD0\x9F\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\x20\xD0\xBC\xD0\xB8\xD1\x80\x21";
    std::wstring sys = CppCommon::Encoding::FromUTF8(utf8);
    std::wcout << sys << std::endl;
    return 0;
}
<commit_msg>Fix Unicode console output<commit_after>/*!
    \file string_encoding.cpp
    \brief Encoding utilities example
    \author Ivan Shynkarenka
    \date 13.08.2016
    \copyright MIT License
*/

#include "string/encoding.h"

#include <iostream>

#if defined(unix) || defined(__unix) || defined(__unix__)
#include <locale.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <fcntl.h>
#include <io.h>
#include <windows.h>
#define CP_UTF16 65002
#endif

int main(int argc, char** argv)
{
    // Allow the console to output Unicode strings using std::wcout
#if defined(unix) || defined(__unix) || defined(__unix__)
    setlocale(LC_ALL, "");
#elif defined(_WIN32) || defined(_WIN64)
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);
    SetConsoleCP(CP_UTF16);
    SetConsoleOutputCP(CP_UTF16);
#endif

    std::string utf8 = "\xD0\x9F\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\x20\xD0\xBC\xD0\xB8\xD1\x80\x21";
    std::wstring sys = CppCommon::Encoding::FromUTF8(utf8);
    std::wcout << sys << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>#include "leap.h"
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(a_known_leap_year)
{
    BOOST_REQUIRE(leap::is_leap_year(1996));
}

#if defined(EXERCISM_RUN_ALL_TESTS)
BOOST_AUTO_TEST_CASE(any_old_year)
{
    BOOST_REQUIRE(!leap::is_leap_year(1997));
}

BOOST_AUTO_TEST_CASE(turn_of_the_20th_century)
{
    BOOST_REQUIRE(!leap::is_leap_year(1900));
}

BOOST_AUTO_TEST_CASE(turn_of_the_21st_century)
{
    BOOST_REQUIRE(leap::is_leap_year(2000));
}

BOOST_AUTO_TEST_CASE(turn_of_the_25th_century)
{
    BOOST_REQUIRE(leap::is_leap_year(2400));;
}
#endif
<commit_msg>leap: remove extra semicolon<commit_after>#include "leap.h"
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(a_known_leap_year)
{
    BOOST_REQUIRE(leap::is_leap_year(1996));
}

#if defined(EXERCISM_RUN_ALL_TESTS)
BOOST_AUTO_TEST_CASE(any_old_year)
{
    BOOST_REQUIRE(!leap::is_leap_year(1997));
}

BOOST_AUTO_TEST_CASE(turn_of_the_20th_century)
{
    BOOST_REQUIRE(!leap::is_leap_year(1900));
}

BOOST_AUTO_TEST_CASE(turn_of_the_21st_century)
{
    BOOST_REQUIRE(leap::is_leap_year(2000));
}

BOOST_AUTO_TEST_CASE(turn_of_the_25th_century)
{
    BOOST_REQUIRE(leap::is_leap_year(2400));
}
#endif
<|endoftext|>


<commit_before>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Ensure that Python.h is included before any other header in Python debuglet.
#include "common.h"

#include "leaky_bucket.h"

#include "third_party/absl/time/clock.h"
#include "third_party/absl/time/time.h"

#ifndef NACL_BUILD
#include <sys/time.h>
#include <time.h>
#else   // NACL_BUILD
#include "third_party/apphosting/nacl/chromium/base/time.h"
#endif  // NACL_BUILD

#include <algorithm>
#include <limits>

namespace devtools {
namespace cdbg {

static int64 NowInNanoseconds() {
#ifndef NACL_BUILD
  timespec time;
  clock_gettime(CLOCK_MONOTONIC, &time);
  return 1000000000LL * time.tv_sec + time.tv_nsec;
#else   // NACL_BUILD
  return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds() * 1000;
#endif  // NACL_BUILD
}

LeakyBucket::LeakyBucket(int64 capacity, int64 fill_rate)
    : capacity_(capacity),
      fractional_tokens_(0.0),
      fill_rate_(fill_rate),
      fill_time_ns_(NowInNanoseconds()) {
  tokens_ = capacity;
}

bool LeakyBucket::RequestTokensSlow(int64 requested_tokens) {
  // Getting the time outside the lock is significantly faster (reduces
  // contention, etc.).
  const int64 current_time_ns = NowInNanoseconds();

  std::lock_guard<std::mutex> lock(mu_);

  const int64 cur_tokens = AtomicLoadTokens();
  if (cur_tokens >= 0) {
    return true;
  }

  const int64 available_tokens =
      RefillBucket(requested_tokens + cur_tokens, current_time_ns);
  if (available_tokens >= 0) {
    return true;
  }

  // Since we were unable to satisfy the request, we need to restore the
  // requested tokens.
  AtomicIncrementTokens(requested_tokens);

  return false;
}

int64 LeakyBucket::RefillBucket(
    int64 available_tokens,
    int64 current_time_ns) {
  if (current_time_ns <= fill_time_ns_) {
    // We check to see if the bucket has been refilled after we checked the
    // current time but before we grabbed mu_. If it has there's nothing to do.
    return AtomicLoadTokens();
  }

  const int64 elapsed_ns = current_time_ns - fill_time_ns_;
  fill_time_ns_ = current_time_ns;

  // Calculate the number of tokens we can add. Note elapsed is in ns while
  // fill_rate_ is in tokens per second, hence the scaling factor.
  // We can get a negative amount of tokens by calling TakeTokens. Make sure we
  // don't add more than the capacity of leaky bucket.
  fractional_tokens_ +=
      std::min(elapsed_ns * (fill_rate_ / 1e9), static_cast<double>(capacity_));
  const int64 ideal_tokens_to_add = fractional_tokens_;

  const int64 max_tokens_to_add = capacity_ - available_tokens;
  int64 real_tokens_to_add;
  if (max_tokens_to_add < ideal_tokens_to_add) {
    fractional_tokens_ = 0.0;
    real_tokens_to_add = max_tokens_to_add;
  } else {
    real_tokens_to_add = ideal_tokens_to_add;
    fractional_tokens_ -= real_tokens_to_add;
  }

  return AtomicIncrementTokens(real_tokens_to_add);
}

void LeakyBucket::TakeTokens(int64 tokens) {
  const int64 remaining = AtomicIncrementTokens(-tokens);

  if (remaining < 0) {
    // (Try to) refill the bucket. If we don't do this, we could just
    // keep decreasing forever without refilling. We need to be
    // refilling at least as frequently as every capacity_ /
    // fill_rate_ seconds. Otherwise, we waste tokens.
    const int64 current_time_ns = NowInNanoseconds();

    std::lock_guard<std::mutex> lock(mu_);
    RefillBucket(remaining, current_time_ns);
  }
}

}  // namespace cdbg
}  // namespace devtools
<commit_msg>Rolling back build breaking change<commit_after>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Ensure that Python.h is included before any other header in Python debuglet.
#include "common.h"

#include "leaky_bucket.h"

#ifndef NACL_BUILD
#include <sys/time.h>
#include <time.h>
#else   // NACL_BUILD
#include "third_party/apphosting/nacl/chromium/base/time.h"
#endif  // NACL_BUILD

#include <algorithm>
#include <limits>

namespace devtools {
namespace cdbg {

static int64 NowInNanoseconds() {
#ifndef NACL_BUILD
  timespec time;
  clock_gettime(CLOCK_MONOTONIC, &time);
  return 1000000000LL * time.tv_sec + time.tv_nsec;
#else   // NACL_BUILD
  return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds() * 1000;
#endif  // NACL_BUILD
}

LeakyBucket::LeakyBucket(int64 capacity, int64 fill_rate)
    : capacity_(capacity),
      fractional_tokens_(0.0),
      fill_rate_(fill_rate),
      fill_time_ns_(NowInNanoseconds()) {
  tokens_ = capacity;
}

bool LeakyBucket::RequestTokensSlow(int64 requested_tokens) {
  // Getting the time outside the lock is significantly faster (reduces
  // contention, etc.).
  const int64 current_time_ns = NowInNanoseconds();

  std::lock_guard<std::mutex> lock(mu_);

  const int64 cur_tokens = AtomicLoadTokens();
  if (cur_tokens >= 0) {
    return true;
  }

  const int64 available_tokens =
      RefillBucket(requested_tokens + cur_tokens, current_time_ns);
  if (available_tokens >= 0) {
    return true;
  }

  // Since we were unable to satisfy the request, we need to restore the
  // requested tokens.
  AtomicIncrementTokens(requested_tokens);

  return false;
}

int64 LeakyBucket::RefillBucket(
    int64 available_tokens,
    int64 current_time_ns) {
  if (current_time_ns <= fill_time_ns_) {
    // We check to see if the bucket has been refilled after we checked the
    // current time but before we grabbed mu_. If it has there's nothing to do.
    return AtomicLoadTokens();
  }

  const int64 elapsed_ns = current_time_ns - fill_time_ns_;
  fill_time_ns_ = current_time_ns;

  // Calculate the number of tokens we can add. Note elapsed is in ns while
  // fill_rate_ is in tokens per second, hence the scaling factor.
  // We can get a negative amount of tokens by calling TakeTokens. Make sure we
  // don't add more than the capacity of leaky bucket.
  fractional_tokens_ +=
      std::min(elapsed_ns * (fill_rate_ / 1e9), static_cast<double>(capacity_));
  const int64 ideal_tokens_to_add = fractional_tokens_;

  const int64 max_tokens_to_add = capacity_ - available_tokens;
  int64 real_tokens_to_add;
  if (max_tokens_to_add < ideal_tokens_to_add) {
    fractional_tokens_ = 0.0;
    real_tokens_to_add = max_tokens_to_add;
  } else {
    real_tokens_to_add = ideal_tokens_to_add;
    fractional_tokens_ -= real_tokens_to_add;
  }

  return AtomicIncrementTokens(real_tokens_to_add);
}

void LeakyBucket::TakeTokens(int64 tokens) {
  const int64 remaining = AtomicIncrementTokens(-tokens);

  if (remaining < 0) {
    // (Try to) refill the bucket. If we don't do this, we could just
    // keep decreasing forever without refilling. We need to be
    // refilling at least as frequently as every capacity_ /
    // fill_rate_ seconds. Otherwise, we waste tokens.
    const int64 current_time_ns = NowInNanoseconds();

    std::lock_guard<std::mutex> lock(mu_);
    RefillBucket(remaining, current_time_ns);
  }
}

}  // namespace cdbg
}  // namespace devtools
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library 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 2 of the License, or (at your option) any later version.
//
//  This library 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.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "ParallelAnim.h"

#include "../player/Player.h"

using namespace boost::python;
using namespace std;

namespace avg {

ParallelAnim::ParallelAnim(const vector<AnimPtr>& anims,
            const object& startCallback, const object& stopCallback, long long maxAge)
    : Anim(startCallback, stopCallback),
      m_Anims(anims),
      m_MaxAge(maxAge)
{
    vector<AnimPtr>::iterator it;
    for (it=m_Anims.begin(); it != m_Anims.end(); ++it) {
        (*it)->setHasParent();
    }
}

ParallelAnim::~ParallelAnim()
{
}

AnimPtr ParallelAnim::create(const vector<AnimPtr>& anims,
            const object& startCallback, const object& stopCallback,
            long long maxAge)
{
    return AnimPtr(new ParallelAnim(anims, startCallback, stopCallback, maxAge));
}

void ParallelAnim::start(bool bKeepAttr)
{
    Anim::start();
    m_StartTime = Player::get()->getFrameTime();

    vector<AnimPtr>::iterator it;
    for (it=m_Anims.begin(); it != m_Anims.end(); ++it) {
        (*it)->start(bKeepAttr);
    }
    m_RunningAnims = m_Anims;
}

void ParallelAnim::abort()
{
    if (isRunning()) {
        vector<AnimPtr>::iterator it;
        for (it=m_RunningAnims.begin(); it != m_RunningAnims.end(); ++it) {
            (*it)->abort();
        }
        m_RunningAnims.clear();
        setStopped();
    }
}

bool ParallelAnim::step()
{
    assert(isRunning());
    vector<AnimPtr>::iterator it;
    for (it=m_RunningAnims.begin(); it != m_RunningAnims.end(); ++it) {
        bool bDone = (*it)->step();
        if (bDone) {
            vector<AnimPtr>::iterator delIt = it;
            --it;
            m_RunningAnims.erase(delIt);
        }
    }
    if (m_RunningAnims.empty()) {
        setStopped();
        return true;
    }
    if (m_MaxAge != -1 && Player::get()->getFrameTime()-m_StartTime >= m_MaxAge) {
        abort();
    }
}

}
<commit_msg>Fixed bug in child ParallelAnims.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library 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 2 of the License, or (at your option) any later version.
//
//  This library 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.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "ParallelAnim.h"

#include "../player/Player.h"

using namespace boost::python;
using namespace std;

namespace avg {

ParallelAnim::ParallelAnim(const vector<AnimPtr>& anims,
            const object& startCallback, const object& stopCallback, long long maxAge)
    : Anim(startCallback, stopCallback),
      m_Anims(anims),
      m_MaxAge(maxAge)
{
    vector<AnimPtr>::iterator it;
    for (it=m_Anims.begin(); it != m_Anims.end(); ++it) {
        (*it)->setHasParent();
    }
}

ParallelAnim::~ParallelAnim()
{
}

AnimPtr ParallelAnim::create(const vector<AnimPtr>& anims,
            const object& startCallback, const object& stopCallback,
            long long maxAge)
{
    return AnimPtr(new ParallelAnim(anims, startCallback, stopCallback, maxAge));
}

void ParallelAnim::start(bool bKeepAttr)
{
    Anim::start();
    m_StartTime = Player::get()->getFrameTime();

    vector<AnimPtr>::iterator it;
    for (it=m_Anims.begin(); it != m_Anims.end(); ++it) {
        (*it)->start(bKeepAttr);
    }
    m_RunningAnims = m_Anims;
}

void ParallelAnim::abort()
{
    if (isRunning()) {
        vector<AnimPtr>::iterator it;
        for (it=m_RunningAnims.begin(); it != m_RunningAnims.end(); ++it) {
            (*it)->abort();
        }
        m_RunningAnims.clear();
        setStopped();
    }
}

bool ParallelAnim::step()
{
    assert(isRunning());
    vector<AnimPtr>::iterator it;
    for (it=m_RunningAnims.begin(); it != m_RunningAnims.end(); ++it) {
        bool bDone = (*it)->step();
        if (bDone) {
            vector<AnimPtr>::iterator delIt = it;
            --it;
            m_RunningAnims.erase(delIt);
        }
    }
    if (m_RunningAnims.empty()) {
        setStopped();
        return true;
    }
    if (m_MaxAge != -1 && Player::get()->getFrameTime()-m_StartTime >= m_MaxAge) {
        abort();
        return true;
    }
    return false;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "chrome/browser/sync/notifier/chrome_invalidation_client.h"
#include "chrome/browser/sync/notifier/state_writer.h"
#include "jingle/notifier/base/fake_base_task.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace sync_notifier {

using ::testing::_;
using ::testing::Return;

class MockListener : public ChromeInvalidationClient::Listener {
 public:
  MOCK_METHOD1(OnInvalidate, void(syncable::ModelType));
  MOCK_METHOD0(OnInvalidateAll, void());
};

class MockStateWriter : public StateWriter {
 public:
  MOCK_METHOD1(WriteState, void(const std::string&));
};

class MockInvalidationClient : public invalidation::InvalidationClient {
 public:
  MOCK_METHOD1(Start, void(const std::string& str));
  MOCK_METHOD1(Register, void(const invalidation::ObjectId&));
  MOCK_METHOD1(Unregister, void(const invalidation::ObjectId&));
  MOCK_METHOD0(network_endpoint, invalidation::NetworkEndpoint*());
};

namespace {
const char kClientId[] = "client_id";
const char kState[] = "state";
}  // namespace

class ChromeInvalidationClientTest : public testing::Test {
 protected:
  virtual void SetUp() {
    client_.Start(kClientId, kState, &mock_listener_, &mock_state_writer_,
                  fake_base_task_.AsWeakPtr());
  }

  virtual void TearDown() {
    client_.Stop();
    message_loop_.RunAllPending();
  }

  // Simulates DoInformOutboundListener() from network-manager.cc.
  virtual void SimulateInformOutboundListener() {
    // Explicitness hack here to work around broken callback
    // implementations.
    void (invalidation::NetworkCallback::*run_function)(
        invalidation::NetworkEndpoint* const&) =
        &invalidation::NetworkCallback::Run;

    client_.chrome_system_resources_.ScheduleOnListenerThread(
        invalidation::NewPermanentCallback(
            client_.handle_outbound_packet_callback_.get(), run_function,
            client_.invalidation_client_->network_endpoint()));
  }

  MessageLoop message_loop_;
  MockListener mock_listener_;
  MockStateWriter mock_state_writer_;
  notifier::FakeBaseTask fake_base_task_;
  ChromeInvalidationClient client_;
};

// Outbound packet sending should be resilient to
// changing/disappearing base tasks.
TEST_F(ChromeInvalidationClientTest, OutboundPackets) {
  SimulateInformOutboundListener();

  notifier::FakeBaseTask fake_base_task;
  client_.ChangeBaseTask(fake_base_task.AsWeakPtr());

  SimulateInformOutboundListener();

  {
    notifier::FakeBaseTask fake_base_task2;
    client_.ChangeBaseTask(fake_base_task2.AsWeakPtr());
  }

  SimulateInformOutboundListener();
}

// TODO(akalin): Flesh out unit tests.

}  // namespace sync_notifier
<commit_msg>[Sync] Added missing include<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/message_loop.h"
#include "chrome/browser/sync/notifier/chrome_invalidation_client.h"
#include "chrome/browser/sync/notifier/state_writer.h"
#include "jingle/notifier/base/fake_base_task.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace sync_notifier {

using ::testing::_;
using ::testing::Return;

class MockListener : public ChromeInvalidationClient::Listener {
 public:
  MOCK_METHOD1(OnInvalidate, void(syncable::ModelType));
  MOCK_METHOD0(OnInvalidateAll, void());
};

class MockStateWriter : public StateWriter {
 public:
  MOCK_METHOD1(WriteState, void(const std::string&));
};

class MockInvalidationClient : public invalidation::InvalidationClient {
 public:
  MOCK_METHOD1(Start, void(const std::string& str));
  MOCK_METHOD1(Register, void(const invalidation::ObjectId&));
  MOCK_METHOD1(Unregister, void(const invalidation::ObjectId&));
  MOCK_METHOD0(network_endpoint, invalidation::NetworkEndpoint*());
};

namespace {
const char kClientId[] = "client_id";
const char kState[] = "state";
}  // namespace

class ChromeInvalidationClientTest : public testing::Test {
 protected:
  virtual void SetUp() {
    client_.Start(kClientId, kState, &mock_listener_, &mock_state_writer_,
                  fake_base_task_.AsWeakPtr());
  }

  virtual void TearDown() {
    client_.Stop();
    message_loop_.RunAllPending();
  }

  // Simulates DoInformOutboundListener() from network-manager.cc.
  virtual void SimulateInformOutboundListener() {
    // Explicitness hack here to work around broken callback
    // implementations.
    void (invalidation::NetworkCallback::*run_function)(
        invalidation::NetworkEndpoint* const&) =
        &invalidation::NetworkCallback::Run;

    client_.chrome_system_resources_.ScheduleOnListenerThread(
        invalidation::NewPermanentCallback(
            client_.handle_outbound_packet_callback_.get(), run_function,
            client_.invalidation_client_->network_endpoint()));
  }

  MessageLoop message_loop_;
  MockListener mock_listener_;
  MockStateWriter mock_state_writer_;
  notifier::FakeBaseTask fake_base_task_;
  ChromeInvalidationClient client_;
};

// Outbound packet sending should be resilient to
// changing/disappearing base tasks.
TEST_F(ChromeInvalidationClientTest, OutboundPackets) {
  SimulateInformOutboundListener();

  notifier::FakeBaseTask fake_base_task;
  client_.ChangeBaseTask(fake_base_task.AsWeakPtr());

  SimulateInformOutboundListener();

  {
    notifier::FakeBaseTask fake_base_task2;
    client_.ChangeBaseTask(fake_base_task2.AsWeakPtr());
  }

  SimulateInformOutboundListener();
}

// TODO(akalin): Flesh out unit tests.

}  // namespace sync_notifier
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2008 The Florida State University
 * Copyright (c) 2009 The University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use 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 holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
 * OWNER 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.
 */

#ifndef __POWER_PROCESS_HH__
#define __POWER_PROCESS_HH__

#include "sim/process.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Loader, loader);
namespace loader
{
class ObjectFile;
} // namespace loader

class PowerProcess : public Process
{
  protected:
    void initState() override;

  public:
    PowerProcess(const ProcessParams &params, loader::ObjectFile *objFile);

    template <typename IntType>
    void argsInit(int pageSize);
};

} // namespace gem5

#endif // __POWER_PROCESS_HH__
<commit_msg>arch-power: Add hardware features<commit_after>/*
 * Copyright (c) 2007-2008 The Florida State University
 * Copyright (c) 2009 The University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use 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 holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
 * OWNER 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.
 */

#ifndef __POWER_PROCESS_HH__
#define __POWER_PROCESS_HH__

#include "sim/process.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Loader, loader);
namespace loader
{
class ObjectFile;
} // namespace loader

class PowerProcess : public Process
{
  protected:
    void initState() override;

  public:
    PowerProcess(const ProcessParams &params, loader::ObjectFile *objFile);

    template <typename IntType>
    void argsInit(int pageSize);
};

} // namespace gem5

enum PowerHWCAPFeature
{
    HWCAP_FEATURE_32 = 1ULL << 31,            // Always set for powerpc64
    HWCAP_FEATURE_64 = 1ULL << 30,            // Always set for powerpc64
    HWCAP_FEATURE_HAS_ALTIVEC = 1ULL << 28,
    HWCAP_FEATURE_HAS_FPU = 1ULL << 27,
    HWCAP_FEATURE_HAS_MMU = 1ULL << 26,
    HWCAP_FEATURE_UNIFIED_CACHE = 1ULL << 24,
    HWCAP_FEATURE_NO_TB = 1ULL << 20,         // 601/403gx have no timebase
    HWCAP_FEATURE_POWER4 = 1ULL << 19,        // POWER4 ISA 2.00
    HWCAP_FEATURE_POWER5 = 1ULL << 18,        // POWER5 ISA 2.02
    HWCAP_FEATURE_POWER5_PLUS = 1ULL << 17,   // POWER5+ ISA 2.03
    HWCAP_FEATURE_CELL_BE = 1ULL << 16,       // CELL Broadband Engine
    HWCAP_FEATURE_BOOKE = 1ULL << 15,         // ISA Category Embedded
    HWCAP_FEATURE_SMT = 1ULL << 14,           // Simultaneous Multi-Threading
    HWCAP_FEATURE_ICACHE_SNOOP = 1ULL << 13,
    HWCAP_FEATURE_ARCH_2_05 = 1ULL << 12,     // ISA 2.05
    HWCAP_FEATURE_PA6T = 1ULL << 11,          // PA Semi 6T Core
    HWCAP_FEATURE_HAS_DFP = 1ULL << 10,       // Decimal FP Unit
    HWCAP_FEATURE_POWER6_EXT = 1ULL << 9,     // P6 + mffgpr/mftgpr
    HWCAP_FEATURE_ARCH_2_06 = 1ULL << 8,      // ISA 2.06
    HWCAP_FEATURE_HAS_VSX = 1ULL << 7,        // P7 Vector Extension
    HWCAP_FEATURE_PSERIES_PERFMON_COMPAT = 1ULL << 6,
    HWCAP_FEATURE_TRUE_LE = 1ULL << 1,
    HWCAP_FEATURE_PPC_LE = 1ULL << 0
};

enum PowerHWCAP2Feature
{
    HWCAP2_FEATURE_ARCH_2_07 = 1ULL << 31,    // ISA 2.07
    HWCAP2_FEATURE_HAS_HTM = 1ULL << 30,      // Hardware Transactional Memory
    HWCAP2_FEATURE_HAS_DSCR = 1ULL << 29,     // Data Stream Control Register
    HWCAP2_FEATURE_HAS_EBB = 1ULL << 28,      // Event Base Branching
    HWCAP2_FEATURE_HAS_ISEL = 1ULL << 27,     // Integer Select
    HWCAP2_FEATURE_HAS_TAR = 1ULL << 26,      // Target Address Register
    HWCAP2_FEATURE_HAS_VCRYPTO = 1ULL << 25,  // Vector AES category
    HWCAP2_FEATURE_HTM_NOSC = 1ULL << 24,
    HWCAP2_FEATURE_ARCH_3_00 = 1ULL << 23,    // ISA 3.0
    HWCAP2_FEATURE_HAS_IEEE128 = 1ULL << 22,  // VSX IEEE Binary Float 128-bit
};

#endif // __POWER_PROCESS_HH__
<|endoftext|>


<commit_before>/*
    Copyright 2011 Joe Hermaszewski. All rights reserved.

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

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

    2. 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.

    THIS SOFTWARE IS PROVIDED BY JOE HERMASZEWSKI "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 JOE HERMASZEWSKI 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.

    The views and conclusions contained in the software and documentation are those of the
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Joe Hermaszewski.
*/

#include <iostream>

#include <engine/context.hpp>

//#include <engine/effect.hpp>
//#include <parser/parser.hpp>
//#include <parser/effect_factory.hpp>

int main( int argc, char** argv )
{
    JoeLang::Context context;
    if( context.CreateEffectFromString( "technique t; pass pass1{ a= (12+1)/add(9.0, 10); }" ) )
        std::cout << "success\n";
    else
        std::cout << "fail\n";
}
<commit_msg>[~] changed parsing string<commit_after>/*
    Copyright 2011 Joe Hermaszewski. All rights reserved.

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

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

    2. 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.

    THIS SOFTWARE IS PROVIDED BY JOE HERMASZEWSKI "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 JOE HERMASZEWSKI 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.

    The views and conclusions contained in the software and documentation are those of the
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Joe Hermaszewski.
*/

#include <iostream>

#include <engine/context.hpp>

//#include <engine/effect.hpp>
//#include <parser/parser.hpp>
//#include <parser/effect_factory.hpp>

int main( int argc, char** argv )
{
    JoeLang::Context context;
    if( context.CreateEffectFromString( "technique t{ pass p{ a=1; } }" ) )
    {
        std::cout << "success\n";
    }
    else
        std::cout << "fail\n";
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once
#include <af/defines.h>
#include <defines.hpp>
#include <limits>
#include <algorithm>
#include "backend.hpp"
#include "types.hpp"

#ifdef __CUDACC__
#include <math_functions.h>
#include <math_constants.h>
#endif

namespace cuda
{
    template<typename T> static inline __DH__ T abs(T val)  { return abs(val); }
    static inline __DH__ float  abs(float  val) { return fabsf(val); }
    static inline __DH__ double abs(double val) { return fabs (val); }
    static inline __DH__ float  abs(cfloat  cval) { return cuCabsf(cval); }
    static inline __DH__ double abs(cdouble cval) { return cuCabs (cval); }

    static inline __DH__ size_t min(size_t lhs, size_t rhs) { return lhs < rhs ? lhs : rhs; }
    static inline __DH__ size_t max(size_t lhs, size_t rhs) { return lhs > rhs ? lhs : rhs; }

#ifndef __CUDA_ARCH__
    template<typename T> static inline __DH__ T min(T lhs, T rhs) { return std::min(lhs, rhs);}
    template<typename T> static inline __DH__ T max(T lhs, T rhs) { return std::max(lhs, rhs);}
#else
    template<typename T> static inline __DH__ T min(T lhs, T rhs) { return ::min(lhs, rhs);}
    template<typename T> static inline __DH__ T max(T lhs, T rhs) { return ::max(lhs, rhs);}
#endif

    template<> __DH__
    STATIC_ cfloat  max<cfloat >(cfloat lhs, cfloat rhs)
    {
        return abs(lhs) > abs(rhs) ? lhs : rhs;
    }

    template<> __DH__
    STATIC_ cdouble max<cdouble>(cdouble lhs, cdouble rhs)
    {
        return abs(lhs) > abs(rhs) ? lhs : rhs;
    }

    template<> __DH__
    STATIC_ cfloat  min<cfloat >(cfloat lhs, cfloat rhs)
    {
        return abs(lhs) < abs(rhs) ? lhs :  rhs;
    }

    template<> __DH__
    STATIC_ cdouble min<cdouble>(cdouble lhs, cdouble rhs)
    {
        return abs(lhs) < abs(rhs) ? lhs :  rhs;
    }

    template<typename T> __DH__
    static T scalar(double val)
    {
        return (T)(val);
    }

    template<> __DH__
    STATIC_ cfloat scalar<cfloat >(double val)
    {
        cfloat  cval = {(float)val, 0};
        return cval;
    }

    template<> __DH__
    STATIC_ cdouble scalar<cdouble >(double val)
    {
        cdouble  cval = {val, 0};
        return cval;
    }

    template<typename To, typename Ti> __DH__
    static To scalar(Ti real, Ti imag)
    {
        To  cval = {real, imag};
        return cval;
    }

#ifndef __CUDA_ARCH__
    template <typename T> T limit_max() { return std::numeric_limits<T>::max(); }
    template <typename T> T limit_min() { return std::numeric_limits<T>::min(); }
#else
    template <typename T> __device__ T limit_max() { return 1u << (8 * sizeof(T) - 1); }
    template <typename T> __device__ T limit_min() { return scalar<T>(0); }

    template<> __device__  int    limit_max<int>()    { return 0x7fffffff; }
    template<> __device__  int    limit_min<int>()    { return 0x80000000; }
    template<> __device__  intl   limit_max<intl>()   { return 0x7fffffffffffffff; }
    template<> __device__  intl   limit_min<intl>()   { return 0x8000000000000000; }
    template<> __device__  uintl  limit_max<uintl>()  { return 1ULL << (8 * sizeof(uintl) - 1); }
    template<> __device__  char   limit_max<char>()   { return 0x7f; }
    template<> __device__  char   limit_min<char>()   { return 0x80; }
    template<> __device__  float  limit_max<float>()  { return  CUDART_INF_F; }
    template<> __device__  float  limit_min<float>()  { return -CUDART_INF_F; }
    template<> __device__  double limit_max<double>() { return  CUDART_INF; }
    template<> __device__  double limit_min<double>() { return -CUDART_INF; }
    template<> __device__  short  limit_max<short>()  { return 0x7fff; }
    template<> __device__  short  limit_min<short>()  { return 0x8000; }
    template<> __device__  ushort limit_max<ushort>() { return ((ushort)1) << (8 * sizeof(ushort) - 1); }
#endif

#define upcast cuComplexFloatToDouble
#define downcast cuComplexDoubleToFloat

#ifdef __GNUC__
//This suprresses unused function warnings in gcc
//FIXME: Check if the warnings exist in other compilers
#define __SDH__ static __DH__ __attribute__((unused))
#else
#define __SDH__ static __DH__
#endif
__SDH__ float  real(cfloat  c) { return cuCrealf(c); }
__SDH__ double real(cdouble c) { return cuCreal(c);  }

__SDH__ float  imag(cfloat  c) { return cuCimagf(c); }
__SDH__ double imag(cdouble c) { return cuCimag(c);  }

template<typename T> T
__SDH__  conj(T  x) { return x; }
__SDH__ cfloat  conj(cfloat  c) { return cuConjf(c);}
__SDH__ cdouble conj(cdouble c) { return cuConj(c); }

__SDH__ cfloat make_cfloat(bool     x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(int      x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(unsigned x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(short    x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(ushort   x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(float    x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(double   x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(cfloat   x) { return x;                    }
__SDH__ cfloat make_cfloat(cdouble  c) { return make_cuComplex(c.x,c.y); }

__SDH__ cdouble make_cdouble(bool      x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(int       x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(unsigned  x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(short     x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(ushort    x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(float     x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(double    x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(cdouble   x) { return x;                       }
__SDH__ cdouble make_cdouble(cfloat    c) { return make_cuDoubleComplex(c.x,c.y);   }

__SDH__ cfloat make_cfloat(float x, float y) { return make_cuComplex(x, y); }
__SDH__ cdouble make_cdouble(double x, double y) { return make_cuDoubleComplex(x, y); }

#define BINOP(OP, cfn, zfn)                                             \
    __SDH__ cfloat   operator OP(cfloat  a, cfloat  b)                  \
    { return cfn(a,b); }                                                \
    __SDH__ cdouble  operator OP(cdouble a, cfloat  b)                  \
    { return zfn(a,upcast(b)); }                                        \
    __SDH__ cdouble  operator OP(cfloat  a, cdouble b)                  \
    { return zfn(upcast(a),b); }                                        \
    __SDH__ cdouble  operator OP(cdouble a, cdouble b)                  \
    { return zfn(a,b); }                                                \
                                                                        \

    BINOP(+, cuCaddf, cuCadd)
    BINOP(-, cuCsubf, cuCsub)
    BINOP(*, cuCmulf, cuCmul)
    BINOP(/, cuCdivf, cuCdiv)

#undef BINOP

#define BINOP_SCALAR(T, TR, R)                  \
    __SDH__ R operator *(TR a, T b)             \
    { return make_##R(a * b.x, a * b.y); }      \
                                                \
    __SDH__ R operator *(T a, TR b)             \
    { return make_##R(a.x * b,  a.y * b); }     \
                                                \
    __SDH__ R operator +(TR a, T b)             \
    { return make_##R(a + b.x, a + b.y); }      \
                                                \
    __SDH__ R operator +(T a, TR b)             \
    { return make_##R(a.x + b,  a.y + b); }     \
                                                \
    __SDH__ R operator -(TR a, T b)             \
    { return make_##R(a - b.x, a - b.y); }      \
                                                \
    __SDH__ R operator -(T a, TR b)             \
    { return make_##R(a.x - b,  a.y - b); }     \
                                                \
    __SDH__ R operator /(T a, TR b)             \
    { return make_##R(a.x / b, a.y / b); }      \
                                                \
    __SDH__ R operator /(TR a, T b)             \
    { return make_##R(a) / b; }                 \
                                                \

    BINOP_SCALAR(cfloat, float, cfloat)
    BINOP_SCALAR(cfloat, double, cdouble)
    BINOP_SCALAR(cdouble, float, cdouble)
    BINOP_SCALAR(cdouble, double, cdouble)

#undef BINOP_SCALAR

__SDH__ bool operator ==(cfloat a, cfloat b) { return (a.x == b.x) && (a.y == b.y); }
__SDH__ bool operator !=(cfloat a, cfloat b) { return !(a == b); }
__SDH__ bool operator ==(cdouble a, cdouble b) { return (a.x == b.x) && (a.y == b.y); }
__SDH__ bool operator !=(cdouble a, cdouble b) { return !(a == b); }

    template<typename T> static inline T division(T lhs, double rhs) { return lhs / rhs; }
    cfloat division(cfloat lhs, double rhs);
    cdouble division(cdouble lhs, double rhs);
}
<commit_msg>specilizations for abs math function for int & char<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once
#include <af/defines.h>
#include <defines.hpp>
#include <limits>
#include <algorithm>
#include "backend.hpp"
#include "types.hpp"

#ifdef __CUDACC__
#include <math_functions.h>
#include <math_constants.h>
#endif

namespace cuda
{
    template<typename T> static inline __DH__ T abs(T val)  { return abs(val); }
    static inline __DH__ int  abs(int  val) { return (val>0? val : -val); }
    static inline __DH__ char  abs(char  val) { return (val>0? val : -val); }
    static inline __DH__ float  abs(float  val) { return fabsf(val); }
    static inline __DH__ double abs(double val) { return fabs (val); }
    static inline __DH__ float  abs(cfloat  cval) { return cuCabsf(cval); }
    static inline __DH__ double abs(cdouble cval) { return cuCabs (cval); }

    static inline __DH__ size_t min(size_t lhs, size_t rhs) { return lhs < rhs ? lhs : rhs; }
    static inline __DH__ size_t max(size_t lhs, size_t rhs) { return lhs > rhs ? lhs : rhs; }

#ifndef __CUDA_ARCH__
    template<typename T> static inline __DH__ T min(T lhs, T rhs) { return std::min(lhs, rhs);}
    template<typename T> static inline __DH__ T max(T lhs, T rhs) { return std::max(lhs, rhs);}
#else
    template<typename T> static inline __DH__ T min(T lhs, T rhs) { return ::min(lhs, rhs);}
    template<typename T> static inline __DH__ T max(T lhs, T rhs) { return ::max(lhs, rhs);}
#endif

    template<> __DH__
    STATIC_ cfloat  max<cfloat >(cfloat lhs, cfloat rhs)
    {
        return abs(lhs) > abs(rhs) ? lhs : rhs;
    }

    template<> __DH__
    STATIC_ cdouble max<cdouble>(cdouble lhs, cdouble rhs)
    {
        return abs(lhs) > abs(rhs) ? lhs : rhs;
    }

    template<> __DH__
    STATIC_ cfloat  min<cfloat >(cfloat lhs, cfloat rhs)
    {
        return abs(lhs) < abs(rhs) ? lhs :  rhs;
    }

    template<> __DH__
    STATIC_ cdouble min<cdouble>(cdouble lhs, cdouble rhs)
    {
        return abs(lhs) < abs(rhs) ? lhs :  rhs;
    }

    template<typename T> __DH__
    static T scalar(double val)
    {
        return (T)(val);
    }

    template<> __DH__
    STATIC_ cfloat scalar<cfloat >(double val)
    {
        cfloat  cval = {(float)val, 0};
        return cval;
    }

    template<> __DH__
    STATIC_ cdouble scalar<cdouble >(double val)
    {
        cdouble  cval = {val, 0};
        return cval;
    }

    template<typename To, typename Ti> __DH__
    static To scalar(Ti real, Ti imag)
    {
        To  cval = {real, imag};
        return cval;
    }

#ifndef __CUDA_ARCH__
    template <typename T> T limit_max() { return std::numeric_limits<T>::max(); }
    template <typename T> T limit_min() { return std::numeric_limits<T>::min(); }
#else
    template <typename T> __device__ T limit_max() { return 1u << (8 * sizeof(T) - 1); }
    template <typename T> __device__ T limit_min() { return scalar<T>(0); }

    template<> __device__  int    limit_max<int>()    { return 0x7fffffff; }
    template<> __device__  int    limit_min<int>()    { return 0x80000000; }
    template<> __device__  intl   limit_max<intl>()   { return 0x7fffffffffffffff; }
    template<> __device__  intl   limit_min<intl>()   { return 0x8000000000000000; }
    template<> __device__  uintl  limit_max<uintl>()  { return 1ULL << (8 * sizeof(uintl) - 1); }
    template<> __device__  char   limit_max<char>()   { return 0x7f; }
    template<> __device__  char   limit_min<char>()   { return 0x80; }
    template<> __device__  float  limit_max<float>()  { return  CUDART_INF_F; }
    template<> __device__  float  limit_min<float>()  { return -CUDART_INF_F; }
    template<> __device__  double limit_max<double>() { return  CUDART_INF; }
    template<> __device__  double limit_min<double>() { return -CUDART_INF; }
    template<> __device__  short  limit_max<short>()  { return 0x7fff; }
    template<> __device__  short  limit_min<short>()  { return 0x8000; }
    template<> __device__  ushort limit_max<ushort>() { return ((ushort)1) << (8 * sizeof(ushort) - 1); }
#endif

#define upcast cuComplexFloatToDouble
#define downcast cuComplexDoubleToFloat

#ifdef __GNUC__
//This suprresses unused function warnings in gcc
//FIXME: Check if the warnings exist in other compilers
#define __SDH__ static __DH__ __attribute__((unused))
#else
#define __SDH__ static __DH__
#endif
__SDH__ float  real(cfloat  c) { return cuCrealf(c); }
__SDH__ double real(cdouble c) { return cuCreal(c);  }

__SDH__ float  imag(cfloat  c) { return cuCimagf(c); }
__SDH__ double imag(cdouble c) { return cuCimag(c);  }

template<typename T> T
__SDH__  conj(T  x) { return x; }
__SDH__ cfloat  conj(cfloat  c) { return cuConjf(c);}
__SDH__ cdouble conj(cdouble c) { return cuConj(c); }

__SDH__ cfloat make_cfloat(bool     x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(int      x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(unsigned x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(short    x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(ushort   x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(float    x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(double   x) { return make_cuComplex(x,0);     }
__SDH__ cfloat make_cfloat(cfloat   x) { return x;                    }
__SDH__ cfloat make_cfloat(cdouble  c) { return make_cuComplex(c.x,c.y); }

__SDH__ cdouble make_cdouble(bool      x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(int       x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(unsigned  x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(short     x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(ushort    x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(float     x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(double    x) { return make_cuDoubleComplex(x,0);       }
__SDH__ cdouble make_cdouble(cdouble   x) { return x;                       }
__SDH__ cdouble make_cdouble(cfloat    c) { return make_cuDoubleComplex(c.x,c.y);   }

__SDH__ cfloat make_cfloat(float x, float y) { return make_cuComplex(x, y); }
__SDH__ cdouble make_cdouble(double x, double y) { return make_cuDoubleComplex(x, y); }

#define BINOP(OP, cfn, zfn)                                             \
    __SDH__ cfloat   operator OP(cfloat  a, cfloat  b)                  \
    { return cfn(a,b); }                                                \
    __SDH__ cdouble  operator OP(cdouble a, cfloat  b)                  \
    { return zfn(a,upcast(b)); }                                        \
    __SDH__ cdouble  operator OP(cfloat  a, cdouble b)                  \
    { return zfn(upcast(a),b); }                                        \
    __SDH__ cdouble  operator OP(cdouble a, cdouble b)                  \
    { return zfn(a,b); }                                                \
                                                                        \

    BINOP(+, cuCaddf, cuCadd)
    BINOP(-, cuCsubf, cuCsub)
    BINOP(*, cuCmulf, cuCmul)
    BINOP(/, cuCdivf, cuCdiv)

#undef BINOP

#define BINOP_SCALAR(T, TR, R)                  \
    __SDH__ R operator *(TR a, T b)             \
    { return make_##R(a * b.x, a * b.y); }      \
                                                \
    __SDH__ R operator *(T a, TR b)             \
    { return make_##R(a.x * b,  a.y * b); }     \
                                                \
    __SDH__ R operator +(TR a, T b)             \
    { return make_##R(a + b.x, a + b.y); }      \
                                                \
    __SDH__ R operator +(T a, TR b)             \
    { return make_##R(a.x + b,  a.y + b); }     \
                                                \
    __SDH__ R operator -(TR a, T b)             \
    { return make_##R(a - b.x, a - b.y); }      \
                                                \
    __SDH__ R operator -(T a, TR b)             \
    { return make_##R(a.x - b,  a.y - b); }     \
                                                \
    __SDH__ R operator /(T a, TR b)             \
    { return make_##R(a.x / b, a.y / b); }      \
                                                \
    __SDH__ R operator /(TR a, T b)             \
    { return make_##R(a) / b; }                 \
                                                \

    BINOP_SCALAR(cfloat, float, cfloat)
    BINOP_SCALAR(cfloat, double, cdouble)
    BINOP_SCALAR(cdouble, float, cdouble)
    BINOP_SCALAR(cdouble, double, cdouble)

#undef BINOP_SCALAR

__SDH__ bool operator ==(cfloat a, cfloat b) { return (a.x == b.x) && (a.y == b.y); }
__SDH__ bool operator !=(cfloat a, cfloat b) { return !(a == b); }
__SDH__ bool operator ==(cdouble a, cdouble b) { return (a.x == b.x) && (a.y == b.y); }
__SDH__ bool operator !=(cdouble a, cdouble b) { return !(a == b); }

    template<typename T> static inline T division(T lhs, double rhs) { return lhs / rhs; }
    cfloat division(cfloat lhs, double rhs);
    cdouble division(cdouble lhs, double rhs);
}
<|endoftext|>