<commit_before>/** @file   ScriptingManager.cpp
    @author Philip Abbet

    Implementation of the class 'Athena::Scripting::ScriptingManager'
*/

#include <Athena-Scripting/ScriptingManager.h>
#include <Athena-Scripting/Functions.h>
#include <Athena-Core/Log/LogManager.h>
#include <Athena-Core/Utils/StringUtils.h>
#include <Athena-Core/Utils/StringConverter.h>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>

#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
#   define WIN32_LEAN_AND_MEAN
#   include <windows.h>
#else
#   include <dlfcn.h>
#endif

#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
#    define DYNLIB_HANDLE           hInstance
#    define DYNLIB_LOAD( a )        LoadLibraryEx( a, NULL, LOAD_WITH_ALTERED_SEARCH_PATH )
#    define DYNLIB_GETSYM( a, b )   GetProcAddress( a, b )
#    define DYNLIB_UNLOAD( a )      !FreeLibrary( a )

struct HINSTANCE__;
typedef struct HINSTANCE__* hInstance;

#else
#    define DYNLIB_HANDLE           void*
#    define DYNLIB_LOAD( a )        dlopen( a, RTLD_NOW | RTLD_LOCAL )
#    define DYNLIB_GETSYM( a, b )   dlsym( a, b )
#    define DYNLIB_UNLOAD( a )      dlclose( a )

#endif

using namespace Athena::Scripting;
using namespace Athena::Utils;
using namespace Athena::Log;
using namespace std;
using namespace v8;

/************************************** CONSTANTS ***************************************/

/// Context used for logging
static const char* __CONTEXT__ = "Scripting manager";

/********************************** STATIC ATTRIBUTES ***********************************/

/// The instance of the singleton
template<> ScriptingManager* Singleton<ScriptingManager>::ms_Singleton = 0;

/****************************** CONSTRUCTION / DESTRUCTION ******************************/

ScriptingManager::ScriptingManager()
{
    ATHENA_LOG_EVENT("Creation");

    // Create the global template
    HandleScope handle_scope;

    // Create the main context
    m_mainContext = createContext();
}

//-----------------------------------------------------------------------

ScriptingManager::~ScriptingManager()
{
    ATHENA_LOG_EVENT("Destruction");

    // Dispose the main context
    m_mainContext.Dispose();
}

//-----------------------------------------------------------------------

ScriptingManager& ScriptingManager::getSingleton()
{
    assert(ms_Singleton);
    return *ms_Singleton;
}

//-----------------------------------------------------------------------

ScriptingManager* ScriptingManager::getSingletonPtr()
{
    return ms_Singleton;
}

/**************************************** METHODS ***************************************/

Handle<Value> ScriptingManager::execute(const std::string& strScript,
                                        const std::string& strSourceName,
                                        Handle<Context> context)
{
    // Assertions
    assert(!strScript.empty());

    // Initialisations
    m_strLastError = "";

    // Create a stack-allocated handle scope
    HandleScope handle_scope;
    TryCatch trycatch;

    // Retrieve the context to use
    if (context.IsEmpty())
        context = m_mainContext;

    // Enter the context for compiling and running the script
    Context::Scope context_scope(context);

    // Create a string containing the JavaScript source code
    Handle<String> sourceCode = String::New(strScript.c_str(), strScript.size());

    // Create a string containing the origin of the source code
    Handle<String> origin;

    if (!strSourceName.empty())
        origin = String::New(strSourceName.c_str(), strSourceName.size());
    else
        origin = String::New("<unknown>", 9);

    // Compile the source code
    Handle<Script> script = Script::Compile(sourceCode, origin);
    if (script.IsEmpty())
    {
        Handle<Value> exception = trycatch.Exception();
        String::AsciiValue exception_str(exception);
        m_strLastError = *exception_str;
        ATHENA_LOG_ERROR(m_strLastError);
        return Handle<Value>();
    }

    // Run the script to get the result
    Handle<Value> result = script->Run();
    if (result.IsEmpty())
    {
        Handle<Message> message = trycatch.Message();
        m_strLastError = *String::AsciiValue(message->GetScriptResourceName());
        m_strLastError += ":";
        m_strLastError += StringConverter::toString(message->GetLineNumber());
        m_strLastError += ": ";
        m_strLastError += *String::AsciiValue(message->Get());

        ATHENA_LOG_ERROR(m_strLastError);

        return Handle<Value>();
    }

    // Return the result
    return handle_scope.Close(result);
}

Handle<Value> ScriptingManager::executeFile(const std::string& strFileName, Handle<Context> context)
{
    // Assertions
    assert(!strFileName.empty());

    // Declarations
    std::ifstream stream;

    // Open the file
#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
    string strConvertedFileName = strFileName;
    StringUtils::replaceAll(strConvertedFileName, "/", "\\");
    stream.open(strConvertedFileName.c_str(), ios_base::in);
#else
    stream.open(strFileName.c_str(), ios_base::in);
#endif
    if (!stream.is_open())
    {
        m_strLastError = "Can't find the file '" + strFileName + "'";
        ATHENA_LOG_ERROR(m_strLastError);
        return Handle<Value>();
    }

    // Load the content
    stream.seekg(0, std::ios::end);
    size_t size = stream.tellg();
    stream.seekg(0, std::ios::beg);

    char* pBuffer = new char[size + 1];
    pBuffer[size] = 0;
    stream.read(pBuffer, size);

    stream.close();

    // Execute the script
    Handle<Value> result = execute(pBuffer, strFileName, context);

    delete[] pBuffer;

    return result;
}

bool ScriptingManager::import(const std::string& strModuleName, v8::Handle<v8::Context> context)
{
    // Assertions
    assert(!strModuleName.empty());

    // Declarations
    DYNLIB_HANDLE                   handle;
    tModuleInitialisationFunction*  init_function;
    string                          strLibraryPath = "modules";
    string                          strLibraryName = "";

    // Initialisations
    m_strLastError = "";

    StringUtils::tStringsList parts = StringUtils::split(strModuleName, ".");

    // Retrieve the context to use
    if (context.IsEmpty())
        context = m_mainContext;

    Context::Scope context_scope(context);

    // Retrieve or create the necessary namespace(s)
    Handle<Object> ns = context->Global();
    for (unsigned int i = 0; i < parts.size(); ++i)
    {
        Handle<String> name = String::New(parts[i].c_str());

        Handle<Value> ns2;

        if (ns->Has(name))
        {
            if (i == parts.size() - 1)
                return true;

            ns2 = ns->Get(name);
        }
        else
        {
            ns2 = Object::New();
            ns->Set(name, ns2);
        }

        ns = ns2->ToObject();
    }

    // Retrieve the path to the dynamic library
#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
    if (!StringUtils::endsWith(strLibraryPath, "\\"))
        strLibraryPath += "\\";

    for (unsigned int i = 0; i < parts.size() - 1; ++i)
        strLibraryPath += parts[i] + "\\";

    strLibraryName = strLibraryPath + parts[parts.size() - 1] + ".dll";
#else
    if (!StringUtils::endsWith(strLibraryPath, "/"))
        strLibraryPath += "/";

    for (unsigned int i = 0; i < parts.size() - 1; ++i)
        strLibraryPath += parts[i] + "/";

    #if ATHENA_PLATFORM == ATHENA_PLATFORM_APPLE
        strLibraryName = strLibraryPath + parts[parts.size() - 1] + ".dylib";
    #else
        strLibraryName = strLibraryPath + parts[parts.size() - 1] + ".so";
    #endif
#endif

    // Load the dynamic library
    struct stat fileInfo;
    if (stat(strLibraryName.c_str(), &fileInfo) != 0)
    {
        m_strLastError = "Failed to find the module '" + strLibraryName + "')";
        ATHENA_LOG_ERROR(m_strLastError);
        return false;
    }

    handle = DYNLIB_LOAD(strLibraryName.c_str());

    if (!handle)
    {
#if ATHENA_PLATFORM != ATHENA_PLATFORM_WIN32
        const char* e = dlerror();
        if (e)
            m_strLastError = e;
        else
#endif
            m_strLastError = "Failed to load the module '" + strLibraryName + "'";

        ATHENA_LOG_ERROR(m_strLastError);

        return false;
    }

    // Retrieve the initialisation function of the module
    init_function = (tModuleInitialisationFunction*) DYNLIB_GETSYM(handle, "init_module");
    if (!init_function)
    {
        int ret = DYNLIB_UNLOAD(handle);
        m_strLastError = "No initialisation function found in the module '" + strLibraryName + "'";
        ATHENA_LOG_ERROR(m_strLastError);
        return false;
    }

    // Initialise the module
    return init_function(ns, strLibraryPath);
}

Persistent<Context> ScriptingManager::createContext()
{
    // Create the context and enter it
    Persistent<Context> context = Context::New();
    Context::Scope context_scope(context);

    // Retrieve the global object
    Handle<Object> global = context->Global();

    // Bind our global functions
    global->Set(String::New("print"), FunctionTemplate::New(Print)->GetFunction());
    global->Set(String::New("import_module"), FunctionTemplate::New(Import)->GetFunction());
    global->Set(String::New("load"), FunctionTemplate::New(Load)->GetFunction());

    // Create the 'Athena.Scripting' namespace
    Handle<Object> ns1 = Object::New();
    global->Set(String::New("Athena"), ns1);

    Handle<Object> ns2 = Object::New();
    ns1->Set(String::New("Scripting"), ns2);

    // Bind the library version
    ns2->Set(String::New("VERSION"), String::New(Athena::Scripting::VERSION));

    return context;
}
<commit_msg>Fix the compilation with clang<commit_after>/** @file   ScriptingManager.cpp
    @author Philip Abbet

    Implementation of the class 'Athena::Scripting::ScriptingManager'
*/

#include <Athena-Scripting/ScriptingManager.h>
#include <Athena-Scripting/Functions.h>
#include <Athena-Core/Log/LogManager.h>
#include <Athena-Core/Utils/StringUtils.h>
#include <Athena-Core/Utils/StringConverter.h>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>

#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
#   define WIN32_LEAN_AND_MEAN
#   include <windows.h>
#else
#   include <dlfcn.h>
#endif

#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
#    define DYNLIB_HANDLE           hInstance
#    define DYNLIB_LOAD( a )        LoadLibraryEx( a, NULL, LOAD_WITH_ALTERED_SEARCH_PATH )
#    define DYNLIB_GETSYM( a, b )   GetProcAddress( a, b )
#    define DYNLIB_UNLOAD( a )      !FreeLibrary( a )

struct HINSTANCE__;
typedef struct HINSTANCE__* hInstance;

#else
#    define DYNLIB_HANDLE           void*
#    define DYNLIB_LOAD( a )        dlopen( a, RTLD_NOW | RTLD_LOCAL )
#    define DYNLIB_GETSYM( a, b )   dlsym( a, b )
#    define DYNLIB_UNLOAD( a )      dlclose( a )

#endif

using namespace Athena::Scripting;
using namespace Athena::Utils;
using namespace Athena::Log;
using namespace std;
using namespace v8;

/************************************** CONSTANTS ***************************************/

/// Context used for logging
static const char* __CONTEXT__ = "Scripting manager";

/********************************** STATIC ATTRIBUTES ***********************************/

/// The instance of the singleton
namespace Athena {
    namespace Utils {
        template<> ScriptingManager* Singleton<ScriptingManager>::ms_Singleton = 0;
    }
}

/****************************** CONSTRUCTION / DESTRUCTION ******************************/

ScriptingManager::ScriptingManager()
{
    ATHENA_LOG_EVENT("Creation");

    // Create the global template
    HandleScope handle_scope;

    // Create the main context
    m_mainContext = createContext();
}

//-----------------------------------------------------------------------

ScriptingManager::~ScriptingManager()
{
    ATHENA_LOG_EVENT("Destruction");

    // Dispose the main context
    m_mainContext.Dispose();
}

//-----------------------------------------------------------------------

ScriptingManager& ScriptingManager::getSingleton()
{
    assert(ms_Singleton);
    return *ms_Singleton;
}

//-----------------------------------------------------------------------

ScriptingManager* ScriptingManager::getSingletonPtr()
{
    return ms_Singleton;
}

/**************************************** METHODS ***************************************/

Handle<Value> ScriptingManager::execute(const std::string& strScript,
                                        const std::string& strSourceName,
                                        Handle<Context> context)
{
    // Assertions
    assert(!strScript.empty());

    // Initialisations
    m_strLastError = "";

    // Create a stack-allocated handle scope
    HandleScope handle_scope;
    TryCatch trycatch;

    // Retrieve the context to use
    if (context.IsEmpty())
        context = m_mainContext;

    // Enter the context for compiling and running the script
    Context::Scope context_scope(context);

    // Create a string containing the JavaScript source code
    Handle<String> sourceCode = String::New(strScript.c_str(), strScript.size());

    // Create a string containing the origin of the source code
    Handle<String> origin;

    if (!strSourceName.empty())
        origin = String::New(strSourceName.c_str(), strSourceName.size());
    else
        origin = String::New("<unknown>", 9);

    // Compile the source code
    Handle<Script> script = Script::Compile(sourceCode, origin);
    if (script.IsEmpty())
    {
        Handle<Value> exception = trycatch.Exception();
        String::AsciiValue exception_str(exception);
        m_strLastError = *exception_str;
        ATHENA_LOG_ERROR(m_strLastError);
        return Handle<Value>();
    }

    // Run the script to get the result
    Handle<Value> result = script->Run();
    if (result.IsEmpty())
    {
        Handle<Message> message = trycatch.Message();
        m_strLastError = *String::AsciiValue(message->GetScriptResourceName());
        m_strLastError += ":";
        m_strLastError += StringConverter::toString(message->GetLineNumber());
        m_strLastError += ": ";
        m_strLastError += *String::AsciiValue(message->Get());

        ATHENA_LOG_ERROR(m_strLastError);

        return Handle<Value>();
    }

    // Return the result
    return handle_scope.Close(result);
}

Handle<Value> ScriptingManager::executeFile(const std::string& strFileName, Handle<Context> context)
{
    // Assertions
    assert(!strFileName.empty());

    // Declarations
    std::ifstream stream;

    // Open the file
#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
    string strConvertedFileName = strFileName;
    StringUtils::replaceAll(strConvertedFileName, "/", "\\");
    stream.open(strConvertedFileName.c_str(), ios_base::in);
#else
    stream.open(strFileName.c_str(), ios_base::in);
#endif
    if (!stream.is_open())
    {
        m_strLastError = "Can't find the file '" + strFileName + "'";
        ATHENA_LOG_ERROR(m_strLastError);
        return Handle<Value>();
    }

    // Load the content
    stream.seekg(0, std::ios::end);
    size_t size = stream.tellg();
    stream.seekg(0, std::ios::beg);

    char* pBuffer = new char[size + 1];
    pBuffer[size] = 0;
    stream.read(pBuffer, size);

    stream.close();

    // Execute the script
    Handle<Value> result = execute(pBuffer, strFileName, context);

    delete[] pBuffer;

    return result;
}

bool ScriptingManager::import(const std::string& strModuleName, v8::Handle<v8::Context> context)
{
    // Assertions
    assert(!strModuleName.empty());

    // Declarations
    DYNLIB_HANDLE                   handle;
    tModuleInitialisationFunction*  init_function;
    string                          strLibraryPath = "modules";
    string                          strLibraryName = "";

    // Initialisations
    m_strLastError = "";

    StringUtils::tStringsList parts = StringUtils::split(strModuleName, ".");

    // Retrieve the context to use
    if (context.IsEmpty())
        context = m_mainContext;

    Context::Scope context_scope(context);

    // Retrieve or create the necessary namespace(s)
    Handle<Object> ns = context->Global();
    for (unsigned int i = 0; i < parts.size(); ++i)
    {
        Handle<String> name = String::New(parts[i].c_str());

        Handle<Value> ns2;

        if (ns->Has(name))
        {
            if (i == parts.size() - 1)
                return true;

            ns2 = ns->Get(name);
        }
        else
        {
            ns2 = Object::New();
            ns->Set(name, ns2);
        }

        ns = ns2->ToObject();
    }

    // Retrieve the path to the dynamic library
#if ATHENA_PLATFORM == ATHENA_PLATFORM_WIN32
    if (!StringUtils::endsWith(strLibraryPath, "\\"))
        strLibraryPath += "\\";

    for (unsigned int i = 0; i < parts.size() - 1; ++i)
        strLibraryPath += parts[i] + "\\";

    strLibraryName = strLibraryPath + parts[parts.size() - 1] + ".dll";
#else
    if (!StringUtils::endsWith(strLibraryPath, "/"))
        strLibraryPath += "/";

    for (unsigned int i = 0; i < parts.size() - 1; ++i)
        strLibraryPath += parts[i] + "/";

    #if ATHENA_PLATFORM == ATHENA_PLATFORM_APPLE
        strLibraryName = strLibraryPath + parts[parts.size() - 1] + ".dylib";
    #else
        strLibraryName = strLibraryPath + parts[parts.size() - 1] + ".so";
    #endif
#endif

    // Load the dynamic library
    struct stat fileInfo;
    if (stat(strLibraryName.c_str(), &fileInfo) != 0)
    {
        m_strLastError = "Failed to find the module '" + strLibraryName + "')";
        ATHENA_LOG_ERROR(m_strLastError);
        return false;
    }

    handle = DYNLIB_LOAD(strLibraryName.c_str());

    if (!handle)
    {
#if ATHENA_PLATFORM != ATHENA_PLATFORM_WIN32
        const char* e = dlerror();
        if (e)
            m_strLastError = e;
        else
#endif
            m_strLastError = "Failed to load the module '" + strLibraryName + "'";

        ATHENA_LOG_ERROR(m_strLastError);

        return false;
    }

    // Retrieve the initialisation function of the module
    init_function = (tModuleInitialisationFunction*) DYNLIB_GETSYM(handle, "init_module");
    if (!init_function)
    {
        int ret = DYNLIB_UNLOAD(handle);
        m_strLastError = "No initialisation function found in the module '" + strLibraryName + "'";
        ATHENA_LOG_ERROR(m_strLastError);
        return false;
    }

    // Initialise the module
    return init_function(ns, strLibraryPath);
}

Persistent<Context> ScriptingManager::createContext()
{
    // Create the context and enter it
    Persistent<Context> context = Context::New();
    Context::Scope context_scope(context);

    // Retrieve the global object
    Handle<Object> global = context->Global();

    // Bind our global functions
    global->Set(String::New("print"), FunctionTemplate::New(Print)->GetFunction());
    global->Set(String::New("import_module"), FunctionTemplate::New(Import)->GetFunction());
    global->Set(String::New("load"), FunctionTemplate::New(Load)->GetFunction());

    // Create the 'Athena.Scripting' namespace
    Handle<Object> ns1 = Object::New();
    global->Set(String::New("Athena"), ns1);

    Handle<Object> ns2 = Object::New();
    ns1->Set(String::New("Scripting"), ns2);

    // Bind the library version
    ns2->Set(String::New("VERSION"), String::New(Athena::Scripting::VERSION));

    return context;
}
<|endoftext|>


<commit_before>#include "network_mesh_analytical.h"
#include "network_mesh_analytical_params.h"
#include "chip.h"
#include <math.h>

using namespace std;

//NetworkMeshAnalytical::NetworkMeshAnalytical(int tid, int num_threads, Core *core)
NetworkMeshAnalytical::NetworkMeshAnalytical(Core *core, int num_threads)
    :
        Network(core, num_threads),
        bytes_sent(0),
        cycles_spent_proc(0),
        cycles_spent_latency(0),
        cycles_spent_contention(0)
{
}

NetworkMeshAnalytical::~NetworkMeshAnalytical()
{
}

int NetworkMeshAnalytical::netSend(NetPacket packet)
{
    bytes_sent += packet.length;
    return Network::netSend(packet);
}

NetPacket NetworkMeshAnalytical::netRecv(NetMatch match)
{
    return Network::netRecv(match);
}

UINT64 NetworkMeshAnalytical::netProcCost(NetPacket packet)
{
    UINT64 cost = 10;
    cycles_spent_proc += cost;
    return cost;
}

UINT64 NetworkMeshAnalytical::netLatency(NetPacket packet)
{
    // We model a unidirectional network with end-around connections
    // using the network model in "Limits on Interconnect Performance"
    // (by Anant). Currently, this ignores communication locality and
    // sets static values for all parameters. We also assume uniform
    // packet distribution, so we do not take the packet destination
    // into account.
    //
    // We combine the contention model (eq. 12) with the model for
    // limited bisection width (sec. 4.2).

    // TODO: Fix (if necessary) distance calculation for uneven
    // topologies, i.e. 8-node 2d mesh or 10-node 3d mesh.

    // TODO: Confirm model for latency computed based on actual number
    // of network hops.

    // Retrieve parameters
    const NetworkMeshAnalyticalParameters *pParams = Config::getSingleton()->getAnalyticNetworkParms();
    double Tw2 = pParams->Tw2;
    double s = pParams->s;
    int n = pParams->n;
    double W = pParams->W;
    double p = pParams->p;

    // This lets us derive the latency, ignoring contention

    int N;                    // number of nodes in the network
    double k;                 // length of mesh in one dimension
    double kd;                // number of hops per dimension
    double time_per_hop;      // time spent in one hop through the network
    double B;                 // number of flits for packet
    double hops_in_network;   // number of nodes visited
    double Tb;                // latency, without contention

    N = g_chip->getNumModules();
    k = pow(N, 1./n);                  // pg 5
    kd = (k-1.)/2.;                    // pg 5 (note this will be
      // different for different network configurations...say,
      // bidirectional networks)
    time_per_hop = s + pow(k, n/2.-1.);  // pg 6
    B = ceil(packet.length * 8. / W);

    // Compute the number of hops based on src, dest
    // Based on this eqn:
    // node number = x1 + x2 k + x3 k^2 + ... + xn k^(n-1)
    int network_distance = 0;
    int src = packet.sender;
    int dest = packet.receiver;
    int ki = (int)k;
    for (int i = 0; i < n; i++)
      {
        div_t q1, q2;
        q1 = div(src, ki);
        q2 = div(dest, ki);
        // This models a unidirectional network distance
        // Should use abs() for bidirectional.
        if (q1.rem > q2.rem)
          network_distance += ki - (q1.rem - q2.rem);
        else
          network_distance += q2.rem - q1.rem;
        src = q1.quot;
        dest = q2.quot;
      }
    hops_in_network = network_distance + B; // B flits must be sent
      // (with wormhole routing, this adds B hops)

    Tb = Tw2 * time_per_hop * hops_in_network; // pg 5

    // Now to model contention... (sec 3.2)
    double w;                 // delay due to contention

    w  = p * B / (1. - p);
    w *= (kd-1.)/(kd*kd);
    w *= 1.+1./((double)n);

    if (w < 0) w = 0; // correct negative contention values for small
                      // networks

    double hops_with_contention;
    double Tc;                // latency, with contention
    hops_with_contention = network_distance * (1. + w) + B;
    Tc = Tw2 * time_per_hop * hops_with_contention;

    // Computation finished...

    UINT64 Tci = (UINT64)(ceil(Tc));
    cycles_spent_latency += Tci;
    cycles_spent_contention += (UINT64)(Tc - Tb);
    return Tci;
}

void NetworkMeshAnalytical::outputSummary(ostream &out)
{
   out << "  Network summary:" << endl;
   out << "    bytes sent: " << bytes_sent << endl;
   out << "    cycles spent proc: " << cycles_spent_proc << endl;
   out << "    cycles spent latency: " << cycles_spent_latency << endl;
   out << "    cycles spent contention: " << cycles_spent_contention << endl;
}

<commit_msg>[misc] Remove singleton references, use g_config.<commit_after>#include "network_mesh_analytical.h"
#include "network_mesh_analytical_params.h"
#include "chip.h"
#include <math.h>

using namespace std;

//NetworkMeshAnalytical::NetworkMeshAnalytical(int tid, int num_threads, Core *core)
NetworkMeshAnalytical::NetworkMeshAnalytical(Core *core, int num_threads)
    :
        Network(core, num_threads),
        bytes_sent(0),
        cycles_spent_proc(0),
        cycles_spent_latency(0),
        cycles_spent_contention(0)
{
}

NetworkMeshAnalytical::~NetworkMeshAnalytical()
{
}

int NetworkMeshAnalytical::netSend(NetPacket packet)
{
    bytes_sent += packet.length;
    return Network::netSend(packet);
}

NetPacket NetworkMeshAnalytical::netRecv(NetMatch match)
{
    return Network::netRecv(match);
}

UINT64 NetworkMeshAnalytical::netProcCost(NetPacket packet)
{
    UINT64 cost = 10;
    cycles_spent_proc += cost;
    return cost;
}

UINT64 NetworkMeshAnalytical::netLatency(NetPacket packet)
{
    // We model a unidirectional network with end-around connections
    // using the network model in "Limits on Interconnect Performance"
    // (by Anant). Currently, this ignores communication locality and
    // sets static values for all parameters. We also assume uniform
    // packet distribution, so we do not take the packet destination
    // into account.
    //
    // We combine the contention model (eq. 12) with the model for
    // limited bisection width (sec. 4.2).

    // TODO: Fix (if necessary) distance calculation for uneven
    // topologies, i.e. 8-node 2d mesh or 10-node 3d mesh.

    // TODO: Confirm model for latency computed based on actual number
    // of network hops.

    // Retrieve parameters
    const NetworkMeshAnalyticalParameters *pParams = g_config->getAnalyticNetworkParms();
    double Tw2 = pParams->Tw2;
    double s = pParams->s;
    int n = pParams->n;
    double W = pParams->W;
    double p = pParams->p;

    // This lets us derive the latency, ignoring contention

    int N;                    // number of nodes in the network
    double k;                 // length of mesh in one dimension
    double kd;                // number of hops per dimension
    double time_per_hop;      // time spent in one hop through the network
    double B;                 // number of flits for packet
    double hops_in_network;   // number of nodes visited
    double Tb;                // latency, without contention

    N = g_chip->getNumModules();
    k = pow(N, 1./n);                  // pg 5
    kd = (k-1.)/2.;                    // pg 5 (note this will be
      // different for different network configurations...say,
      // bidirectional networks)
    time_per_hop = s + pow(k, n/2.-1.);  // pg 6
    B = ceil(packet.length * 8. / W);

    // Compute the number of hops based on src, dest
    // Based on this eqn:
    // node number = x1 + x2 k + x3 k^2 + ... + xn k^(n-1)
    int network_distance = 0;
    int src = packet.sender;
    int dest = packet.receiver;
    int ki = (int)k;
    for (int i = 0; i < n; i++)
      {
        div_t q1, q2;
        q1 = div(src, ki);
        q2 = div(dest, ki);
        // This models a unidirectional network distance
        // Should use abs() for bidirectional.
        if (q1.rem > q2.rem)
          network_distance += ki - (q1.rem - q2.rem);
        else
          network_distance += q2.rem - q1.rem;
        src = q1.quot;
        dest = q2.quot;
      }
    hops_in_network = network_distance + B; // B flits must be sent
      // (with wormhole routing, this adds B hops)

    Tb = Tw2 * time_per_hop * hops_in_network; // pg 5

    // Now to model contention... (sec 3.2)
    double w;                 // delay due to contention

    w  = p * B / (1. - p);
    w *= (kd-1.)/(kd*kd);
    w *= 1.+1./((double)n);

    if (w < 0) w = 0; // correct negative contention values for small
                      // networks

    double hops_with_contention;
    double Tc;                // latency, with contention
    hops_with_contention = network_distance * (1. + w) + B;
    Tc = Tw2 * time_per_hop * hops_with_contention;

    // Computation finished...

    UINT64 Tci = (UINT64)(ceil(Tc));
    cycles_spent_latency += Tci;
    cycles_spent_contention += (UINT64)(Tc - Tb);
    return Tci;
}

void NetworkMeshAnalytical::outputSummary(ostream &out)
{
   out << "  Network summary:" << endl;
   out << "    bytes sent: " << bytes_sent << endl;
   out << "    cycles spent proc: " << cycles_spent_proc << endl;
   out << "    cycles spent latency: " << cycles_spent_latency << endl;
   out << "    cycles spent contention: " << cycles_spent_contention << endl;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SwXMLBlockListContext.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: mtg $ $Date: 2001-02-08 15:53:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
*
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _SW_XMLBLOCKLISTCONTEXT_HXX
#define _SW_XMLBLOCKLISTCONTEXT_HXX

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif

#ifndef _XMLOFF_XMLITMAP_HXX
#include <xmloff/xmlitmap.hxx>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include <xmloff/xmlimp.hxx>
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif

#ifndef _XMLOFF_XMLKYWD_HXX
#include <xmloff/xmlkywd.hxx>
#endif

#ifndef _SW_XMLBLOCKIMPORT_HXX
#include <SwXMLBlockImport.hxx>
#endif

#ifndef _SW_XMLTEXTBLOCKS_HXX
#include <SwXMLTextBlocks.hxx>
#endif

class SwXMLBlockListImport;
class SwXMLTextBlockImport;

class SwXMLBlockListContext : public SvXMLImportContext
{
private:
    SwXMLBlockListImport & rLocalRef;
public:
    SwXMLBlockListContext( SwXMLBlockListImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLBlockListContext ( void );
    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

};
class SwXMLBlockContext : public SvXMLImportContext
{
private:
    SwXMLBlockListImport & rLocalRef;
public:
    SwXMLBlockContext(     SwXMLBlockListImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLBlockContext ( void );
};

class SwXMLTextBlockDocumentContext : public SvXMLImportContext
{
private:
    SwXMLTextBlockImport & rLocalRef;
public:
    SwXMLTextBlockDocumentContext(     SwXMLTextBlockImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLTextBlockDocumentContext ( void );
};
class SwXMLTextBlockBodyContext : public SvXMLImportContext
{
private:
    SwXMLTextBlockImport & rLocalRef;
public:
    SwXMLTextBlockBodyContext(     SwXMLTextBlockImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLTextBlockBodyContext ( void );
};
class SwXMLTextBlockParContext : public SvXMLImportContext
{
private:
    SwXMLTextBlockImport & rLocalRef;
    ::rtl::OUString sContent;
public:
    SwXMLTextBlockParContext(     SwXMLTextBlockImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    virtual void Characters( const ::rtl::OUString& rChars );
    ~SwXMLTextBlockParContext ( void );
};
#endif
<commit_msg>Remove unused class member<commit_after>/*************************************************************************
 *
 *  $RCSfile: SwXMLBlockListContext.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: mtg $ $Date: 2001-05-02 16:41:02 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
*
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _SW_XMLBLOCKLISTCONTEXT_HXX
#define _SW_XMLBLOCKLISTCONTEXT_HXX

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif

#ifndef _XMLOFF_XMLITMAP_HXX
#include <xmloff/xmlitmap.hxx>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include <xmloff/xmlimp.hxx>
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif

#ifndef _XMLOFF_XMLKYWD_HXX
#include <xmloff/xmlkywd.hxx>
#endif

#ifndef _SW_XMLBLOCKIMPORT_HXX
#include <SwXMLBlockImport.hxx>
#endif

#ifndef _SW_XMLTEXTBLOCKS_HXX
#include <SwXMLTextBlocks.hxx>
#endif

class SwXMLBlockListImport;
class SwXMLTextBlockImport;

class SwXMLBlockListContext : public SvXMLImportContext
{
private:
    SwXMLBlockListImport & rLocalRef;
public:
    SwXMLBlockListContext( SwXMLBlockListImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLBlockListContext ( void );
    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

};
class SwXMLBlockContext : public SvXMLImportContext
{
private:
    SwXMLBlockListImport & rLocalRef;
public:
    SwXMLBlockContext(     SwXMLBlockListImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLBlockContext ( void );
};

class SwXMLTextBlockDocumentContext : public SvXMLImportContext
{
private:
    SwXMLTextBlockImport & rLocalRef;
public:
    SwXMLTextBlockDocumentContext(     SwXMLTextBlockImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLTextBlockDocumentContext ( void );
};
class SwXMLTextBlockBodyContext : public SvXMLImportContext
{
private:
    SwXMLTextBlockImport & rLocalRef;
public:
    SwXMLTextBlockBodyContext(     SwXMLTextBlockImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    ~SwXMLTextBlockBodyContext ( void );
};
class SwXMLTextBlockParContext : public SvXMLImportContext
{
private:
    SwXMLTextBlockImport & rLocalRef;
public:
    SwXMLTextBlockParContext(     SwXMLTextBlockImport& rImport,
                           sal_uInt16 nPrefix,
                           const rtl::OUString& rLocalName,
                           const ::com::sun::star::uno::Reference<
                           ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
    virtual void Characters( const ::rtl::OUString& rChars );
    ~SwXMLTextBlockParContext ( void );
};
#endif
<|endoftext|>


<commit_before>#include "./SDAMatchHits.h"

SDAMatchHits::SDAMatchHits(const char* name, const char* description)
  : JPetTask(name, description),
    fMatched(0),
    fCurrentEventNumber(0)
{
}

SDAMatchHits::~SDAMatchHits()
{
}

void SDAMatchHits::init(const JPetTaskInterface::Options& /* opts */)
{
  fMatched = 0;
  fCurrentEventNumber=0;
}

void SDAMatchHits::exec()
{

  JPetPhysSignal currSignal = (JPetPhysSignal&) (*getEvent());

  if (fSignalsArray.empty()) {
    fSignalsArray.push_back(currSignal);
  } else {
    if (fSignalsArray[0].getTimeWindowIndex() == currSignal.getTimeWindowIndex()) {
      fSignalsArray.push_back(currSignal);
    } else {
      saveHits(createHits(fSignalsArray)); //create Hits from previously saved signals
      fSignalsArray.clear();
      fSignalsArray.push_back(currSignal);
    }
  }

  fCurrentEventNumber++;
}

void SDAMatchHits::terminate()
{
  int fEventNb = fCurrentEventNumber;
  INFO(
       Form("Matching complete \nAmount of fMatched hits: %d out of initial %d signals" , fMatched, fEventNb) );
}

std::vector<JPetHit> SDAMatchHits::createHits(std::vector<JPetPhysSignal>& signals){

  std::vector<JPetHit> hits;

  // group the signals by barrel slot ID
  std::map<int, std::vector<JPetPhysSignal>> signalsBySlot;
  for(auto const & signal : signals){
    int barrelSlotID = signal.getBarrelSlot().getID();
    signalsBySlot[barrelSlotID].push_back(signal);
  }

  // discard entries for PMTs with smalller number of signals than two for each barrel slot
  // since they cannot be merged into JPetHit and later for JPetLOR
  for(std::map<int, std::vector<JPetPhysSignal>>::iterator it = signalsBySlot.begin();
      it != signalsBySlot.end(); ++it){
    if( it->second.size() < 2 ){
      signalsBySlot.erase( it );
    }
  }

  // iterate over barrel slots which had a sufficient number
  // of signals to match a hit
  for(std::map<int, std::vector<JPetPhysSignal>>::iterator it = signalsBySlot.begin();
      it != signalsBySlot.end(); ++it){
      std::vector<JPetHit> hitsFromSingleSlot = matchHitsWithinSlot(it->second);
      // append the hits found for one specific barrel slot to all hits from this time window
      hits.insert(hits.end(), hitsFromSingleSlot.begin(), hitsFromSingleSlot.end());
  }

  return hits;
}

std::vector<JPetHit> matchHitsWithinSlot(std::vector<JPetPhysSignal> signals){

  std::vector<JPetHit> hits;

  for(int i=0;i<signals.size()-1;++i){
    for(int j=i+1;j<signals.size();++j){
      JPetPhysSignal & sig1 = signals.at(i);
      JPetPhysSignal & sig2 = signals.at(j);
      if( sig1.getPM().getSide() == sig2.getPM().getSide() ){
	// @ todo: add more strict rules for deciding whether two signals constitute a hit
	continue;
      }else{
	// ha wave a hit
	JPetHit hit;
	if (sig1.getPM().getSide() == JPetPM::SideA){
	  hit.setSignalA(sig1);
	  hit.setSignalB(sig2);
	}else{
	  hit.setSignalA(sig2);
	  hit.setSignalB(sig1);
	}
	hits.push_back(hit);
      }
    }
  }

  return hits;
}

void SDAMatchHits::saveHits(std::vector<JPetHit> hits){
  assert(fWriter);
  fMatched += hits.size();
  for (auto hit : hits) {
    fWriter->write(hit);
  }
}
<commit_msg>Fixed bug in SDAMatchHits<commit_after>#include "./SDAMatchHits.h"

SDAMatchHits::SDAMatchHits(const char* name, const char* description)
  : JPetTask(name, description),
    fMatched(0),
    fCurrentEventNumber(0)
{
}

SDAMatchHits::~SDAMatchHits()
{
}

void SDAMatchHits::init(const JPetTaskInterface::Options& /* opts */)
{
  fMatched = 0;
  fCurrentEventNumber=0;
}

void SDAMatchHits::exec()
{

  JPetPhysSignal currSignal = (JPetPhysSignal&) (*getEvent());

  if (fSignalsArray.empty()) {
    fSignalsArray.push_back(currSignal);
  } else {
    if (fSignalsArray[0].getTimeWindowIndex() == currSignal.getTimeWindowIndex()) {
      fSignalsArray.push_back(currSignal);
    } else {
      saveHits(createHits(fSignalsArray)); //create Hits from previously saved signals
      fSignalsArray.clear();
      fSignalsArray.push_back(currSignal);
    }
  }

  fCurrentEventNumber++;
}

void SDAMatchHits::terminate()
{
  int fEventNb = fCurrentEventNumber;
  INFO(
       Form("Matching complete \nAmount of fMatched hits: %d out of initial %d signals" , fMatched, fEventNb) );
}

std::vector<JPetHit> SDAMatchHits::createHits(std::vector<JPetPhysSignal>& signals){

  std::vector<JPetHit> hits;

  // group the signals by barrel slot ID
  std::map<int, std::vector<JPetPhysSignal>> signalsBySlot;
  for(auto const & signal : signals){
    int barrelSlotID = signal.getBarrelSlot().getID();
    signalsBySlot[barrelSlotID].push_back(signal);
  }

  // discard entries for PMTs with smalller number of signals than two for each barrel slot
  // since they cannot be merged into JPetHit and later for JPetLOR
  for(std::map<int, std::vector<JPetPhysSignal>>::iterator it = signalsBySlot.begin();
      it != signalsBySlot.end(); ++it){
    if( it->second.size() < 2 ){
      signalsBySlot.erase( it );
    }
  }

  // iterate over barrel slots which had a sufficient number
  // of signals to match a hit
  for(std::map<int, std::vector<JPetPhysSignal>>::iterator it = signalsBySlot.begin();
      it != signalsBySlot.end(); ++it){
      std::vector<JPetHit> hitsFromSingleSlot = matchHitsWithinSlot(it->second);
      // append the hits found for one specific barrel slot to all hits from this time window
      hits.insert(hits.end(), hitsFromSingleSlot.begin(), hitsFromSingleSlot.end());
  }

  return hits;
}

std::vector<JPetHit> SDAMatchHits::matchHitsWithinSlot(std::vector<JPetPhysSignal> signals){

  std::vector<JPetHit> hits;

  for(int i=0;i<signals.size()-1;++i){
    for(int j=i+1;j<signals.size();++j){
      JPetPhysSignal & sig1 = signals.at(i);
      JPetPhysSignal & sig2 = signals.at(j);
      if( sig1.getPM().getSide() == sig2.getPM().getSide() ){
	// @ todo: add more strict rules for deciding whether two signals constitute a hit
	continue;
      }else{
	// ha wave a hit
	JPetHit hit;
	if (sig1.getPM().getSide() == JPetPM::SideA){
	  hit.setSignalA(sig1);
	  hit.setSignalB(sig2);
	}else{
	  hit.setSignalA(sig2);
	  hit.setSignalB(sig1);
	}
	hits.push_back(hit);
      }
    }
  }

  return hits;
}

void SDAMatchHits::saveHits(std::vector<JPetHit> hits){
  assert(fWriter);
  fMatched += hits.size();
  for (auto hit : hits) {
    fWriter->write(hit);
  }
}
<|endoftext|>


<commit_before>/*****************************************/
/* class BOARD_ITEM: som basic functions */
/*****************************************/

#include "fctsys.h"
#include "gr_basic.h"

#include "common.h"
#include "pcbnew.h"

#include "id.h"
#include "collectors.h"

#include "bitmaps.h"
#include "add_cotation.xpm"
#include "Add_Mires.xpm"
#include "Add_Zone.xpm"

/********************************************************/
wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
/********************************************************/

/** return a specific comment for "this". Used in pop up menus
 * @param aPcb = the parent board
 */
{
    wxString          text;
    const BOARD_ITEM* item = this;
    EQUIPOT*          net;

    switch( item->Type() )
    {
    case PCB_EQUIPOT_STRUCT_TYPE:
        text << _( "Net" ) << ( (EQUIPOT*) item )->m_Netname << wxT( " " ) <<
        ( (EQUIPOT*) item )->m_NetCode;
        break;

    case TYPEMODULE:
        text << _( "Footprint" ) << wxT( " " ) << ( (MODULE*) item )->GetReference();
        text << wxT( " (" ) << ReturnPcbLayerName( item->m_Layer ).Trim() << wxT( ")" );
        break;

    case TYPEPAD:
        text << _( "Pad" ) << wxT( " " ) << ( (D_PAD*) item )->ReturnStringPadName() << _( " of " )
             << ( (MODULE*) GetParent() )->GetReference();
        break;

    case TYPEDRAWSEGMENT:
        text << _( "Pcb Graphic" ) << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();  // @todo: extend text
        break;

    case TYPETEXTE:
        text << _( "Pcb Text" ) << wxT( " " );;
        if( ( (TEXTE_PCB*) item )->m_Text.Len() < 12 )
            text << ( (TEXTE_PCB*) item )->m_Text;
        else
            text += ( (TEXTE_PCB*) item )->m_Text.Left( 10 ) + wxT( ".." );
        text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
        break;

    case TYPETEXTEMODULE:

        switch( ( (TEXTE_MODULE*) item )->m_Type )
        {
        case TEXT_is_REFERENCE:
            text << _( "Reference" ) << wxT( " " ) << ( (TEXTE_MODULE*) item )->m_Text;
            break;

        case TEXT_is_VALUE:
            text << _( "Value" ) << wxT( " " ) << ( (TEXTE_MODULE*) item )->m_Text << _( " of " )
                 << ( (MODULE*) GetParent() )->GetReference();
            break;

        default:    // wrap this one in quotes:
            text << _( "Text" ) << wxT( " \"" ) << ( (TEXTE_MODULE*) item )->m_Text <<
            wxT( "\"" ) << _( " of " )
                 << ( (MODULE*) GetParent() )->GetReference();
            break;
        }

        break;

    case TYPEEDGEMODULE:
        text << _( "Graphic" ) << wxT( " " );
        const wxChar* cp;

        switch( ( (EDGE_MODULE*) item )->m_Shape )
        {
        case S_SEGMENT:
            cp = _( "Line" );             break;

        case S_RECT:
            cp = _( "Rect" );             break;

        case S_ARC:
            cp = _( "Arc" );              break;

        case S_CIRCLE:
            cp = _( "Circle" );           break;

            /* used in Gerbview: */
        case S_ARC_RECT:
            cp = wxT( "arc_rect" );       break;

        case S_SPOT_OVALE:
            cp = wxT( "spot_oval" );      break;

        case S_SPOT_CIRCLE:
            cp = wxT( "spot_circle" );    break;

        case S_SPOT_RECT:
            cp = wxT( "spot_rect" );      break;

        case S_POLYGON:
            cp = wxT( "polygon" );        break;

        default:
            cp = wxT( "??EDGE??" );       break;
        }

        text << *cp << _( " of " )
             << ( (MODULE*) GetParent() )->GetReference();
        break;

    case TYPETRACK:
        text << _( "Track" ) << wxT( " " );
        net = aPcb->FindNet( ( (TRACK*) item )->m_NetCode );
        if( net )
        {
            text << wxT( " [" ) << net->m_Netname << wxT( "]" );
        }
        text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
        break;

    case TYPEZONE:
        text << _( "Zone" ) << wxT( " " );
        {
            wxString TimeStampText;
            TimeStampText.Printf( wxT( "(%8.8X)" ), item->m_TimeStamp );
            text << TimeStampText;
        }
        net = aPcb->FindNet( ( (SEGZONE*) item )->m_NetCode );
        if( net )
        {
            text << wxT( " [" ) << net->m_Netname << wxT( "]" );
        }
        text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
        break;

    case TYPEVIA:
        {
            SEGVIA* via = (SEGVIA*) item;
            text << _( "Via" ) << wxT( " " ) << via->m_NetCode;

            int shape = via->Shape();
            if( shape == VIA_ENTERREE )
                text << wxT(" ") << _( "Blind" );
            else if( shape == VIA_BORGNE )
                text << wxT(" ") << _("Buried");
            // else say nothing about normal vias

            net = aPcb->FindNet( via->m_NetCode );
            if( net )
            {
                text << wxT( " [" ) << net->m_Netname << wxT( "]" );
            }

            // say which layers, only two for now
            int topLayer;
            int botLayer;
            via->ReturnLayerPair( &topLayer, &botLayer );
            text << _( " on " ) << ReturnPcbLayerName( topLayer).Trim() << wxT(" <-> ")
                << ReturnPcbLayerName( botLayer ).Trim();
        }
        break;

    case TYPEMARQUEUR:
        text << _( "Marker" );
        break;

    case TYPECOTATION:
        text << _( "Dimension" ) << wxT( " \"" ) << ( (COTATION*) item )->GetText() << wxT( "\"" );
        break;

    case TYPEMIRE:
        text << _( "Mire" );          // @todo: extend text,  Mire is not an english word!
        break;

    case TYPEEDGEZONE:
        text << _( "Edge Zone" ) << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();  // @todo: extend text
        break;

    default:
        text << item->GetClass() << wxT( " Unexpected item type: BUG!!" );
        break;
    }

    return text;
}

/*****************************************/
const char** BOARD_ITEM::MenuIcon() const
/*****************************************/

/** return a specific icon pointer (an xpm icon)  for "this". Used in pop up menus
 * @return an icon pointer (can be NULL)
 */
{
    char**            xpm;
    const BOARD_ITEM* item = this;

    switch( item->Type() )
    {
    case PCB_EQUIPOT_STRUCT_TYPE:
        xpm = general_ratsnet_xpm;
        break;

    case TYPEMODULE:
        xpm = module_xpm;
        break;

    case TYPEPAD:
        xpm = pad_xpm;
        break;

    case TYPEDRAWSEGMENT:
        xpm = add_dashed_line_xpm;
        break;

    case TYPETEXTE:
        xpm = add_text_xpm;
        break;

    case TYPETEXTEMODULE:
        xpm = footprint_text_xpm;
        break;

    case TYPEEDGEMODULE:
        xpm = show_mod_edge_xpm;
        break;

    case TYPETRACK:
        xpm = showtrack_xpm;
        break;

    case TYPEZONE:
        xpm = add_zone_xpm;
        break;

    case TYPEVIA:
        xpm = pad_sketch_xpm;
        break;

    case TYPEMARQUEUR:
        xpm = pad_xpm;              // @todo: create and use marker xpm
        break;

    case TYPECOTATION:
        xpm = add_cotation_xpm;
        break;

    case TYPEMIRE:
        xpm = add_mires_xpm;
        break;

    case TYPEEDGEZONE:
        xpm = show_mod_edge_xpm;    // @todo: pcb edge xpm
        break;

    default:
        xpm = 0;
        break;
    }

    return (const char**) xpm;
}
<commit_msg>BOARD_ITEM::MenuText()<commit_after>/*****************************************/
/* class BOARD_ITEM: som basic functions */
/*****************************************/

#include "fctsys.h"
#include "gr_basic.h"

#include "common.h"
#include "pcbnew.h"

#include "id.h"
#include "collectors.h"

#include "bitmaps.h"
#include "add_cotation.xpm"
#include "Add_Mires.xpm"
#include "Add_Zone.xpm"

/********************************************************/
wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
/********************************************************/

/** return a specific comment for "this". Used in pop up menus
 * @param aPcb = the parent board
 */
{
    wxString          text;
    const BOARD_ITEM* item = this;
    EQUIPOT*          net;

    switch( item->Type() )
    {
    case PCB_EQUIPOT_STRUCT_TYPE:
        text << _( "Net" ) << ( (EQUIPOT*) item )->m_Netname << wxT( " " ) <<
        ( (EQUIPOT*) item )->m_NetCode;
        break;

    case TYPEMODULE:
        text << _( "Footprint" ) << wxT( " " ) << ( (MODULE*) item )->GetReference();
        text << wxT( " (" ) << ReturnPcbLayerName( item->m_Layer ).Trim() << wxT( ")" );
        break;

    case TYPEPAD:
        text << _( "Pad" ) << wxT( " " ) << ( (D_PAD*) item )->ReturnStringPadName() << _( " of " )
             << ( (MODULE*) GetParent() )->GetReference();
        break;

    case TYPEDRAWSEGMENT:
        text << _( "Pcb Graphic" ) << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();  // @todo: extend text
        break;

    case TYPETEXTE:
        text << _( "Pcb Text" ) << wxT( " " );;
        if( ( (TEXTE_PCB*) item )->m_Text.Len() < 12 )
            text << ( (TEXTE_PCB*) item )->m_Text;
        else
            text += ( (TEXTE_PCB*) item )->m_Text.Left( 10 ) + wxT( ".." );
        text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
        break;

    case TYPETEXTEMODULE:

        switch( ( (TEXTE_MODULE*) item )->m_Type )
        {
        case TEXT_is_REFERENCE:
            text << _( "Reference" ) << wxT( " " ) << ( (TEXTE_MODULE*) item )->m_Text;
            break;

        case TEXT_is_VALUE:
            text << _( "Value" ) << wxT( " " ) << ( (TEXTE_MODULE*) item )->m_Text << _( " of " )
                 << ( (MODULE*) GetParent() )->GetReference();
            break;

        default:    // wrap this one in quotes:
            text << _( "Text" ) << wxT( " \"" ) << ( (TEXTE_MODULE*) item )->m_Text <<
            wxT( "\"" ) << _( " of " )
                 << ( (MODULE*) GetParent() )->GetReference();
            break;
        }

        break;

    case TYPEEDGEMODULE:
        text << _( "Graphic" ) << wxT( " " );
        const wxChar* cp;

        switch( ( (EDGE_MODULE*) item )->m_Shape )
        {
        case S_SEGMENT:
            cp = _( "Line" );             break;

        case S_RECT:
            cp = _( "Rect" );             break;

        case S_ARC:
            cp = _( "Arc" );              break;

        case S_CIRCLE:
            cp = _( "Circle" );           break;

            /* used in Gerbview: */
        case S_ARC_RECT:
            cp = wxT( "arc_rect" );       break;

        case S_SPOT_OVALE:
            cp = wxT( "spot_oval" );      break;

        case S_SPOT_CIRCLE:
            cp = wxT( "spot_circle" );    break;

        case S_SPOT_RECT:
            cp = wxT( "spot_rect" );      break;

        case S_POLYGON:
            cp = wxT( "polygon" );        break;

        default:
            cp = wxT( "??EDGE??" );       break;
        }

        text << *cp << _( " of " )
             << ( (MODULE*) GetParent() )->GetReference();
        break;

    case TYPETRACK:
        text << _( "Track" ) << wxT( " " );
        net = aPcb->FindNet( ( (TRACK*) item )->m_NetCode );
        if( net )
        {
            text << wxT( " [" ) << net->m_Netname << wxT( "]" );
        }
        text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
        break;

    case TYPEZONE:
        text << _( "Zone" ) << wxT( " " );
        {
            wxString TimeStampText;
            TimeStampText.Printf( wxT( "(%8.8X)" ), item->m_TimeStamp );
            text << TimeStampText;
        }
        net = aPcb->FindNet( ( (SEGZONE*) item )->m_NetCode );
        if( net )
        {
            text << wxT( " [" ) << net->m_Netname << wxT( "]" );
        }
        text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
        break;

    case TYPEVIA:
        {
            SEGVIA* via = (SEGVIA*) item;
            text << _( "Via" ) << wxT( " " ) << via->m_NetCode;

            int shape = via->Shape();
            if( shape == VIA_ENTERREE )
                text << wxT(" ") << _( "Blind" );
            else if( shape == VIA_BORGNE )
                text << wxT(" ") << _("Buried");
            // else say nothing about normal vias

            net = aPcb->FindNet( via->m_NetCode );
            if( net )
            {
                text << wxT( " [" ) << net->m_Netname << wxT( "]" );
            }

            if( shape != VIA_NORMALE )
            {
                // say which layers, only two for now
                int topLayer;
                int botLayer;
                via->ReturnLayerPair( &topLayer, &botLayer );
                text << _( " on " ) << ReturnPcbLayerName( topLayer).Trim() << wxT(" <-> ")
                    << ReturnPcbLayerName( botLayer ).Trim();
            }
        }
        break;

    case TYPEMARQUEUR:
        text << _( "Marker" );
        break;

    case TYPECOTATION:
        text << _( "Dimension" ) << wxT( " \"" ) << ( (COTATION*) item )->GetText() << wxT( "\"" );
        break;

    case TYPEMIRE:
        text << _( "Mire" );          // @todo: extend text,  Mire is not an english word!
        break;

    case TYPEEDGEZONE:
        text << _( "Edge Zone" ) << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();  // @todo: extend text
        break;

    default:
        text << item->GetClass() << wxT( " Unexpected item type: BUG!!" );
        break;
    }

    return text;
}

/*****************************************/
const char** BOARD_ITEM::MenuIcon() const
/*****************************************/

/** return a specific icon pointer (an xpm icon)  for "this". Used in pop up menus
 * @return an icon pointer (can be NULL)
 */
{
    char**            xpm;
    const BOARD_ITEM* item = this;

    switch( item->Type() )
    {
    case PCB_EQUIPOT_STRUCT_TYPE:
        xpm = general_ratsnet_xpm;
        break;

    case TYPEMODULE:
        xpm = module_xpm;
        break;

    case TYPEPAD:
        xpm = pad_xpm;
        break;

    case TYPEDRAWSEGMENT:
        xpm = add_dashed_line_xpm;
        break;

    case TYPETEXTE:
        xpm = add_text_xpm;
        break;

    case TYPETEXTEMODULE:
        xpm = footprint_text_xpm;
        break;

    case TYPEEDGEMODULE:
        xpm = show_mod_edge_xpm;
        break;

    case TYPETRACK:
        xpm = showtrack_xpm;
        break;

    case TYPEZONE:
        xpm = add_zone_xpm;
        break;

    case TYPEVIA:
        xpm = pad_sketch_xpm;
        break;

    case TYPEMARQUEUR:
        xpm = pad_xpm;              // @todo: create and use marker xpm
        break;

    case TYPECOTATION:
        xpm = add_cotation_xpm;
        break;

    case TYPEMIRE:
        xpm = add_mires_xpm;
        break;

    case TYPEEDGEZONE:
        xpm = show_mod_edge_xpm;    // @todo: pcb edge xpm
        break;

    default:
        xpm = 0;
        break;
    }

    return (const char**) xpm;
}
<|endoftext|>


<commit_before>#ifndef AMGCL_UTIL_HPP
#define AMGCL_UTIL_HPP

/*
The MIT License

Copyright (c) 2012-2019 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   amgcl/util.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Various utilities.
 */

#include <iostream>
#include <iomanip>
#include <vector>
#include <array>
#include <string>
#include <set>
#include <complex>
#include <limits>
#include <stdexcept>
#include <cstddef>

// If asked explicitly, or if boost is available, enable
// using boost::propert_tree::ptree as amgcl parameters:
#ifndef AMGCL_NO_BOOST
#  include <boost/property_tree/ptree.hpp>
#endif

/* Performance measurement macros
 *
 * If AMGCL_PROFILING macro is defined at compilation, then AMGCL_TIC(name) and
 * AMGCL_TOC(name) macros correspond to prof.tic(name) and prof.toc(name).
 * amgcl::prof should be an instance of amgcl::profiler<> defined in a user
 * code similar to:
 * \code
 * namespace amgcl { profiler<> prof; }
 * \endcode
 * If AMGCL_PROFILING is undefined, then AMGCL_TIC and AMGCL_TOC are noop macros.
 */
#ifdef AMGCL_PROFILING
#  include <amgcl/profiler.hpp>
#  define AMGCL_TIC(name) amgcl::prof.tic(name);
#  define AMGCL_TOC(name) amgcl::prof.toc(name);
namespace amgcl { extern profiler<> prof; }
#else
#  ifndef AMGCL_TIC
#    define AMGCL_TIC(name)
#  endif
#  ifndef AMGCL_TOC
#    define AMGCL_TOC(name)
#  endif
#endif

#define AMGCL_DEBUG_SHOW(x)                                                    \
    std::cout << std::setw(20) << #x << ": "                                   \
              << std::setw(15) << std::setprecision(8) << std::scientific      \
              << (x) << std::endl

namespace amgcl {

/// Throws \p message if \p condition is not true.
template <class Condition, class Message>
void precondition(const Condition &condition, const Message &message) {
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4800)
#endif
    if (!condition) throw std::runtime_error(message);
#ifdef _MSC_VER
#  pragma warning(pop)
#endif
}

#ifndef AMGCL_NO_BOOST

#define AMGCL_PARAMS_IMPORT_VALUE(p, name)                                     \
    name( p.get(#name, params().name) )

#define AMGCL_PARAMS_IMPORT_CHILD(p, name)                                     \
    name( p.get_child(#name, amgcl::detail::empty_ptree()) )

#define AMGCL_PARAMS_EXPORT_VALUE(p, path, name)                               \
    p.put(std::string(path) + #name, name)

#define AMGCL_PARAMS_EXPORT_CHILD(p, path, name)                               \
    name.get(p, std::string(path) + #name + ".")

// Missing parameter action
#ifndef AMGCL_PARAM_MISSING
#  define AMGCL_PARAM_MISSING(name) (void)0
#endif

// Unknown parameter action
#ifndef AMGCL_PARAM_UNKNOWN
#  define AMGCL_PARAM_UNKNOWN(name)                                            \
      std::cerr << "AMGCL WARNING: unknown parameter " << name << std::endl
#endif

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names,
        const std::set<std::string> &opt_names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &n : opt_names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first) && !opt_names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

// Put parameter in form "key=value" into a boost::property_tree::ptree
inline void put(boost::property_tree::ptree &p, const std::string &param) {
    size_t eq_pos = param.find('=');
    if (eq_pos == std::string::npos)
        throw std::invalid_argument("param in amgcl::put() should have \"key=value\" format!");
    p.put(param.substr(0, eq_pos), param.substr(eq_pos + 1));
}

#endif

namespace detail {

#ifndef AMGCL_NO_BOOST
inline const boost::property_tree::ptree& empty_ptree() {
    static const boost::property_tree::ptree p;
    return p;
}
#endif

struct empty_params {
    empty_params() {}

#ifndef AMGCL_NO_BOOST
    empty_params(const boost::property_tree::ptree &p) {
        for(const auto &v : p) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
    void get(boost::property_tree::ptree&, const std::string&) const {}
#endif
};

} // namespace detail

// N-dimensional dense matrix
template <class T, int N>
class multi_array {
    static_assert(N > 0, "Wrong number of dimensions");

    public:
        template <class... I>
        multi_array(I... n) {
            static_assert(sizeof...(I) == N, "Wrong number of dimensions");
            buf.resize(init(n...));
        }

        size_t size() const {
            return buf.size();
        }

        int stride(int i) const {
            return strides[i];
        }

        template <class... I>
        T operator()(I... i) const {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        template <class... I>
        T& operator()(I... i) {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        const T* data() const {
            return buf.data();
        }

        T* data() {
            return buf.data();
        }
    private:
        std::array<int, N> strides;
        std::vector<T>  buf;

        template <class... I>
        int index(int i, I... tail) const {
            return strides[N - sizeof...(I) - 1] * i + index(tail...);
        }

        int index(int i) const {
            return strides[N-1] * i;
        }

        template <class... I>
        int init(int i, I... tail) {
            int size = init(tail...);
            strides[N - sizeof...(I) - 1] = size;
            return i * size;
        }

        int init(int i) {
            strides[N-1] = 1;
            return i;
        }
};

template <class T>
class circular_buffer {
    public:
        circular_buffer(size_t n) : start(0) {
            buf.reserve(n);
        }

        size_t size() const {
            return buf.size();
        }

        void push_back(const T &v) {
            if (buf.size() < buf.capacity()) {
                buf.push_back(v);
            } else {
                buf[start] = v;
                start = (start + 1) % buf.capacity();
            }
        }

        const T& operator[](size_t i) const {
            return buf[(start + i) % buf.capacity()];
        }

        T& operator[](size_t i) {
            return buf[(start + i) % buf.capacity()];
        }

        void clear() {
            buf.clear();
            start = 0;
        }

    private:
        size_t start;
        std::vector<T> buf;
};

namespace detail {

template <class T>
T eps(size_t n) {
    return 2 * std::numeric_limits<T>::epsilon() * n;
}

} // namespace detail

template <class T> struct is_complex : std::false_type {};
template <class T> struct is_complex< std::complex<T> > : std::true_type {};

inline std::string human_readable_memory(size_t bytes) {
    static const char *suffix[] = {"B", "K", "M", "G", "T"};

    int i = 0;
    double m = static_cast<double>(bytes);
    for(; i < 4 && m >= 1024.0; ++i, m /= 1024.0);

    std::ostringstream s;
    s << std::fixed << std::setprecision(2) << m << " " << suffix[i];
    return s.str();
}

namespace detail {

class non_copyable {
    protected:
        non_copyable() = default;
        ~non_copyable() = default;

        non_copyable(non_copyable const &) = delete;
        void operator=(non_copyable const &x) = delete;
};

} // namespace detail

} // namespace amgcl

namespace std {

// Read pointers from input streams.
// This allows to exchange pointers through boost::property_tree::ptree.
template <class T>
inline istream& operator>>(istream &is, T* &ptr) {
    std::ios_base::fmtflags ff(is.flags());

    size_t val;
    is >> std::hex >> val;

    ptr = reinterpret_cast<T*>(val);

    is.flags(ff);
    return is;
}

} // namespace std

#endif
<commit_msg>Allow to configure AMGCL_TIC and AMGCL_TOC<commit_after>#ifndef AMGCL_UTIL_HPP
#define AMGCL_UTIL_HPP

/*
The MIT License

Copyright (c) 2012-2019 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   amgcl/util.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Various utilities.
 */

#include <iostream>
#include <iomanip>
#include <vector>
#include <array>
#include <string>
#include <set>
#include <complex>
#include <limits>
#include <stdexcept>
#include <cstddef>

// If asked explicitly, or if boost is available, enable
// using boost::propert_tree::ptree as amgcl parameters:
#ifndef AMGCL_NO_BOOST
#  include <boost/property_tree/ptree.hpp>
#endif

/* Performance measurement macros
 *
 * If AMGCL_PROFILING macro is defined at compilation, then AMGCL_TIC(name) and
 * AMGCL_TOC(name) macros correspond to prof.tic(name) and prof.toc(name).
 * amgcl::prof should be an instance of amgcl::profiler<> defined in a user
 * code similar to:
 * \code
 * namespace amgcl { profiler<> prof; }
 * \endcode
 * If AMGCL_PROFILING is undefined, then AMGCL_TIC and AMGCL_TOC are noop macros.
 */
#ifdef AMGCL_PROFILING
#  if !defined(AMGCL_TIC) || !defined(AMGCL_TOC)
#    include <amgcl/profiler.hpp>
#    define AMGCL_TIC(name) amgcl::prof.tic(name);
#    define AMGCL_TOC(name) amgcl::prof.toc(name);
namespace amgcl { extern profiler<> prof; }
#  endif
#else
#  ifndef AMGCL_TIC
#    define AMGCL_TIC(name)
#  endif
#  ifndef AMGCL_TOC
#    define AMGCL_TOC(name)
#  endif
#endif

#define AMGCL_DEBUG_SHOW(x)                                                    \
    std::cout << std::setw(20) << #x << ": "                                   \
              << std::setw(15) << std::setprecision(8) << std::scientific      \
              << (x) << std::endl

namespace amgcl {

/// Throws \p message if \p condition is not true.
template <class Condition, class Message>
void precondition(const Condition &condition, const Message &message) {
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4800)
#endif
    if (!condition) throw std::runtime_error(message);
#ifdef _MSC_VER
#  pragma warning(pop)
#endif
}

#ifndef AMGCL_NO_BOOST

#define AMGCL_PARAMS_IMPORT_VALUE(p, name)                                     \
    name( p.get(#name, params().name) )

#define AMGCL_PARAMS_IMPORT_CHILD(p, name)                                     \
    name( p.get_child(#name, amgcl::detail::empty_ptree()) )

#define AMGCL_PARAMS_EXPORT_VALUE(p, path, name)                               \
    p.put(std::string(path) + #name, name)

#define AMGCL_PARAMS_EXPORT_CHILD(p, path, name)                               \
    name.get(p, std::string(path) + #name + ".")

// Missing parameter action
#ifndef AMGCL_PARAM_MISSING
#  define AMGCL_PARAM_MISSING(name) (void)0
#endif

// Unknown parameter action
#ifndef AMGCL_PARAM_UNKNOWN
#  define AMGCL_PARAM_UNKNOWN(name)                                            \
      std::cerr << "AMGCL WARNING: unknown parameter " << name << std::endl
#endif

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names,
        const std::set<std::string> &opt_names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &n : opt_names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first) && !opt_names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

// Put parameter in form "key=value" into a boost::property_tree::ptree
inline void put(boost::property_tree::ptree &p, const std::string &param) {
    size_t eq_pos = param.find('=');
    if (eq_pos == std::string::npos)
        throw std::invalid_argument("param in amgcl::put() should have \"key=value\" format!");
    p.put(param.substr(0, eq_pos), param.substr(eq_pos + 1));
}

#endif

namespace detail {

#ifndef AMGCL_NO_BOOST
inline const boost::property_tree::ptree& empty_ptree() {
    static const boost::property_tree::ptree p;
    return p;
}
#endif

struct empty_params {
    empty_params() {}

#ifndef AMGCL_NO_BOOST
    empty_params(const boost::property_tree::ptree &p) {
        for(const auto &v : p) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
    void get(boost::property_tree::ptree&, const std::string&) const {}
#endif
};

} // namespace detail

// N-dimensional dense matrix
template <class T, int N>
class multi_array {
    static_assert(N > 0, "Wrong number of dimensions");

    public:
        template <class... I>
        multi_array(I... n) {
            static_assert(sizeof...(I) == N, "Wrong number of dimensions");
            buf.resize(init(n...));
        }

        size_t size() const {
            return buf.size();
        }

        int stride(int i) const {
            return strides[i];
        }

        template <class... I>
        T operator()(I... i) const {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        template <class... I>
        T& operator()(I... i) {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        const T* data() const {
            return buf.data();
        }

        T* data() {
            return buf.data();
        }
    private:
        std::array<int, N> strides;
        std::vector<T>  buf;

        template <class... I>
        int index(int i, I... tail) const {
            return strides[N - sizeof...(I) - 1] * i + index(tail...);
        }

        int index(int i) const {
            return strides[N-1] * i;
        }

        template <class... I>
        int init(int i, I... tail) {
            int size = init(tail...);
            strides[N - sizeof...(I) - 1] = size;
            return i * size;
        }

        int init(int i) {
            strides[N-1] = 1;
            return i;
        }
};

template <class T>
class circular_buffer {
    public:
        circular_buffer(size_t n) : start(0) {
            buf.reserve(n);
        }

        size_t size() const {
            return buf.size();
        }

        void push_back(const T &v) {
            if (buf.size() < buf.capacity()) {
                buf.push_back(v);
            } else {
                buf[start] = v;
                start = (start + 1) % buf.capacity();
            }
        }

        const T& operator[](size_t i) const {
            return buf[(start + i) % buf.capacity()];
        }

        T& operator[](size_t i) {
            return buf[(start + i) % buf.capacity()];
        }

        void clear() {
            buf.clear();
            start = 0;
        }

    private:
        size_t start;
        std::vector<T> buf;
};

namespace detail {

template <class T>
T eps(size_t n) {
    return 2 * std::numeric_limits<T>::epsilon() * n;
}

} // namespace detail

template <class T> struct is_complex : std::false_type {};
template <class T> struct is_complex< std::complex<T> > : std::true_type {};

inline std::string human_readable_memory(size_t bytes) {
    static const char *suffix[] = {"B", "K", "M", "G", "T"};

    int i = 0;
    double m = static_cast<double>(bytes);
    for(; i < 4 && m >= 1024.0; ++i, m /= 1024.0);

    std::ostringstream s;
    s << std::fixed << std::setprecision(2) << m << " " << suffix[i];
    return s.str();
}

namespace detail {

class non_copyable {
    protected:
        non_copyable() = default;
        ~non_copyable() = default;

        non_copyable(non_copyable const &) = delete;
        void operator=(non_copyable const &x) = delete;
};

} // namespace detail

} // namespace amgcl

namespace std {

// Read pointers from input streams.
// This allows to exchange pointers through boost::property_tree::ptree.
template <class T>
inline istream& operator>>(istream &is, T* &ptr) {
    std::ios_base::fmtflags ff(is.flags());

    size_t val;
    is >> std::hex >> val;

    ptr = reinterpret_cast<T*>(val);

    is.flags(ff);
    return is;
}

} // namespace std

#endif
<|endoftext|>


<commit_before>//
// Matrix
//
#define MAX_ROWS MAX_STATES
#define MAX_COLS MAX_STATES
struct Matrix {
	int r, c;
	MatrixT m[MAX_ROWS][MAX_COLS];

	void init(int R, int C) { r = R, c = C; }
	void init(int R, int C, MatrixT *v) {
		r = R, c = C;
		for (int i = 0, p = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
				m[i][j] = v[p++];
	}
	void iden() { Clr(m); for (int i = 0; i < r; ++i) m[i][i] = 1; }
	void print() {
		for (int i = 0; i < r; ++i) {
			for (int j = 0; j < c; ++j) printf("%3d ", m[i][j]);
			puts("");
		}
	}

	MatrixT x[MAX_ROWS][MAX_COLS];
	Matrix &operator*=(const Matrix &y) {
		Clr(x);
		for (int i = 0; i < r; ++i)
			for (int k = 0; k < c; ++k)
				if (m[i][k] != 0)
					for (int j = 0; j < c; ++j)
						x[i][j] += m[i][k] * y.m[k][j];
		memcpy(m, x, sizeof(m)); return *this;
	}

	//
	// Gaussian elimination. Returns number of free variables.
	//
	int gaussian() {
		int fv = 0, nr, p, q;
		for (p=0, q=0; p < r && q < c; ++p, ++q) {
			for (nr = p; nr < r; ++nr) if (m[nr][q] != 0) break;
			if (nr == r) { ++fv; --p; continue; }
			if (nr != p) swap(m[p], m[nr]);
			for (int i = p + 1; i < r; ++i) {
				T fac = m[i][q] / m[p][q];
				for (int j = q + 1; j < c; ++j)
					m[i][j] -= m[p][j] * fac;
				m[i][q] = 0;
			}
		}
		return fv + c - q;
	}

	MatrixT memo[MAX_ROWS];
	bool vis[MAX_ROWS];
	MatrixT solve(int i) {
		if (vis[i]) return memo[i];
		MatrixT ans = m[i][c - 1] / m[i][i];
		for (int j = i + 1; j < r; ++j)
			if (m[i][j] != 0)
				ans -= solve(j) * m[i][j] / m[i][i];

		vis[i] = true;
		return memo[i] = ans;
	}
};

template<typename T>
void matrix_pow(Matrix &b, T e, Matrix &res) {
	res.init(b.r, b.c);	res.iden(); if (e == 0) return;
	while (true) {
		if (e & 1) res *= b;
		if ((e >>= 1) == 0) break;
		b *= b;
	}
}
<commit_msg>Minor fixup<commit_after>//
// Matrix
//
#define MAX_ROWS MAX_STATES
#define MAX_COLS MAX_STATES
struct Matrix {
	int r, c;
	MatrixT m[MAX_ROWS][MAX_COLS];

	void init(int R, int C) { r = R, c = C; }
	void init(int R, int C, const MatrixT *v) {
		r = R, c = C;
		for (int i = 0, p = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
				m[i][j] = v[p++];
	}
	void iden() { Clr(m); for (int i = 0; i < r; ++i) m[i][i] = 1; }
	void print() {
		for (int i = 0; i < r; ++i) {
			for (int j = 0; j < c; ++j) printf("%3d ", m[i][j]);
			puts("");
		}
	}

	MatrixT x[MAX_ROWS][MAX_COLS];
	Matrix &operator*=(const Matrix &y) {
		Clr(x);
		for (int i = 0; i < r; ++i)
			for (int k = 0; k < c; ++k)
				if (m[i][k] != 0)
					for (int j = 0; j < c; ++j)
						x[i][j] += m[i][k] * y.m[k][j];
		memcpy(m, x, sizeof(m)); return *this;
	}

	//
	// Gaussian elimination. Returns number of free variables.
	//
	int gaussian() {
		int fv = 0, nr, p, q;
		for (p=0, q=0; p < r && q < c; ++p, ++q) {
			for (nr = p; nr < r; ++nr) if (m[nr][q] != 0) break;
			if (nr == r) { ++fv; --p; continue; }
			if (nr != p) swap(m[p], m[nr]);
			for (int i = p + 1; i < r; ++i) {
				T fac = m[i][q] / m[p][q];
				for (int j = q + 1; j < c; ++j)
					m[i][j] -= m[p][j] * fac;
				m[i][q] = 0;
			}
		}
		return fv + c - q;
	}

	MatrixT memo[MAX_ROWS];
	bool vis[MAX_ROWS];
	MatrixT solve(int i) {
		if (vis[i]) return memo[i];
		MatrixT ans = m[i][c - 1] / m[i][i];
		for (int j = i + 1; j < r; ++j)
			if (m[i][j] != 0)
				ans -= solve(j) * m[i][j] / m[i][i];

		vis[i] = true;
		return memo[i] = ans;
	}
};

template<typename T>
void matrix_pow(Matrix &b, T e, Matrix &res) {
	res.init(b.r, b.c);	res.iden(); if (e == 0) return;
	while (true) {
		if (e & 1) res *= b;
		if ((e >>= 1) == 0) break;
		b *= b;
	}
}
<|endoftext|>


<commit_before>#pragma once

#include "../util/SharedPtr.hpp"
#include <allegro5/allegro.h>
#include <string>

namespace alcpp
{

class Bitmap : public SharedPtr<ALLEGRO_BITMAP>
{
public:
    Bitmap() {}
    Bitmap(ALLEGRO_BITMAP *bitmap, bool managed = true);
    Bitmap(int width, int height);
    Bitmap(Bitmap &parent, int x, int y, int width, int height);
    Bitmap(const std::string &filename);

    Bitmap Clone() const;

    int GetWidth() const;
    int GetHeight() const;

    bool IsLocked() const;
    bool IsSubBitmap() const;
    bool IsCompatible() const;

    void SetAsTarget() const;

    bool Load(const std::string &filename);
    bool Save(const std::string &filename) const;

    // TODO: create bitmap from primitives
};

}<commit_msg>minor fix<commit_after>#pragma once

#include "../util/SharedPtr.hpp"
#include <allegro5/allegro.h>
#include <string>

namespace alcpp
{

class Bitmap : public SharedPtr<ALLEGRO_BITMAP>
{
public:
    Bitmap() {}
    Bitmap(ALLEGRO_BITMAP *bitmap, bool retain = true);
    Bitmap(int width, int height);
    Bitmap(Bitmap &parent, int x, int y, int width, int height);
    Bitmap(const std::string &filename);

    Bitmap Clone() const;

    int GetWidth() const;
    int GetHeight() const;

    bool IsLocked() const;
    bool IsSubBitmap() const;
    bool IsCompatible() const;

    void SetAsTarget() const;

    bool Load(const std::string &filename);
    bool Save(const std::string &filename) const;

    // TODO: create bitmap from primitives
};

}<|endoftext|>