<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.6  2000/01/18 21:32:21  aruna1
 * XMLCh assigned to wchar_t
 *
 * Revision 1.5  1999/12/14 23:53:25  rahulj
 * Removed the offending Ctrl-M's from the commit message
 * logs which was giving packaging problems.
 *
 * PR:
 * Obtained from:
 * Submitted by:
 * Reviewed by:
 *
 * Revision 1.4  1999/11/23 02:00:12  rahulj
 * Code now works under HPUX 11. Tested inmemory message loader.
 * Revamped makefiles. Builds with both DCE threads as well as pthread libraries.
 *
 * Revision 1.3  1999/11/12 20:36:57  rahulj
 * Changed library name to xerces-c.lib.
 *
 * Revision 1.1.1.1  1999/11/09 01:07:34  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:23  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
// Define these away for this platform
// ---------------------------------------------------------------------------
#define PLATFORM_EXPORT
#define PLATFORM_IMPORT

// ---------------------------------------------------------------------------
// Indicate that we do not support native bools
// ---------------------------------------------------------------------------
#if defined(XML_HPUX_CC)
#define NO_NATIVE_BOOL
#endif

// ---------------------------------------------------------------------------
//  Define our version of the XML character
// ---------------------------------------------------------------------------
#ifndef INCLUDE_THIS_FILE
#define INCLUDE_THIS_FILE
#include <wchar.h>
#endif
typedef wchar_t XMLCh;
typedef unsigned short UTF16Ch;

// ---------------------------------------------------------------------------
//  Define unsigned 16 and 32 bits integers
// ---------------------------------------------------------------------------
typedef unsigned short  XMLUInt16;
typedef unsigned int    XMLUInt32;

// ---------------------------------------------------------------------------
//  Provide prototypes for some string methods that are not always available
//  on all platforms.
// ---------------------------------------------------------------------------
int stricmp(const char* const str1, const char* const  str2);
int strnicmp(const char* const str1, const char* const  str2, const unsigned int count);

// ---------------------------------------------------------------------------
//  The name of the DLL that is built by the HP CC version of the system.
// ---------------------------------------------------------------------------
const char* const XML4C_DLLName = "libxerces-c";
<commit_msg>Modified XMLCh to unsigned short<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.7  2000/01/18 22:37:20  aruna1
 * Modified XMLCh to unsigned short
 *
 * Revision 1.6  2000/01/18 21:32:21  aruna1
 * XMLCh assigned to wchar_t
 *
 * Revision 1.5  1999/12/14 23:53:25  rahulj
 * Removed the offending Ctrl-M's from the commit message
 * logs which was giving packaging problems.
 *
 * PR:
 * Obtained from:
 * Submitted by:
 * Reviewed by:
 *
 * Revision 1.4  1999/11/23 02:00:12  rahulj
 * Code now works under HPUX 11. Tested inmemory message loader.
 * Revamped makefiles. Builds with both DCE threads as well as pthread libraries.
 *
 * Revision 1.3  1999/11/12 20:36:57  rahulj
 * Changed library name to xerces-c.lib.
 *
 * Revision 1.1.1.1  1999/11/09 01:07:34  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:23  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
// Define these away for this platform
// ---------------------------------------------------------------------------
#define PLATFORM_EXPORT
#define PLATFORM_IMPORT

// ---------------------------------------------------------------------------
// Indicate that we do not support native bools
// ---------------------------------------------------------------------------
#if defined(XML_HPUX_CC)
#define NO_NATIVE_BOOL
#endif

// ---------------------------------------------------------------------------
//  Define our version of the XML character
// ---------------------------------------------------------------------------
#ifndef INCLUDE_THIS_FILE
#define INCLUDE_THIS_FILE
#include <wchar.h>
#endif
typedef unsigned short XMLCh;
typedef unsigned short UTF16Ch;

// ---------------------------------------------------------------------------
//  Define unsigned 16 and 32 bits integers
// ---------------------------------------------------------------------------
typedef unsigned short  XMLUInt16;
typedef unsigned int    XMLUInt32;

// ---------------------------------------------------------------------------
//  Provide prototypes for some string methods that are not always available
//  on all platforms.
// ---------------------------------------------------------------------------
int stricmp(const char* const str1, const char* const  str2);
int strnicmp(const char* const str1, const char* const  str2, const unsigned int count);

// ---------------------------------------------------------------------------
//  The name of the DLL that is built by the HP CC version of the system.
// ---------------------------------------------------------------------------
const char* const XML4C_DLLName = "libxerces-c";
<|endoftext|>


<commit_before>#ifndef _PROPHY_PROPHY_HPP
#define _PROPHY_PROPHY_HPP

#include <stdint.h>

namespace prophy
{

inline void swap(uint8_t&)
{ }

inline void swap(uint16_t& in)
{
    in = (in << 8) | (in >> 8);
}

inline void swap(uint32_t& in)
{
    in = ((in << 8) & 0xFF00FF00) | ((in >> 8) & 0x00FF00FF);
    in = (in << 16) | (in >> 16);
}

inline void swap(uint64_t& in)
{
    in = ((in << 8) & 0xFF00FF00FF00FF00ULL ) | ((in >> 8) & 0x00FF00FF00FF00FFULL );
    in = ((in << 16) & 0xFFFF0000FFFF0000ULL ) | ((in >> 16) & 0x0000FFFF0000FFFFULL );
    in = (in << 32) | (in >> 32);
}

inline void swap(int8_t&)
{ }

inline void swap(int16_t& in)
{
    swap(*static_cast<uint16_t*>(static_cast<void*>(&in)));
}

inline void swap(int32_t& in)
{
    swap(*static_cast<uint32_t*>(static_cast<void*>(&in)));
}

inline void swap(int64_t& in)
{
    swap(*static_cast<uint64_t*>(static_cast<void*>(&in)));
}

inline void swap(float& in)
{
    swap(*static_cast<uint32_t*>(static_cast<void*>(&in)));
}

inline void swap(double& in)
{
    swap(*static_cast<uint64_t*>(static_cast<void*>(&in)));
}

template <typename Tp>
struct alignment
{
    struct finder
    {
        char align;
        Tp t;
    };
    enum { value = sizeof(finder) - sizeof(Tp) };
};

template <typename Tp>
inline Tp* align(Tp* ptr)
{
    enum { mask = alignment<Tp>::value - 1 };
    return reinterpret_cast<Tp*>((reinterpret_cast<uintptr_t>(ptr) + mask) & ~uintptr_t(mask));
}

template <typename To, typename From>
inline To cast(From from)
{
    return align(static_cast<To>(static_cast<void*>(from)));
}

template <typename Tp>
inline Tp* swap_n_fixed(Tp* first, size_t n)
{
    while (n--)
    {
        swap(*first);
        ++first;
    }
    return first;
}

template <typename Tp>
inline Tp* swap_n_dynamic(Tp* first, size_t n)
{
    while (n--)
    {
        first = swap(*first);
    }
    return first;
}

} // namespace prophy

#endif  /* _PROPHY_PROPHY_HPP */
<commit_msg>double static cast refactored out<commit_after>#ifndef _PROPHY_PROPHY_HPP
#define _PROPHY_PROPHY_HPP

#include <stdint.h>

namespace prophy
{

inline void swap(uint8_t&)
{ }

inline void swap(uint16_t& in)
{
    in = (in << 8) | (in >> 8);
}

inline void swap(uint32_t& in)
{
    in = ((in << 8) & 0xFF00FF00) | ((in >> 8) & 0x00FF00FF);
    in = (in << 16) | (in >> 16);
}

inline void swap(uint64_t& in)
{
    in = ((in << 8) & 0xFF00FF00FF00FF00ULL ) | ((in >> 8) & 0x00FF00FF00FF00FFULL );
    in = ((in << 16) & 0xFFFF0000FFFF0000ULL ) | ((in >> 16) & 0x0000FFFF0000FFFFULL );
    in = (in << 32) | (in >> 32);
}

inline void swap(int8_t&)
{ }

inline void swap(int16_t& in)
{
    swap(reinterpret_cast<uint16_t&>(in));
}

inline void swap(int32_t& in)
{
    swap(reinterpret_cast<uint32_t&>(in));
}

inline void swap(int64_t& in)
{
    swap(reinterpret_cast<uint64_t&>(in));
}

inline void swap(float& in)
{
    swap(reinterpret_cast<uint32_t&>(in));
}

inline void swap(double& in)
{
    swap(reinterpret_cast<uint64_t&>(in));
}

template <typename Tp>
struct alignment
{
    struct finder
    {
        char align;
        Tp t;
    };
    enum { value = sizeof(finder) - sizeof(Tp) };
};

template <typename Tp>
inline Tp* align(Tp* ptr)
{
    enum { mask = alignment<Tp>::value - 1 };
    return reinterpret_cast<Tp*>((reinterpret_cast<uintptr_t>(ptr) + mask) & ~uintptr_t(mask));
}

template <typename To, typename From>
inline To cast(From from)
{
    return align(static_cast<To>(static_cast<void*>(from)));
}

template <typename Tp>
inline Tp* swap_n_fixed(Tp* first, size_t n)
{
    while (n--)
    {
        swap(*first);
        ++first;
    }
    return first;
}

template <typename Tp>
inline Tp* swap_n_dynamic(Tp* first, size_t n)
{
    while (n--)
    {
        first = swap(*first);
    }
    return first;
}

} // namespace prophy

#endif  /* _PROPHY_PROPHY_HPP */
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>

// Loriano: let's try Armadillo quick code
#include <armadillo>

#define ENTDIM 8
#define COORDIM (ENTDIM-2)
#define PARAMDIM 5

namespace
{
  int numofline (const char * fname)
  {
    int number_of_lines = 0;
    std::string line;
    std::ifstream myfile(fname);

    while (std::getline(myfile, line))
      ++number_of_lines;

    myfile.close();

    return number_of_lines;
  }
}

int main (int argc, char ** argv)
{
  if (argc != 2)
  {
    std::cerr << "usage: " << argv[0] << " coordinatesfile " << std::endl;
    return 1;
  }

  int num_of_line = numofline(argv[1]);
  std::cout << "file has " << num_of_line << " line " << std::endl;
  int num_of_ent = (num_of_line-1)/ENTDIM;
  std::cout << "  " << num_of_ent << " entries " << std::endl;

  // non perfomante ma easy to go
  double ** param_mtx = new double *[num_of_ent];
  double ** coord_mtx = new double *[num_of_ent];
  for (int i = 0; i < num_of_ent; ++i)
  {
    coord_mtx[i] = new double[3*COORDIM];
    param_mtx[i] = new double[PARAMDIM];
  }

  // leggere file coordinate tracce simulate plus parametri
  std::string line;
  std::ifstream mytfp;
  mytfp.open (argv[1], std::ios::in);

  std::getline (mytfp, line);
  //std::cout << line << std::endl;

  for (int i = 0; i < num_of_ent; ++i)
  {
    int fake1, fake2;
    mytfp >> fake1 >> fake2 ;
#ifdef DEBUG
    std::cout << fake1 << " " << fake2 << std::endl;
#endif
    for (int j = 0; j < COORDIM; ++j)
    {
      int a, b, c;
      mytfp >> coord_mtx[i][j*3] >>
               coord_mtx[i][j*3+1] >>
               coord_mtx[i][j*3+2] >>
               a >> b >> c;
    }
    mytfp >> param_mtx[i][0] >>
             param_mtx[i][1] >>
             param_mtx[i][2] >>
             param_mtx[i][3] >>
             param_mtx[i][4];
  }

  mytfp.close();

#ifdef DEBUG
  for (int i = 0; i < num_of_ent; ++i)
  {
    for (int j = 0; j < COORDIM; ++j)
    {
      std::cout << coord_mtx[i][j*3] << " " <<
                   coord_mtx[i][j*3+1] << " " <<
                   coord_mtx[i][j*3+2] << std::endl;
    }
    std::cout << param_mtx[i][0] << " " <<
                 param_mtx[i][1] << " " <<
                 param_mtx[i][2] << " " <<
                 param_mtx[i][3] << " " <<
                 param_mtx[i][4] << std::endl;
  }
#endif

  double sum = 1.0e0;
  double coordm[3*COORDIM] = {0.0e0};
  double hc[3*COORDIM][3*COORDIM] = {0.0e0};

  for (int l=0; l<num_of_ent; ++l)
  {
    sum += 1.0e0;
    for (int i=0; i<(3*COORDIM); ++i)
      coordm[i] += (coord_mtx[l][i]-coordm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
    {
      for (int j=0; j<(3*COORDIM); ++j)
      {
        hc[i][j] += ((coord_mtx[l][i] - coordm[i])*
                     (coord_mtx[l][j] - coordm[j])-
                     (sum-1.0e0)*hc[i][j]/sum)/(sum-1.0e0);
      }
    }
  }

  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=i+1; j<(3*COORDIM); ++j)
      if (hc[i][j] != hc[j][i])
        std::cout << i << " " << j << " " <<
          hc[i][j] << " ERROR" << std::endl;;

  arma::mat hca = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=0; j<(3*COORDIM); ++j)
      hca(i,j) = hc[i][j];

  arma::vec eigval;
  arma::mat eigvec;

  arma::eig_sym(eigval, eigvec, hca);

  double totval = 0.0e0;
  for (int i=0; i<(3*COORDIM); ++i)
    totval += eigval(i);

  int j = 1;
  double totvar = 0.0e0;
  for (int i=(3*COORDIM-1); i>=0; --i)
  {
    if (j <= PARAMDIM)
      totvar += 100.0e0*(eigval(i)/totval);
    ++j;

    std::cout << i+1 << " ==> " << 100.0e0*(eigval(i)/totval) << std::endl;
  }
  std::cout << "PARAMDIM eigenvalues: " << totvar << std::endl;

  arma::mat hcai = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  hcai = hca.i();

  //std::cout << hca * hcai ;

  // and so on ...
  std::fill(coordm, &(coordm[3*COORDIM]), 0.0e0 );
  double paramm[PARAMDIM] = {0.0e0};
  double hcp[3*COORDIM][PARAMDIM] = {0.0e0};

  for (int l=0; l<num_of_ent; ++l)
  {
    sum += 1.0e0;
    for (int i=0; i<(3*COORDIM); ++i)
      coordm[i] += (coord_mtx[l][i]-coordm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
      paramm[i] += (param_mtx[l][i]-paramm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
    {
      for (int j=0; j<PARAMDIM; ++j)
      {
        hcp[i][j] += ((coord_mtx[l][i] - coordm[i])*
                     (param_mtx[l][j] - paramm[j])-
                     (sum-1.0e0)*hcp[i][j]/sum)/(sum-1.0e0);
      }
    }
  }

  // documento Annovi
  // calcolo matrice di correlazione traccie HC
  // diagonalizzo HC e determino A, matrice 5 autovettori principali (5 componenti pricipali)
  // A matrice rotazione che mi permette di calcolare la traslazione usando i paamtri di tracce
  // simulate.

  // documento ATLAS
  // calcolare V e data V calcolare inversa V e quindi C, matrice di rotazione
  // data C determinare il vettore di traslazione q
  // c plus q costanti PCA
  // write constants in a file

  for (int i = 0; i < num_of_ent; ++i)
  {
    delete(coord_mtx[i]);
    delete(param_mtx[i]);
  }
  delete(coord_mtx);
  delete(param_mtx);

  return 0;
}
<commit_msg>fast code/pseudocode (as in atlas tdr) to give an impression of armadillo API<commit_after>#include <iostream>
#include <fstream>
#include <string>

// Loriano: let's try Armadillo quick code
#include <armadillo>

#define ENTDIM 8
#define COORDIM (ENTDIM-2)
#define PARAMDIM 5

namespace
{
  int numofline (const char * fname)
  {
    int number_of_lines = 0;
    std::string line;
    std::ifstream myfile(fname);

    while (std::getline(myfile, line))
      ++number_of_lines;

    myfile.close();

    return number_of_lines;
  }
}

int main (int argc, char ** argv)
{
  if (argc != 2)
  {
    std::cerr << "usage: " << argv[0] << " coordinatesfile " << std::endl;
    return 1;
  }

  int num_of_line = numofline(argv[1]);
  std::cout << "file has " << num_of_line << " line " << std::endl;
  int num_of_ent = (num_of_line-1)/ENTDIM;
  std::cout << "  " << num_of_ent << " entries " << std::endl;

  // non perfomante ma easy to go
  double ** param_mtx = new double *[num_of_ent];
  double ** coord_mtx = new double *[num_of_ent];
  for (int i = 0; i < num_of_ent; ++i)
  {
    coord_mtx[i] = new double[3*COORDIM];
    param_mtx[i] = new double[PARAMDIM];
  }

  // leggere file coordinate tracce simulate plus parametri
  std::string line;
  std::ifstream mytfp;
  mytfp.open (argv[1], std::ios::in);

  std::getline (mytfp, line);
  //std::cout << line << std::endl;

  for (int i = 0; i < num_of_ent; ++i)
  {
    int fake1, fake2;
    mytfp >> fake1 >> fake2 ;
#ifdef DEBUG
    std::cout << fake1 << " " << fake2 << std::endl;
#endif
    for (int j = 0; j < COORDIM; ++j)
    {
      int a, b, c;
      mytfp >> coord_mtx[i][j*3] >>
               coord_mtx[i][j*3+1] >>
               coord_mtx[i][j*3+2] >>
               a >> b >> c;
    }
    mytfp >> param_mtx[i][0] >>
             param_mtx[i][1] >>
             param_mtx[i][2] >>
             param_mtx[i][3] >>
             param_mtx[i][4];
  }

  mytfp.close();

#ifdef DEBUG
  for (int i = 0; i < num_of_ent; ++i)
  {
    for (int j = 0; j < COORDIM; ++j)
    {
      std::cout << coord_mtx[i][j*3] << " " <<
                   coord_mtx[i][j*3+1] << " " <<
                   coord_mtx[i][j*3+2] << std::endl;
    }
    std::cout << param_mtx[i][0] << " " <<
                 param_mtx[i][1] << " " <<
                 param_mtx[i][2] << " " <<
                 param_mtx[i][3] << " " <<
                 param_mtx[i][4] << std::endl;
  }
#endif

  double sum = 1.0e0;
  double coordm[3*COORDIM];
  double hc[3*COORDIM][3*COORDIM];

  std::fill_n (coordm, (3*COORDIM), 0.0e0);
  std::fill_n (&(hc[0][0]), (3*COORDIM)*(3*COORDIM), 0.0e0);

  for (int l=0; l<num_of_ent; ++l)
  {
    sum += 1.0e0;
    for (int i=0; i<(3*COORDIM); ++i)
      coordm[i] += (coord_mtx[l][i]-coordm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
    {
      for (int j=0; j<(3*COORDIM); ++j)
      {
        hc[i][j] += ((coord_mtx[l][i] - coordm[i])*
                     (coord_mtx[l][j] - coordm[j])-
                     (sum-1.0e0)*hc[i][j]/sum)/(sum-1.0e0);
      }
    }
  }

  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=i+1; j<(3*COORDIM); ++j)
      if (hc[i][j] != hc[j][i])
        std::cout << i << " " << j << " " <<
          hc[i][j] << " ERROR" << std::endl;;

  arma::mat hca = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=0; j<(3*COORDIM); ++j)
      hca(i,j) = hc[i][j];

  arma::vec eigval;
  arma::mat eigvec;

  arma::eig_sym(eigval, eigvec, hca);

  double totval = 0.0e0;
  for (int i=0; i<(3*COORDIM); ++i)
    totval += eigval(i);

  int j = 1;
  double totvar = 0.0e0;
  for (int i=(3*COORDIM-1); i>=0; --i)
  {
    if (j <= PARAMDIM)
      totvar += 100.0e0*(eigval(i)/totval);
    ++j;

    std::cout << i+1 << " ==> " << 100.0e0*(eigval(i)/totval) << std::endl;
  }
  std::cout << "PARAMDIM eigenvalues: " << totvar << std::endl;

  arma::mat hcai = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  hcai = hca.i();

  //std::cout << hca * hcai ;

  // and so on ...
  double paramm[PARAMDIM];
  arma::mat hcap = arma::zeros<arma::mat>(3*COORDIM,PARAMDIM);

  std::fill_n(coordm, (3*COORDIM), 0.0e0 );
  std::fill_n(paramm, PARAMDIM, 0.0e0 );

  for (int l=0; l<num_of_ent; ++l)
  {
    sum += 1.0e0;
    for (int i=0; i<(3*COORDIM); ++i)
      coordm[i] += (coord_mtx[l][i]-coordm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
      paramm[i] += (param_mtx[l][i]-paramm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
    {
      for (int j=0; j<PARAMDIM; ++j)
      {
        hcap(i,j) += ((coord_mtx[l][i] - coordm[i])*
                      (param_mtx[l][j] - paramm[j])-
                      (sum-1.0e0)*hcap(i,j)/sum)/(sum-1.0e0);
      }
    }
  }

  arma::mat cmtx = arma::zeros<arma::mat>(PARAMDIM,3*COORDIM);

  for (int i=0; i<PARAMDIM; ++i)
    for (int l=0; l<(3*COORDIM); ++l)
      for (int m=0; m<(3*COORDIM); ++m)
        cmtx(i,l) += hcai(l,m) * hcap (m,i);

  std::cout << "C matrix: " << std::endl;
  std::cout << cmtx;

  double q[PARAMDIM];
  std::fill_n(q, PARAMDIM, 0.0e0 );

  //std::cout << cmtx;

  for (int i=0; i<PARAMDIM; ++i)
  {
    q[i] = paramm[i];
    for (int j=0; j<(3*COORDIM); ++j)
      q[i] -= cmtx(i,j)*coordm[j];
  }

  std::cout << "Q vector: " << std::endl;
  for (int i=0; i<PARAMDIM; ++i)
    std::cout << q[i] << std::endl;

  // documento Annovi
  // calcolo matrice di correlazione traccie HC
  // diagonalizzo HC e determino A, matrice 5 autovettori principali (5 componenti pricipali)
  // A matrice rotazione che mi permette di calcolare la traslazione usando i paamtri di tracce
  // simulate.

  // documento ATLAS
  // calcolare V e data V calcolare inversa V e quindi C, matrice di rotazione
  // data C determinare il vettore di traslazione q
  // c plus q costanti PCA
  // write constants in a file

  for (int i = 0; i < num_of_ent; ++i)
  {
    delete(coord_mtx[i]);
    delete(param_mtx[i]);
  }
  delete(coord_mtx);
  delete(param_mtx);

  return 0;
}
<|endoftext|>


<commit_before>/***********
AUTHORS:  Michael Katelman, Vijay Ganesh, Trevor Hansen, Dan Liew

BEGIN DATE: Oct, 2008

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

#include <gtest/gtest.h>
#include <stdio.h>
#include "stp/c_interface.h"

// FIXME: Pick a sensible testname that actually means something!
TEST(array_cvcl02, one)
{
  VC vc = vc_createValidityChecker();
  vc_setFlag(vc, 'n');
  vc_setFlag(vc, 'd');
  vc_setFlag(vc, 'p');

  Expr cvcl_array = vc_varExpr1(vc, "a", 32, 32);
  Expr i = vc_varExpr1(vc, "i", 0, 8);
  Expr i32 = vc_bvConcatExpr(
      vc, vc_bvConstExprFromStr(vc, "000000000000000000000000"), i);
  Expr no_underflow = vc_bvLeExpr(vc, vc_bvConstExprFromInt(vc, 32, 0), i32);
  Expr no_overflow = vc_bvLeExpr(vc, i32, vc_bvConstExprFromInt(vc, 32, 9));
  Expr in_bounds = vc_andExpr(vc, no_underflow, no_overflow);
  Expr a_of_i = vc_bvSignExtend(vc, vc_readExpr(vc, cvcl_array, i32), 32);
  Expr a_of_i_eq_11 = vc_eqExpr(vc, vc_bvConcatExpr(vc, i32, a_of_i),
                                vc_bvConstExprFromInt(vc, 64, 11));

  vc_assertFormula(vc, in_bounds);
  vc_assertFormula(vc, a_of_i_eq_11);
  vc_query(vc, vc_falseExpr(vc));

  long long v;
  Expr pre = vc_bvConstExprFromInt(vc, 24, 0);
  int j;
  for (j = 0; j < 10; j++)
  {
    Expr exprj = vc_bvConstExprFromInt(vc, 8, j);
    Expr index = vc_bvConcatExpr(vc, pre, exprj);
    index = vc_simplify(vc, index);
    Expr a_of_j = vc_readExpr(vc, cvcl_array, index);
    Expr ce = vc_getCounterExample(vc, a_of_j);
  }
  vc_Destroy(vc);
  // vc_printCounterExample(vc);

  // FIXME: Actually test something
  // ASSERT_TRUE(false && "FIXME: Actually test something");
}
<commit_msg>Removing unused variable<commit_after>/***********
AUTHORS:  Michael Katelman, Vijay Ganesh, Trevor Hansen, Dan Liew

BEGIN DATE: Oct, 2008

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

#include <gtest/gtest.h>
#include <stdio.h>
#include "stp/c_interface.h"

// FIXME: Pick a sensible testname that actually means something!
TEST(array_cvcl02, one)
{
  VC vc = vc_createValidityChecker();
  vc_setFlag(vc, 'n');
  vc_setFlag(vc, 'd');
  vc_setFlag(vc, 'p');

  Expr cvcl_array = vc_varExpr1(vc, "a", 32, 32);
  Expr i = vc_varExpr1(vc, "i", 0, 8);
  Expr i32 = vc_bvConcatExpr(
      vc, vc_bvConstExprFromStr(vc, "000000000000000000000000"), i);
  Expr no_underflow = vc_bvLeExpr(vc, vc_bvConstExprFromInt(vc, 32, 0), i32);
  Expr no_overflow = vc_bvLeExpr(vc, i32, vc_bvConstExprFromInt(vc, 32, 9));
  Expr in_bounds = vc_andExpr(vc, no_underflow, no_overflow);
  Expr a_of_i = vc_bvSignExtend(vc, vc_readExpr(vc, cvcl_array, i32), 32);
  Expr a_of_i_eq_11 = vc_eqExpr(vc, vc_bvConcatExpr(vc, i32, a_of_i),
                                vc_bvConstExprFromInt(vc, 64, 11));

  vc_assertFormula(vc, in_bounds);
  vc_assertFormula(vc, a_of_i_eq_11);
  vc_query(vc, vc_falseExpr(vc));

  Expr pre = vc_bvConstExprFromInt(vc, 24, 0);
  int j;
  for (j = 0; j < 10; j++)
  {
    Expr exprj = vc_bvConstExprFromInt(vc, 8, j);
    Expr index = vc_bvConcatExpr(vc, pre, exprj);
    index = vc_simplify(vc, index);
    Expr a_of_j = vc_readExpr(vc, cvcl_array, index);
    Expr ce = vc_getCounterExample(vc, a_of_j);
  }
  vc_Destroy(vc);
  // vc_printCounterExample(vc);

  // FIXME: Actually test something
  // ASSERT_TRUE(false && "FIXME: Actually test something");
}
<|endoftext|>


<commit_before>//----------------------------  quadrature_test.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  quadrature_test.cc  ---------------------------

#include <iostream>
#include <fstream>

#include <base/logstream.h>
#include <base/quadrature_lib.h>
#include <cmath>

int main(int,char)
{
  ofstream logfile("quadrature_test.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  vector<Quadrature<1> *> quadratures(14);
  quadratures[2]=new QGauss2<1>();
  quadratures[3]=new QGauss3<1>();
  quadratures[4]=new QGauss4<1>();
  quadratures[5]=new QGauss5<1>();
  quadratures[6]=new QGauss6<1>();
  quadratures[7]=new QGauss7<1>();
  quadratures[8]=new QGauss8<1>();
  quadratures[9] = new QMidpoint<1>();
  quadratures[10] = new QTrapez<1>();
  quadratures[11] = new QSimpson<1>();
  quadratures[12] = new QMilne<1>();
  quadratures[13] = new QWeddle<1>();

  for (unsigned int n=2; n<14; ++n)
    {
      Quadrature<1> *quadrature=quadratures[n];
      const vector<Point<1> > &points=quadrature->get_points();
      const vector<double> &weights=quadrature->get_weights();

      deallog << "Quadrature no." << n;

      unsigned int i=0;
      double quadrature_int=0;
      double exact_int=0;
      double err = 0;
      do
	{
	  ++i;

	  quadrature_int=0;
	  for (unsigned int x=0; x<quadrature->n_quadrature_points; ++x)
	    quadrature_int+=pow(points[x](0), i)*weights[x];

					   // the exact integral is 1/(i+1)
	  exact_int=1./(i+1);
	  err = fabs(quadrature_int-exact_int);
	}
      while (err<1e-15);

				       // Uncomment here for testing
//      deallog << " (Error " << err << ")";
      deallog << " is exact for polynomials of degree " << i-1 << endl;
    }
}

<commit_msg>Check 2d Quadrature instead of 1d<commit_after>//----------------------------  quadrature_test.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  quadrature_test.cc  ---------------------------

#include <iostream>
#include <fstream>

#include <base/logstream.h>
#include <base/quadrature_lib.h>
#include <cmath>

int main(int,char)
{
  ofstream logfile("quadrature_test.output");
  deallog.attach(logfile);
  deallog.depth_console(0);
  vector<Quadrature<2> *> quadratures(14);
  quadratures[2]=new QGauss2<2>();
  quadratures[3]=new QGauss3<2>();
  quadratures[4]=new QGauss4<2>();
  quadratures[5]=new QGauss5<2>();
  quadratures[6]=new QGauss6<2>();
  quadratures[7]=new QGauss7<2>();
  quadratures[8]=new QGauss8<2>();
  quadratures[9] = new QMidpoint<2>();
  quadratures[10] = new QTrapez<2>();
  quadratures[11] = new QSimpson<2>();
  quadratures[12] = new QMilne<2>();
  quadratures[13] = new QWeddle<2>();

  for (unsigned int n=2; n<14; ++n)
    {
      Quadrature<2> *quadrature=quadratures[n];
      const vector<Point<2> > &points=quadrature->get_points();
      const vector<double> &weights=quadrature->get_weights();

      deallog << "Quadrature no." << n;

      unsigned int i=0;
      double quadrature_int=0;
      double exact_int=0;
      double err = 0;
      do
	{
	  ++i;

	  quadrature_int=0;

					   // Check the polynomial x^i*y^i

	  for (unsigned int x=0; x<quadrature->n_quadrature_points; ++x)
	    quadrature_int+=pow(points[x](0), i)*pow(points[x](1), i)*weights[x];

					   // the exact integral is 1/(i+1)
	  exact_int=1./(i+1)/(i+1);
	  err = fabs(quadrature_int-exact_int);
	}
      while (err<1e-15);

				       // Uncomment here for testing
//      deallog << " (Error " << err << ")";
      deallog << " is exact for polynomials of degree " << i-1 << endl;
    }
}

<|endoftext|>


<commit_before>#include "x86_64-Codegen.h"
#include "ASTNode.h"
#include "lib/Runtime.h"
#include "lib/SnowString.h"
#include "Internal.h"
#include <stdexcept>
#include <vector>
using namespace std;

#define __ m_Asm->
#define e__ entry_asm->

namespace snow {
namespace x86_64 {
	// stack_frame->`member'
	#define GET_STACK(member) (Address(rbp, (-(int)sizeof(StackFrame))+(int)offsetof(StackFrame, member)))

	// temporaries[id]
	#define GET_TEMPORARY(id) (Address(rbp, (-(int)sizeof(StackFrame))-(sizeof(VALUE)*(id+1))))

	// reg[index] (reg must contain a pointer to an array of values)
	#define GET_ARRAY_PTR(reg, index) (Address((reg), index * sizeof(VALUE)))

	static const Register* arg_regs[] = { &rdi, &rsi, &rdx, &rcx, &r8, &r9 };
	static const uint64_t num_arg_regs = 6;

	Codegen::Codegen(ast::FunctionDefinition& def) :
		snow::Codegen(def),
		m_NumLocals(0),
		m_NumStackArguments(0),
		m_NumTemporaries(0) {
		m_LocalMap = new LocalMap;
		m_Asm = new x86_64::Assembler;
		m_Return = new Label;
	}

	uint64_t Codegen::reserve_temporary() {
		if (m_FreeTemporaries.size() > 0) {
			uint64_t t = m_FreeTemporaries.back();
			m_FreeTemporaries.pop_back();
			return t;
		}
		return m_NumTemporaries++;
	}

	void Codegen::free_temporary(uint64_t id) {
		m_FreeTemporaries.push_back(id);
	}

	void Codegen::get_local(uint64_t id, const Register& reg) {
		ASSERT(!m_InGlobalScope);
		__ mov(GET_STACK(locals), reg);
		__ mov(GET_ARRAY_PTR(reg, id), reg);
	}

	void Codegen::set_local(const Register& reg, uint64_t id, const Register& tmp) {
		ASSERT(reg != tmp && "Cannot use source register as temporary storage!");
		ASSERT(!m_InGlobalScope);
		__ mov(GET_STACK(locals), tmp);
		__ mov(reg, GET_ARRAY_PTR(tmp, id));
	}

	Handle<CompiledCode> Codegen::compile(bool in_global_scope) {
		m_InGlobalScope = in_global_scope;

		RefPtr<x86_64::Assembler> entry_asm = new x86_64::Assembler;
		__ subasm(entry_asm);

		if (m_Def.arguments.size() > 0) {
			__ comment("copy arguments to locals");
			__ mov(GET_STACK(arguments), r8);
			__ mov(GET_STACK(locals), r9);
			size_t i = 0;
			for each (iter, m_Def.arguments) {
				auto local = m_LocalMap->define_local((*iter)->name);
				__ mov(GET_ARRAY_PTR(r8, i), rax);
				__ mov(rax, GET_ARRAY_PTR(r9, local));
				++i;
			}
		}

		__ comment("function body");
		compile(*m_Def.sequence);

		uint64_t return_temporary = reserve_temporary();
		__ comment("function exit");
		__ bind(m_Return);
		__ mov(rax, GET_TEMPORARY(return_temporary));
		__ call("snow_leave_scope");
		__ mov(GET_TEMPORARY(return_temporary), rax);
		__ leave();
		__ ret();

		// Compile the function entry, now that we know all the locals and
		// temporaries.
		{
			e__ comment("function entry");
			int stack_size = sizeof(StackFrame) + sizeof(VALUE)*(m_NumTemporaries + m_NumStackArguments);
			// maintain 16-byte stack alignment
			stack_size += stack_size % 16;
			e__ enter(stack_size);

			e__ mov(rbp, rsi);
			e__ sub(sizeof(StackFrame), rsi);
			e__ mov(rsi, rax);
			e__ sub((m_NumTemporaries+m_NumStackArguments)*sizeof(VALUE), rax);
			e__ mov(rax, GET_STACK(temporaries));
			e__ mov(m_NumTemporaries+m_NumStackArguments, GET_STACK(num_temporaries));
			e__ call("snow_enter_scope");
			e__ mov(nil(), rax);
		}

		Handle<CompiledCode> code = __ compile();
		code->set_local_map(m_LocalMap);
		for each (iter, m_Related) {
			code->add_related(*iter);
		}
		return code;
	}

	void Codegen::compile(ast::Literal& literal) {
		__ comment(std::string("literal: `")  + literal.string + std::string("'"));
		using ast::Literal;

		const char* str = literal.string.c_str();

		VALUE val = nil();

		switch (literal.type) {
			case Literal::INTEGER_DEC_TYPE:
				val = value(strtoll(str, NULL, 10));
				break;
			case Literal::INTEGER_HEX_TYPE:
				val = value(strtoll(str, NULL, 16));
				break;
			case Literal::INTEGER_BIN_TYPE:
				val = value(strtoll(str, NULL, 2));
				break;
			case Literal::FLOAT_TYPE:
				// TODO: Doubles
				val = value(strtof(str, NULL));
				break;
			case Literal::STRING_TYPE:
				val = new(kMalloc) String(str);
				break;
			case Literal::TRUE_TYPE:
				val = value(true);
				break;
			case Literal::FALSE_TYPE:
				val = value(false);
				break;
			case Literal::NIL_TYPE:
				val = nil();
				break;
			case Literal::SYMBOL_TYPE:
				val = symbol(str);
				break;
		}

		__ mov(val, rax);
	}

	void Codegen::compile(ast::Identifier& id) {
		__ comment(std::string("identifier: `") + value_to_string(id.name) + std::string("'"));
		if (!m_InGlobalScope && m_LocalMap->has_local(id.name)) {
			// It's a local from current scope...
			get_local(m_LocalMap->local(id.name), rax);
		} else {
			// THE PAIN! It's from a parent scope...
			__ mov(rbp, rdi);
			__ sub(sizeof(StackFrame), rdi);
			__ mov(id.name, rsi);
			__ mov(id.quiet, rdx);
			__ call("snow_get_local");
		}
	}

	void Codegen::compile(ast::Sequence& seq) {
		for each (iter, seq.nodes) {
			(*iter)->compile(*this);
		}
	}

	void Codegen::compile(ast::FunctionDefinition& def) {
		__ comment("function definition");
		RefPtr<Codegen> codegen = new Codegen(def);
		Handle<CompiledCode> code = codegen->compile();
		m_Related.push_back(code);
		VALUE func = new(kMalloc) Function(*code);
		__ mov(func, rdi);
		__ mov(GET_STACK(scope), rsi);
		__ call("snow_set_parent_scope");
		__ mov(func, rax);
	}

	void Codegen::compile(ast::Return& ret) {
		__ comment("return");
		if (ret.expression)
			ret.expression->compile(*this);
		else
			__ clear(rax);
		__ jmp(m_Return);
	}

	void Codegen::compile(ast::Assignment& assign) {
		assign.expression->compile(*this);
		__ comment(std::string("assignment: ") + value_to_string(assign.identifier->name));

		if (!m_InGlobalScope) {
			uint64_t l;
			if (m_LocalMap->has_local(assign.identifier->name))
				l = m_LocalMap->local(assign.identifier->name);
			else
				l = m_LocalMap->define_local(assign.identifier->name);

			set_local(rax, l);
		} else {
			__ mov(rbp, rdi);
			__ sub(sizeof(StackFrame), rdi);
			__ mov(assign.identifier->name, rsi);
			__ mov(rax, rdx);
			__ call("snow_set_local");
		}
	}

	void Codegen::compile(ast::IfCondition& cond) {
		RefPtr<Label> test_cond = new Label;
		RefPtr<Label> after = new Label;

		__ bind(test_cond);
		__ comment("if cond");
		cond.expression->compile(*this);
		__ mov(rax, rdi);
		__ call("snow_eval_truth");
		__ cmp(cond.unless, rax);
		__ j(CC_EQUAL, after);
		__ comment("if body");
		cond.if_true->compile(*this);
		__ bind(after);
	}

	void Codegen::compile(ast::IfElseCondition& cond) {
		RefPtr<Label> test_cond = new Label;
		RefPtr<Label> if_true = new Label;
		RefPtr<Label> if_false = new Label;
		RefPtr<Label> after = new Label;

		__ bind(test_cond);
		__ comment("if-else cond");
		cond.expression->compile(*this);
		__ mov(rax, rdi);
		__ call("snow_eval_truth");
		__ cmp(cond.unless, rax);
		__ j(CC_EQUAL, if_false);
		__ bind(if_true);
		__ comment("if true");
		cond.if_true->compile(*this);
		__ jmp(after);
		__ bind(if_false);
		__ comment("if false");
		cond.if_false->compile(*this);
		__ bind(after);
	}

	void Codegen::compile(ast::Call& call) {
		auto self_tmp = reserve_temporary();

		__ comment("self for call");
		call.self->compile(*this);
		__ mov(rax, GET_TEMPORARY(self_tmp));

		// evaluate arguments and store temporaries
		auto num_args = call.arguments->length();
		uint64_t args_tmp[num_args];
		size_t i = 0;
		for each (arg_iter, call.arguments->nodes) {
			args_tmp[i] = reserve_temporary();
			__ comment(string_printf("argument %d", i));
			(*arg_iter)->compile(*this);
			__ mov(rax, GET_TEMPORARY(args_tmp[i]));
			++i;
		}

		auto function_tmp = self_tmp;
		if (call.member) {
			__ comment("method call");
			function_tmp = reserve_temporary();
			__ mov(GET_TEMPORARY(self_tmp), rdi);
			__ mov(call.member->name, rsi);
			__ call("snow_get");
			__ mov(rax, GET_TEMPORARY(function_tmp));
			__ mov(GET_TEMPORARY(self_tmp), rdi);
		} else {
			__ comment("closure call");
			__ clear(rdi);         // "self" is NULL for closures
		}

		__ mov(GET_TEMPORARY(function_tmp), rsi);
		__ mov(num_args, rdx);

		bool rsp_in_rbx = false;
		for (size_t i = 0; i < num_args; ++i) {
			const size_t arg_offset = i + 3;

			if (arg_offset < num_arg_regs) {
				__ mov(GET_TEMPORARY(args_tmp[i]), *arg_regs[arg_offset]);
			} else {
				const size_t stack_offset = arg_offset - num_arg_regs;
				if (m_NumStackArguments < stack_offset)
					m_NumStackArguments = stack_offset;

				__ mov(GET_TEMPORARY(args_tmp[i]), rax);

				if (!rsp_in_rbx) {
					__ mov(rsp, rbx);
					rsp_in_rbx = true;
				}
				__ mov(rax, Address(rbx, stack_offset*sizeof(VALUE)));
			}

			free_temporary(args_tmp[i]);
		}

		if (self_tmp == function_tmp)
			free_temporary(self_tmp);
		else {
			free_temporary(self_tmp);
			free_temporary(function_tmp);
		}

		// finally!
		__ clear(rax);
		__ call("snow_call");
	}

	void Codegen::compile(ast::Get& get) {
		__ comment(std::string("get `") + value_to_string(get.member->name) + "'");
		get.self->compile(*this);
		__ mov(rax, rdi);
		__ mov(get.member->name, rsi);
		__ call("snow_get");
	}

	void Codegen::compile(ast::Set& set) {
		__ comment(std::string("set `") + value_to_string(set.member->name) + "'");
		set.expression->compile(*this);
		auto tmp = reserve_temporary();
		__ mov(rax, GET_TEMPORARY(tmp));
		set.self->compile(*this);
		__ mov(rax, rdi);
		__ mov(set.member->name, rsi);
		__ mov(GET_TEMPORARY(tmp), rdx);
		__ call("snow_set");
		free_temporary(tmp);
	}

	void Codegen::compile(ast::Loop& loop) {
		RefPtr<Label> test_cond = new Label;
		RefPtr<Label> body = new Label;
		RefPtr<Label> after = new Label;

		__ bind(test_cond);
		__ comment("loop cond");
		loop.expression->compile(*this);
		__ mov(rax, rdi);
		__ call("snow_eval_truth");
		__ cmp(0, rax);
		__ j(CC_EQUAL, after);
		__ bind(body);
		__ comment("loop body");
		loop.while_true->compile(*this);
		__ jmp(test_cond);
		__ bind(after);
	}

	void Codegen::compile(ast::Self&) {
		__ mov(GET_STACK(self), rax);
	}

	void Codegen::compile(ast::It&) {
		__ mov(GET_STACK(it), rax);
	}
}
}
<commit_msg>x86_64 codegen: Fixed stack frame initialization and exit<commit_after>#include "x86_64-Codegen.h"
#include "ASTNode.h"
#include "lib/Runtime.h"
#include "lib/SnowString.h"
#include "Internal.h"
#include <stdexcept>
#include <vector>
using namespace std;

#define __ m_Asm->
#define e__ entry_asm->

namespace snow {
namespace x86_64 {
	// stack_frame->`member'
	#define GET_STACK(member) (Address(rbp, (-(int)sizeof(StackFrame))+(int)offsetof(StackFrame, member)))

	// temporaries[id]
	#define GET_TEMPORARY(id) (Address(rbp, (-(int)sizeof(StackFrame))-(sizeof(VALUE)*(id+1))))

	// reg[index] (reg must contain a pointer to an array of values)
	#define GET_ARRAY_PTR(reg, index) (Address((reg), index * sizeof(VALUE)))

	static const Register* arg_regs[] = { &rdi, &rsi, &rdx, &rcx, &r8, &r9 };
	static const uint64_t num_arg_regs = 6;

	Codegen::Codegen(ast::FunctionDefinition& def) :
		snow::Codegen(def),
		m_NumLocals(0),
		m_NumStackArguments(0),
		m_NumTemporaries(0) {
		m_LocalMap = new LocalMap;
		m_Asm = new x86_64::Assembler;
		m_Return = new Label;
	}

	uint64_t Codegen::reserve_temporary() {
		if (m_FreeTemporaries.size() > 0) {
			uint64_t t = m_FreeTemporaries.back();
			m_FreeTemporaries.pop_back();
			return t;
		}
		return m_NumTemporaries++;
	}

	void Codegen::free_temporary(uint64_t id) {
		m_FreeTemporaries.push_back(id);
	}

	void Codegen::get_local(uint64_t id, const Register& reg) {
		ASSERT(!m_InGlobalScope);
		__ mov(GET_STACK(locals), reg);
		__ mov(GET_ARRAY_PTR(reg, id), reg);
	}

	void Codegen::set_local(const Register& reg, uint64_t id, const Register& tmp) {
		ASSERT(reg != tmp && "Cannot use source register as temporary storage!");
		ASSERT(!m_InGlobalScope);
		__ mov(GET_STACK(locals), tmp);
		__ mov(reg, GET_ARRAY_PTR(tmp, id));
	}

	Handle<CompiledCode> Codegen::compile(bool in_global_scope) {
		m_InGlobalScope = in_global_scope;

		RefPtr<x86_64::Assembler> entry_asm = new x86_64::Assembler;
		__ subasm(entry_asm);

		if (m_Def.arguments.size() > 0) {
			__ comment("copy arguments to locals");
			__ mov(GET_STACK(arguments), r8);
			__ mov(GET_STACK(locals), r9);
			size_t i = 0;
			for each (iter, m_Def.arguments) {
				auto local = m_LocalMap->define_local((*iter)->name);
				__ mov(GET_ARRAY_PTR(r8, i), rax);
				__ mov(rax, GET_ARRAY_PTR(r9, local));
				++i;
			}
		}

		__ comment("function body");
		compile(*m_Def.sequence);

		uint64_t return_temporary = reserve_temporary();
		__ comment("function exit");
		__ bind(m_Return);
		__ mov(rax, GET_TEMPORARY(return_temporary));
		if (m_InGlobalScope) {
			// Preserve objects in global scope for GC
			__ call("snow_leave_global_subscope");
		} else {
			__ call("snow_leave_scope");
		}
		__ mov(GET_TEMPORARY(return_temporary), rax);
		__ leave();
		__ ret();

		// Compile the function entry, now that we know all the locals and
		// temporaries.
		{
			e__ comment("function entry");
			int stack_size = sizeof(StackFrame) + sizeof(VALUE)*(m_NumTemporaries + m_NumStackArguments);
			// maintain 16-byte stack alignment
			stack_size += stack_size % 16;
			e__ enter(stack_size);

			e__ mov(rbp, rsi);
			e__ sub(sizeof(StackFrame), rsi);
			e__ mov(rsi, rax);
			e__ sub((m_NumTemporaries+m_NumStackArguments)*sizeof(VALUE), rax);
			e__ mov(rax, GET_STACK(temporaries));
			e__ mov(m_NumTemporaries+m_NumStackArguments, rax);
			e__ mov(rax, GET_STACK(num_temporaries));
			e__ call("snow_enter_scope");
			e__ mov(nil(), rax);
		}

		Handle<CompiledCode> code = __ compile();
		code->set_local_map(m_LocalMap);
		for each (iter, m_Related) {
			code->add_related(*iter);
		}
		return code;
	}

	void Codegen::compile(ast::Literal& literal) {
		__ comment(std::string("literal: `")  + literal.string + std::string("'"));
		using ast::Literal;

		const char* str = literal.string.c_str();

		VALUE val = nil();

		switch (literal.type) {
			case Literal::INTEGER_DEC_TYPE:
				val = value(strtoll(str, NULL, 10));
				break;
			case Literal::INTEGER_HEX_TYPE:
				val = value(strtoll(str, NULL, 16));
				break;
			case Literal::INTEGER_BIN_TYPE:
				val = value(strtoll(str, NULL, 2));
				break;
			case Literal::FLOAT_TYPE:
				// TODO: Doubles
				val = value(strtof(str, NULL));
				break;
			case Literal::STRING_TYPE:
				val = new(kMalloc) String(str);
				break;
			case Literal::TRUE_TYPE:
				val = value(true);
				break;
			case Literal::FALSE_TYPE:
				val = value(false);
				break;
			case Literal::NIL_TYPE:
				val = nil();
				break;
			case Literal::SYMBOL_TYPE:
				val = symbol(str);
				break;
		}

		__ mov(val, rax);
	}

	void Codegen::compile(ast::Identifier& id) {
		__ comment(std::string("identifier: `") + value_to_string(id.name) + std::string("'"));
		if (!m_InGlobalScope && m_LocalMap->has_local(id.name)) {
			// It's a local from current scope...
			get_local(m_LocalMap->local(id.name), rax);
		} else {
			// THE PAIN! It's from a parent scope...
			__ mov(rbp, rdi);
			__ sub(sizeof(StackFrame), rdi);
			__ mov(id.name, rsi);
			__ mov(id.quiet, rdx);
			__ call("snow_get_local");
		}
	}

	void Codegen::compile(ast::Sequence& seq) {
		for each (iter, seq.nodes) {
			(*iter)->compile(*this);
		}
	}

	void Codegen::compile(ast::FunctionDefinition& def) {
		__ comment("function definition");
		RefPtr<Codegen> codegen = new Codegen(def);
		Handle<CompiledCode> code = codegen->compile();
		m_Related.push_back(code);
		VALUE func = new(kMalloc) Function(*code);
		__ mov(func, rdi);
		__ mov(GET_STACK(scope), rsi);
		__ call("snow_set_parent_scope");
		__ mov(func, rax);
	}

	void Codegen::compile(ast::Return& ret) {
		__ comment("return");
		if (ret.expression)
			ret.expression->compile(*this);
		else
			__ clear(rax);
		__ jmp(m_Return);
	}

	void Codegen::compile(ast::Assignment& assign) {
		assign.expression->compile(*this);
		__ comment(std::string("assignment: ") + value_to_string(assign.identifier->name));

		if (!m_InGlobalScope) {
			uint64_t l;
			if (m_LocalMap->has_local(assign.identifier->name))
				l = m_LocalMap->local(assign.identifier->name);
			else
				l = m_LocalMap->define_local(assign.identifier->name);

			set_local(rax, l);
		} else {
			__ mov(rbp, rdi);
			__ sub(sizeof(StackFrame), rdi);
			__ mov(assign.identifier->name, rsi);
			__ mov(rax, rdx);
			__ call("snow_set_local");
		}
	}

	void Codegen::compile(ast::IfCondition& cond) {
		RefPtr<Label> test_cond = new Label;
		RefPtr<Label> after = new Label;

		__ bind(test_cond);
		__ comment("if cond");
		cond.expression->compile(*this);
		__ mov(rax, rdi);
		__ call("snow_eval_truth");
		__ cmp(cond.unless, rax);
		__ j(CC_EQUAL, after);
		__ comment("if body");
		cond.if_true->compile(*this);
		__ bind(after);
	}

	void Codegen::compile(ast::IfElseCondition& cond) {
		RefPtr<Label> test_cond = new Label;
		RefPtr<Label> if_true = new Label;
		RefPtr<Label> if_false = new Label;
		RefPtr<Label> after = new Label;

		__ bind(test_cond);
		__ comment("if-else cond");
		cond.expression->compile(*this);
		__ mov(rax, rdi);
		__ call("snow_eval_truth");
		__ cmp(cond.unless, rax);
		__ j(CC_EQUAL, if_false);
		__ bind(if_true);
		__ comment("if true");
		cond.if_true->compile(*this);
		__ jmp(after);
		__ bind(if_false);
		__ comment("if false");
		cond.if_false->compile(*this);
		__ bind(after);
	}

	void Codegen::compile(ast::Call& call) {
		auto self_tmp = reserve_temporary();

		__ comment("self for call");
		call.self->compile(*this);
		__ mov(rax, GET_TEMPORARY(self_tmp));

		// evaluate arguments and store temporaries
		auto num_args = call.arguments->length();
		uint64_t args_tmp[num_args];
		size_t i = 0;
		for each (arg_iter, call.arguments->nodes) {
			args_tmp[i] = reserve_temporary();
			__ comment(string_printf("argument %d", i));
			(*arg_iter)->compile(*this);
			__ mov(rax, GET_TEMPORARY(args_tmp[i]));
			++i;
		}

		auto function_tmp = self_tmp;
		if (call.member) {
			__ comment("method call");
			function_tmp = reserve_temporary();
			__ mov(GET_TEMPORARY(self_tmp), rdi);
			__ mov(call.member->name, rsi);
			__ call("snow_get");
			__ mov(rax, GET_TEMPORARY(function_tmp));
			__ mov(GET_TEMPORARY(self_tmp), rdi);
		} else {
			__ comment("closure call");
			__ clear(rdi);         // "self" is NULL for closures
		}

		__ mov(GET_TEMPORARY(function_tmp), rsi);
		__ mov(num_args, rdx);

		bool rsp_in_rbx = false;
		for (size_t i = 0; i < num_args; ++i) {
			const size_t arg_offset = i + 3;

			if (arg_offset < num_arg_regs) {
				__ mov(GET_TEMPORARY(args_tmp[i]), *arg_regs[arg_offset]);
			} else {
				const size_t stack_offset = arg_offset - num_arg_regs;
				if (m_NumStackArguments < stack_offset)
					m_NumStackArguments = stack_offset;

				__ mov(GET_TEMPORARY(args_tmp[i]), rax);

				if (!rsp_in_rbx) {
					__ mov(rsp, rbx);
					rsp_in_rbx = true;
				}
				__ mov(rax, Address(rbx, stack_offset*sizeof(VALUE)));
			}

			free_temporary(args_tmp[i]);
		}

		if (self_tmp == function_tmp)
			free_temporary(self_tmp);
		else {
			free_temporary(self_tmp);
			free_temporary(function_tmp);
		}

		// finally!
		__ clear(rax);
		__ call("snow_call");
	}

	void Codegen::compile(ast::Get& get) {
		__ comment(std::string("get `") + value_to_string(get.member->name) + "'");
		get.self->compile(*this);
		__ mov(rax, rdi);
		__ mov(get.member->name, rsi);
		__ call("snow_get");
	}

	void Codegen::compile(ast::Set& set) {
		__ comment(std::string("set `") + value_to_string(set.member->name) + "'");
		set.expression->compile(*this);
		auto tmp = reserve_temporary();
		__ mov(rax, GET_TEMPORARY(tmp));
		set.self->compile(*this);
		__ mov(rax, rdi);
		__ mov(set.member->name, rsi);
		__ mov(GET_TEMPORARY(tmp), rdx);
		__ call("snow_set");
		free_temporary(tmp);
	}

	void Codegen::compile(ast::Loop& loop) {
		RefPtr<Label> test_cond = new Label;
		RefPtr<Label> body = new Label;
		RefPtr<Label> after = new Label;

		__ bind(test_cond);
		__ comment("loop cond");
		loop.expression->compile(*this);
		__ mov(rax, rdi);
		__ call("snow_eval_truth");
		__ cmp(0, rax);
		__ j(CC_EQUAL, after);
		__ bind(body);
		__ comment("loop body");
		loop.while_true->compile(*this);
		__ jmp(test_cond);
		__ bind(after);
	}

	void Codegen::compile(ast::Self&) {
		__ mov(GET_STACK(self), rax);
	}

	void Codegen::compile(ast::It&) {
		__ mov(GET_STACK(it), rax);
	}
}
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/ui/gl/gl_context.h"

#include <gflags/gflags.h>

#include <mutex>
#include <string>

#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/gl/gl_immediate_drawer.h"
#include "xenia/ui/window.h"

DEFINE_bool(thread_safe_gl, false,
            "Only allow one GL context to be active at a time.");

DEFINE_bool(disable_gl_context_reset, false,
            "Do not aggressively reset the GL context (helps with capture "
            "programs such as OBS or FRAPS).");

DEFINE_bool(random_clear_color, false, "Randomizes GL clear color.");

DEFINE_bool(gl_debug, false, "Enable OpenGL debug validation layer.");
DEFINE_bool(gl_debug_output, false, "Dump ARB_debug_output to stderr.");
DEFINE_bool(gl_debug_output_synchronous, true,
            "ARB_debug_output will synchronize to be thread safe.");

namespace xe {
namespace ui {
namespace gl {

std::recursive_mutex GLContext::global_gl_mutex_;

void GLContext::FatalGLError(std::string error) {
  xe::FatalError(
      error +
      "\nEnsure you have the latest drivers for your GPU and that it supports "
      "OpenGL 4.5. See http://xenia.jp/faq/ for more information and a list"
      "of supported GPUs.");
}

GLContext::GLContext(GraphicsProvider* provider, Window* target_window)
    : GraphicsContext(provider, target_window) {}

GLContext::~GLContext() {}

void GLContext::AssertExtensionsPresent() {
  if (!MakeCurrent()) {
    FatalGLError("Unable to make GL context current.");
    return;
  }

  // Check shader version at least 4.5 (matching GL 4.5).
  auto glsl_version_raw =
      reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
  std::string glsl_version(glsl_version_raw);
  if (glsl_version.find("4.50") != 0) {
    FatalGLError("OpenGL GLSL version 4.50 is required.");
    return;
  }

  if (!GLEW_ARB_bindless_texture || !glMakeTextureHandleResidentARB) {
    FatalGLError("OpenGL extension ARB_bindless_texture is required.");
    return;
  }

  if (!GLEW_ARB_fragment_coord_conventions) {
    FatalGLError(
        "OpenGL extension ARB_fragment_coord_conventions is required.");
    return;
  }

  ClearCurrent();
}

void GLContext::DebugMessage(GLenum source, GLenum type, GLuint id,
                             GLenum severity, GLsizei length,
                             const GLchar* message) {
  const char* source_name = nullptr;
  switch (source) {
    case GL_DEBUG_SOURCE_API_ARB:
      source_name = "OpenGL";
      break;
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
      source_name = "Windows";
      break;
    case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
      source_name = "Shader Compiler";
      break;
    case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
      source_name = "Third Party";
      break;
    case GL_DEBUG_SOURCE_APPLICATION_ARB:
      source_name = "Application";
      break;
    case GL_DEBUG_SOURCE_OTHER_ARB:
      source_name = "Other";
      break;
    default:
      source_name = "(unknown source)";
      break;
  }

  const char* type_name = nullptr;
  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
      type_name = "error";
      break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
      type_name = "deprecated behavior";
      break;
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
      type_name = "undefined behavior";
      break;
    case GL_DEBUG_TYPE_PORTABILITY:
      type_name = "portability";
      break;
    case GL_DEBUG_TYPE_PERFORMANCE:
      type_name = "performance";
      break;
    case GL_DEBUG_TYPE_OTHER:
      type_name = "message";
      break;
    case GL_DEBUG_TYPE_MARKER:
      type_name = "marker";
      break;
    case GL_DEBUG_TYPE_PUSH_GROUP:
      type_name = "push group";
      break;
    case GL_DEBUG_TYPE_POP_GROUP:
      type_name = "pop group";
      break;
    default:
      type_name = "(unknown type)";
      break;
  }

  const char* severity_name = nullptr;
  switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH_ARB:
      severity_name = "high";
      break;
    case GL_DEBUG_SEVERITY_MEDIUM_ARB:
      severity_name = "medium";
      break;
    case GL_DEBUG_SEVERITY_LOW_ARB:
      severity_name = "low";
      break;
    case GL_DEBUG_SEVERITY_NOTIFICATION:
      severity_name = "notification";
      break;
    default:
      severity_name = "(unknown severity)";
      break;
  }

  XELOGE("GL4 %s: %s(%s) %d: %s", source_name, type_name, severity_name, id,
         message);
}

void GLAPIENTRY GLContext::DebugMessageThunk(GLenum source, GLenum type,
                                             GLuint id, GLenum severity,
                                             GLsizei length,
                                             const GLchar* message,
                                             GLvoid* user_param) {
  reinterpret_cast<GLContext*>(user_param)
      ->DebugMessage(source, type, id, severity, length, message);
}

void GLContext::SetupDebugging() {
  if (!FLAGS_gl_debug || !FLAGS_gl_debug_output) {
    return;
  }

  glEnable(GL_DEBUG_OUTPUT);

  // Synchronous output hurts, but is required if we want to line up the logs.
  if (FLAGS_gl_debug_output_synchronous) {
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  } else {
    glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  }

  // Enable everything by default.
  glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
                        GL_TRUE);

  // Disable annoying messages.
  GLuint disable_message_ids[] = {
      0x00020004,  // Usage warning: Generic vertex attribute array 0 uses a
                   // pointer with a small value (0x0000000000000000). Is this
                   // intended to be used as an offset into a buffer object?
  };
  glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
                        GLsizei(xe::countof(disable_message_ids)),
                        disable_message_ids, GL_FALSE);

  // Callback will be made from driver threads.
  glDebugMessageCallback(reinterpret_cast<GLDEBUGPROC>(&DebugMessageThunk),
                         this);
}

ImmediateDrawer* GLContext::immediate_drawer() {
  return immediate_drawer_.get();
}

bool GLContext::WasLost() {
  if (!robust_access_supported_) {
    // Can't determine if we lost the context.
    return false;
  }

  if (context_lost_) {
    return true;
  }

  auto status = glGetGraphicsResetStatusARB();
  if (status != GL_NO_ERROR) {
    // Graphics card reset.
    XELOGE("============= TDR detected on context %p! Context %s =============",
           handle(), status == GL_GUILTY_CONTEXT_RESET ? "guilty" : "innocent");
    context_lost_ = true;
    return true;
  }

  return false;
}

std::unique_ptr<RawImage> GLContext::Capture() {
  GraphicsContextLock lock(this);

  std::unique_ptr<RawImage> raw_image(new RawImage());
  raw_image->width = target_window_->width();
  raw_image->stride = raw_image->width * 4;
  raw_image->height = target_window_->height();
  raw_image->data.resize(raw_image->stride * raw_image->height);

  glReadPixels(0, 0, target_window_->width(), target_window_->height(), GL_RGBA,
               GL_UNSIGNED_BYTE, raw_image->data.data());

  // Flip vertically in-place.
  size_t yt = 0;
  size_t yb = (raw_image->height - 1) * raw_image->stride;
  while (yt < yb) {
    for (size_t i = 0; i < raw_image->stride; ++i) {
      std::swap(raw_image->data[yt + i], raw_image->data[yb + i]);
    }
    yt += raw_image->stride;
    yb -= raw_image->stride;
  }

  return raw_image;
}

}  // namespace gl
}  // namespace ui
}  // namespace xe
<commit_msg>Detect OpenGL 4.60 (#816)<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/ui/gl/gl_context.h"

#include <gflags/gflags.h>

#include <mutex>
#include <string>

#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/gl/gl_immediate_drawer.h"
#include "xenia/ui/window.h"

DEFINE_bool(thread_safe_gl, false,
            "Only allow one GL context to be active at a time.");

DEFINE_bool(disable_gl_context_reset, false,
            "Do not aggressively reset the GL context (helps with capture "
            "programs such as OBS or FRAPS).");

DEFINE_bool(random_clear_color, false, "Randomizes GL clear color.");

DEFINE_bool(gl_debug, false, "Enable OpenGL debug validation layer.");
DEFINE_bool(gl_debug_output, false, "Dump ARB_debug_output to stderr.");
DEFINE_bool(gl_debug_output_synchronous, true,
            "ARB_debug_output will synchronize to be thread safe.");

namespace xe {
namespace ui {
namespace gl {

std::recursive_mutex GLContext::global_gl_mutex_;

void GLContext::FatalGLError(std::string error) {
  xe::FatalError(
      error +
      "\nEnsure you have the latest drivers for your GPU and that it supports "
      "OpenGL 4.5. See http://xenia.jp/faq/ for more information and a list"
      "of supported GPUs.");
}

GLContext::GLContext(GraphicsProvider* provider, Window* target_window)
    : GraphicsContext(provider, target_window) {}

GLContext::~GLContext() {}

void GLContext::AssertExtensionsPresent() {
  if (!MakeCurrent()) {
    FatalGLError("Unable to make GL context current.");
    return;
  }

  // Check shader version at least 4.5 (matching GL 4.5).
  auto glsl_version_raw =
      reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
  std::string glsl_version(glsl_version_raw);
  if (glsl_version.find("4.5") == std::string::npos && glsl_version.find("4.6") == std::string::npos) {
    FatalGLError("OpenGL GLSL version 4.50 or higher is required.");
    return;
  }

  if (!GLEW_ARB_bindless_texture || !glMakeTextureHandleResidentARB) {
    FatalGLError("OpenGL extension ARB_bindless_texture is required.");
    return;
  }

  if (!GLEW_ARB_fragment_coord_conventions) {
    FatalGLError(
        "OpenGL extension ARB_fragment_coord_conventions is required.");
    return;
  }

  ClearCurrent();
}

void GLContext::DebugMessage(GLenum source, GLenum type, GLuint id,
                             GLenum severity, GLsizei length,
                             const GLchar* message) {
  const char* source_name = nullptr;
  switch (source) {
    case GL_DEBUG_SOURCE_API_ARB:
      source_name = "OpenGL";
      break;
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
      source_name = "Windows";
      break;
    case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
      source_name = "Shader Compiler";
      break;
    case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
      source_name = "Third Party";
      break;
    case GL_DEBUG_SOURCE_APPLICATION_ARB:
      source_name = "Application";
      break;
    case GL_DEBUG_SOURCE_OTHER_ARB:
      source_name = "Other";
      break;
    default:
      source_name = "(unknown source)";
      break;
  }

  const char* type_name = nullptr;
  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
      type_name = "error";
      break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
      type_name = "deprecated behavior";
      break;
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
      type_name = "undefined behavior";
      break;
    case GL_DEBUG_TYPE_PORTABILITY:
      type_name = "portability";
      break;
    case GL_DEBUG_TYPE_PERFORMANCE:
      type_name = "performance";
      break;
    case GL_DEBUG_TYPE_OTHER:
      type_name = "message";
      break;
    case GL_DEBUG_TYPE_MARKER:
      type_name = "marker";
      break;
    case GL_DEBUG_TYPE_PUSH_GROUP:
      type_name = "push group";
      break;
    case GL_DEBUG_TYPE_POP_GROUP:
      type_name = "pop group";
      break;
    default:
      type_name = "(unknown type)";
      break;
  }

  const char* severity_name = nullptr;
  switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH_ARB:
      severity_name = "high";
      break;
    case GL_DEBUG_SEVERITY_MEDIUM_ARB:
      severity_name = "medium";
      break;
    case GL_DEBUG_SEVERITY_LOW_ARB:
      severity_name = "low";
      break;
    case GL_DEBUG_SEVERITY_NOTIFICATION:
      severity_name = "notification";
      break;
    default:
      severity_name = "(unknown severity)";
      break;
  }

  XELOGE("GL4 %s: %s(%s) %d: %s", source_name, type_name, severity_name, id,
         message);
}

void GLAPIENTRY GLContext::DebugMessageThunk(GLenum source, GLenum type,
                                             GLuint id, GLenum severity,
                                             GLsizei length,
                                             const GLchar* message,
                                             GLvoid* user_param) {
  reinterpret_cast<GLContext*>(user_param)
      ->DebugMessage(source, type, id, severity, length, message);
}

void GLContext::SetupDebugging() {
  if (!FLAGS_gl_debug || !FLAGS_gl_debug_output) {
    return;
  }

  glEnable(GL_DEBUG_OUTPUT);

  // Synchronous output hurts, but is required if we want to line up the logs.
  if (FLAGS_gl_debug_output_synchronous) {
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  } else {
    glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  }

  // Enable everything by default.
  glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
                        GL_TRUE);

  // Disable annoying messages.
  GLuint disable_message_ids[] = {
      0x00020004,  // Usage warning: Generic vertex attribute array 0 uses a
                   // pointer with a small value (0x0000000000000000). Is this
                   // intended to be used as an offset into a buffer object?
  };
  glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
                        GLsizei(xe::countof(disable_message_ids)),
                        disable_message_ids, GL_FALSE);

  // Callback will be made from driver threads.
  glDebugMessageCallback(reinterpret_cast<GLDEBUGPROC>(&DebugMessageThunk),
                         this);
}

ImmediateDrawer* GLContext::immediate_drawer() {
  return immediate_drawer_.get();
}

bool GLContext::WasLost() {
  if (!robust_access_supported_) {
    // Can't determine if we lost the context.
    return false;
  }

  if (context_lost_) {
    return true;
  }

  auto status = glGetGraphicsResetStatusARB();
  if (status != GL_NO_ERROR) {
    // Graphics card reset.
    XELOGE("============= TDR detected on context %p! Context %s =============",
           handle(), status == GL_GUILTY_CONTEXT_RESET ? "guilty" : "innocent");
    context_lost_ = true;
    return true;
  }

  return false;
}

std::unique_ptr<RawImage> GLContext::Capture() {
  GraphicsContextLock lock(this);

  std::unique_ptr<RawImage> raw_image(new RawImage());
  raw_image->width = target_window_->width();
  raw_image->stride = raw_image->width * 4;
  raw_image->height = target_window_->height();
  raw_image->data.resize(raw_image->stride * raw_image->height);

  glReadPixels(0, 0, target_window_->width(), target_window_->height(), GL_RGBA,
               GL_UNSIGNED_BYTE, raw_image->data.data());

  // Flip vertically in-place.
  size_t yt = 0;
  size_t yb = (raw_image->height - 1) * raw_image->stride;
  while (yt < yb) {
    for (size_t i = 0; i < raw_image->stride; ++i) {
      std::swap(raw_image->data[yt + i], raw_image->data[yb + i]);
    }
    yt += raw_image->stride;
    yb -= raw_image->stride;
  }

  return raw_image;
}

}  // namespace gl
}  // namespace ui
}  // namespace xe
<|endoftext|>


<commit_before>/*********************************************
* Author: Jun Jiang - jiangjun4@sina.com
* Created: 2017-06-01 11:22
* Last modified: 2017-06-01 11:22
* Filename: TestRNN.cpp
* Description:
**********************************************/

#include "utils/RNNHelper.h"
#include "rnn/RNN.h"

int main(int argc, char** argv){
	std::map<std::string, size_t> map;
	abcdl::utils::RNNHelper helper(8000);
	helper.read_word2index("data/word_to_index", map);

	std::vector<abcdl::algebra::Mat*> data_seq_data;
	std::vector<abcdl::algebra::Mat*> data_seq_label;
	helper.read_seqdata("data/train_seq_data", &data_seq_data, "data/train_seq_label", &data_seq_label, 1000);

    printf("Start training....\n");

    abcdl::rnn::RNN rnn(8000, 100);
    rnn.train(data_seq_data, data_seq_label);

	for(auto&& d : data_seq_data){
		delete d;
	}
	data_seq_data.clear();

	for(auto&& d : data_seq_label){
		delete d;
	}
	data_seq_label.clear();

}
<commit_msg>initialize<commit_after>/*********************************************
* Author: Jun Jiang - jiangjun4@sina.com
* Created: 2017-06-01 11:22
* Last modified: 2017-06-01 11:22
* Filename: TestRNN.cpp
* Description:
**********************************************/

#include "utils/RNNHelper.h"
#include "rnn/RNN.h"

int main(int argc, char** argv){
	std::map<std::string, size_t> map;
	abcdl::utils::RNNHelper helper(8000);
	helper.read_word2index("data/rnn/word_to_index", map);

	std::vector<abcdl::algebra::Mat*> data_seq_data;
	std::vector<abcdl::algebra::Mat*> data_seq_label;
	helper.read_seqdata("data/rnn/train_seq_data", &data_seq_data, "data/rnn/train_seq_label", &data_seq_label, 1000);

    printf("Start training....\n");

    abcdl::rnn::RNN rnn(8000, 100);
    rnn.train(data_seq_data, data_seq_label);

	for(auto&& d : data_seq_data){
		delete d;
	}
	data_seq_data.clear();

	for(auto&& d : data_seq_label){
		delete d;
	}
	data_seq_label.clear();
}
<|endoftext|>


<commit_before>#include <chrono>
#include <vector>
#include <initializer_list>

#include <cstdint>
#include <cstdlib>
#include <cstdio>
#include <cassert>

class bitvector {

    const size_t n;
    uint64_t* array;

public:
    bitvector(size_t n_) : n(n_) {
        assert(n > 0);
        array = new uint64_t[n];
    }

    ~bitvector() {
        delete[] array;
    }

    void fill(uint64_t word) {
        for (size_t i=0; i < n; i++)
            array[i] = word;
    }

    void fill_random(int threshold) {
        assert(threshold >= 0);
        assert(threshold <= 100);

        srand(0);
        for (size_t i=0; i < n; i++) {
            if ((rand() % 100) > threshold) {
                array[i] = -1;
            } else {
                array[i] = 0;
            }
        }
    }

    size_t size() const {
        return n * 64;
    }

    size_t cardinality() const {
        size_t k = 0;
        for (size_t i=0; i < n; i++) {
            k += __builtin_popcountll(array[i]);
        }

        return k;
    }

public:
    template <typename CALLBACK>
    void iterate_naive(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                if (tmp & 0x1) {
                    callback(k);
                }

                tmp >>= 1;
                k += 1;
            }
        }
    }

    template <typename CALLBACK>
    void iterate_better(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                const uint64_t t = tmp & (~tmp + 1);
                const uint64_t r = __builtin_ctzll(t);
                callback(k + r);
                tmp ^= t;
            }
        }
    }

    template <typename CALLBACK>
    void iterate_block3(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                switch (tmp & 0x7) {
                    case 0:
                        break;

                    case 1:
                        callback(k);
                        break;

                    case 2:
                        callback(k + 1);
                        break;

                    case 3:
                        callback(k);
                        callback(k + 1);
                        break;

                    case 4:
                        callback(k + 2);
                        break;

                    case 5:
                        callback(k);
                        callback(k + 2);
                        break;

                    case 6:
                        callback(k + 1);
                        callback(k + 2);
                        break;

                    case 7:
                        callback(k);
                        callback(k + 1);
                        callback(k + 2);
                        break;
                }

                tmp >>= 3;
                k += 3;
            }
        }
    }

    template <typename CALLBACK>
    void iterate_block4(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                switch (tmp & 0xf) {
                    case 0:
                        break;

                    case 1:
                        callback(k);
                        break;

                    case 2:
                        callback(k + 1);
                        break;

                    case 3:
                        callback(k);
                        callback(k + 1);
                        break;

                    case 4:
                        callback(k + 2);
                        break;

                    case 5:
                        callback(k);
                        callback(k + 2);
                        break;

                    case 6:
                        callback(k + 1);
                        callback(k + 2);
                        break;

                    case 7:
                        callback(k);
                        callback(k + 1);
                        callback(k + 2);
                        break;

                    case 8:
                        callback(k + 3);
                        break;

                    case 9:
                        callback(k);
                        callback(k + 3);
                        break;

                    case 10:
                        callback(k + 1);
                        callback(k + 3);
                        break;

                    case 11:
                        callback(k);
                        callback(k + 1);
                        callback(k + 3);
                        break;

                    case 12:
                        callback(k + 2);
                        callback(k + 3);
                        break;

                    case 13:
                        callback(k);
                        callback(k + 2);
                        callback(k + 3);
                        break;

                    case 14:
                        callback(k + 1);
                        callback(k + 2);
                        callback(k + 3);
                        break;

                    case 15:
                        callback(k);
                        callback(k + 1);
                        callback(k + 2);
                        callback(k + 3);
                        break;
                }

                tmp >>= 4;
                k += 4;
            }
        }
    }
};

void testcase(const bitvector& bv, int iterations) {
    using clock = std::chrono::high_resolution_clock;
    using std::chrono::duration_cast;
    using std::chrono::microseconds;

    uint64_t ta;
    uint64_t tb;

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            uint64_t n = 0;
            auto callback = [&n](size_t i) {
                n += i;
            };

            bv.iterate_naive(callback);
            k += n;
        }
        const auto t2 = clock::now();

        ta = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tnaive:  %10ld us [%ld]\n", ta, k);
    }

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            uint64_t n = 0;
            auto callback = [&n](size_t i) {
                n += i;
            };

            bv.iterate_better(callback);
            k += n;
        }
        const auto t2 = clock::now();

        tb = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tbetter: %10ld us [%ld]", tb, k);
        printf(" (%0.2f)\n", ta/double(tb));
    }

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            uint64_t n = 0;
            auto callback = [&n](size_t i) {
                n += i;
            };

            bv.iterate_block3(callback);
            k += n;
        }
        const auto t2 = clock::now();

        tb = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tblock3: %10ld us [%ld]", tb, k);
        printf(" (%0.2f)\n", ta/double(tb));
    }

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            uint64_t n = 0;
            auto callback = [&n](size_t i) {
                n += i;
            };

            bv.iterate_block4(callback);
            k += n;
        }
        const auto t2 = clock::now();

        tb = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tblock4: %10ld us [%ld]", tb, k);
        printf(" (%0.2f)\n", ta/double(tb));
    }
}

template <typename INITIALIZER>
void test(const char* info, const std::vector<size_t>& sizes, int iterations, INITIALIZER initalizer) {

    bool print = true;
    for (size_t i: sizes) {
        bitvector bv(i);
        initalizer(bv);
        if (print) {
            printf("%s\n", info);
            print = false;
        }
        printf("\tsize=%lu, cardinality=%lu\n", bv.size(), bv.cardinality());

        testcase(bv, iterations);
    }
}

int main() {

    const std::vector<size_t> sizes = {64, 256, 1024, 4096, 8192};

    test("empty", sizes, 10000, [](bitvector& bv) {bv.fill(0);});
    test("1/4",   sizes,  1000, [](bitvector& bv) {bv.fill(0x000000000000ffff);});
    test("1/2",   sizes,  1000, [](bitvector& bv) {bv.fill(0x00000000ffffffff);});
    test("3/4",   sizes,  1000, [](bitvector& bv) {bv.fill(0x0000ffffffffffff);});
    test("full",  sizes,  1000, [](bitvector& bv) {bv.fill(0xffffffffffffffff);});
    test("rand",  sizes,  1000, [](bitvector& bv) {bv.fill_random(80);});
    test("rand2", sizes,  1000, [](bitvector& bv) {bv.fill_random(5);});
    return 0;
}

<commit_msg>Refacto, allow to call function inside callback<commit_after>#include <chrono>
#include <vector>
#include <initializer_list>

#include <cstdint>
#include <cstdlib>
#include <cstdio>
#include <cassert>

class bitvector {

    const size_t n;
    uint64_t* array;

public:
    bitvector(size_t n_) : n(n_) {
        assert(n > 0);
        array = new uint64_t[n];
    }

    ~bitvector() {
        delete[] array;
    }

    void fill(uint64_t word) {
        for (size_t i=0; i < n; i++)
            array[i] = word;
    }

    void fill_random(int threshold) {
        assert(threshold >= 0);
        assert(threshold <= 100);

        srand(0);
        for (size_t i=0; i < n; i++) {
            if ((rand() % 100) > threshold) {
                array[i] = -1;
            } else {
                array[i] = 0;
            }
        }
    }

    size_t size() const {
        return n * 64;
    }

    size_t cardinality() const {
        size_t k = 0;
        for (size_t i=0; i < n; i++) {
            k += __builtin_popcountll(array[i]);
        }

        return k;
    }

public:
    template <typename CALLBACK>
    void iterate_naive(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                if (tmp & 0x1) {
                    callback(k);
                }

                tmp >>= 1;
                k += 1;
            }
        }
    }

    template <typename CALLBACK>
    void iterate_better(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                const uint64_t t = tmp & (~tmp + 1);
                const uint64_t r = __builtin_ctzll(t);
                callback(k + r);
                tmp ^= t;
            }
        }
    }

    template <typename CALLBACK>
    void iterate_block3(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                switch (tmp & 0x7) {
                    case 0:
                        break;

                    case 1:
                        callback(k);
                        break;

                    case 2:
                        callback(k + 1);
                        break;

                    case 3:
                        callback(k);
                        callback(k + 1);
                        break;

                    case 4:
                        callback(k + 2);
                        break;

                    case 5:
                        callback(k);
                        callback(k + 2);
                        break;

                    case 6:
                        callback(k + 1);
                        callback(k + 2);
                        break;

                    case 7:
                        callback(k);
                        callback(k + 1);
                        callback(k + 2);
                        break;
                }

                tmp >>= 3;
                k += 3;
            }
        }
    }

    template <typename CALLBACK>
    void iterate_block4(CALLBACK callback) const {
        for (size_t i=0; i < n; i++) {
            uint64_t tmp = array[i];

            size_t k = i * 64;
            while (tmp) {
                switch (tmp & 0xf) {
                    case 0:
                        break;

                    case 1:
                        callback(k);
                        break;

                    case 2:
                        callback(k + 1);
                        break;

                    case 3:
                        callback(k);
                        callback(k + 1);
                        break;

                    case 4:
                        callback(k + 2);
                        break;

                    case 5:
                        callback(k);
                        callback(k + 2);
                        break;

                    case 6:
                        callback(k + 1);
                        callback(k + 2);
                        break;

                    case 7:
                        callback(k);
                        callback(k + 1);
                        callback(k + 2);
                        break;

                    case 8:
                        callback(k + 3);
                        break;

                    case 9:
                        callback(k);
                        callback(k + 3);
                        break;

                    case 10:
                        callback(k + 1);
                        callback(k + 3);
                        break;

                    case 11:
                        callback(k);
                        callback(k + 1);
                        callback(k + 3);
                        break;

                    case 12:
                        callback(k + 2);
                        callback(k + 3);
                        break;

                    case 13:
                        callback(k);
                        callback(k + 2);
                        callback(k + 3);
                        break;

                    case 14:
                        callback(k + 1);
                        callback(k + 2);
                        callback(k + 3);
                        break;

                    case 15:
                        callback(k);
                        callback(k + 1);
                        callback(k + 2);
                        callback(k + 3);
                        break;
                }

                tmp >>= 4;
                k += 4;
            }
        }
    }
};

#ifdef __GNUC__
#   define NOINLINE __attribute__((noline))
#else
#   define NOINLINE
#endif

size_t callback_function(size_t index) {
    return index;
}

void testcase(const bitvector& bv, int iterations, size_t (*cb_fun)(size_t)) {
    using clock = std::chrono::high_resolution_clock;
    using std::chrono::duration_cast;
    using std::chrono::microseconds;

    uint64_t ta;
    uint64_t tb;

    uint64_t n;
    auto callback = [&n, cb_fun](size_t i) {
#if 0
        n += cb_fun(i);
#else
        n += i;
#endif
    };

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            n = 0;
            bv.iterate_naive(callback);
            k += n;
        }
        const auto t2 = clock::now();

        ta = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tnaive:  %10ld us [%ld]\n", ta, k);
    }

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            n = 0;
            bv.iterate_better(callback);
            k += n;
        }
        const auto t2 = clock::now();

        tb = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tbetter: %10ld us [%ld]", tb, k);
        printf(" (%0.2f)\n", ta/double(tb));
    }

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            n = 0;
            bv.iterate_block3(callback);
            k += n;
        }
        const auto t2 = clock::now();

        tb = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tblock3: %10ld us [%ld]", tb, k);
        printf(" (%0.2f)\n", ta/double(tb));
    }

    {
        int tmp = iterations;
        volatile uint64_t k = 0;

        const auto t1 = clock::now();
        while (tmp--) {
            n = 0;
            bv.iterate_block4(callback);
            k += n;
        }
        const auto t2 = clock::now();

        tb = duration_cast<microseconds>(t2 - t1).count();
        printf("\t\tblock4: %10ld us [%ld]", tb, k);
        printf(" (%0.2f)\n", ta/double(tb));
    }
}

template <typename INITIALIZER>
void test(const char* info, const std::vector<size_t>& sizes, int iterations, INITIALIZER initalizer) {

    bool print = true;
    for (size_t i: sizes) {
        bitvector bv(i);
        initalizer(bv);
        if (print) {
            printf("%s\n", info);
            print = false;
        }
        printf("\tsize=%lu, cardinality=%lu\n", bv.size(), bv.cardinality());

        testcase(bv, iterations, callback_function);
    }
}

int main() {

    const std::vector<size_t> sizes = {64, 256, 1024, 4096, 8192};

    test("empty", sizes, 10000, [](bitvector& bv) {bv.fill(0);});
    test("1/4",   sizes,  1000, [](bitvector& bv) {bv.fill(0x000000000000ffff);});
    test("1/2",   sizes,  1000, [](bitvector& bv) {bv.fill(0x00000000ffffffff);});
    test("3/4",   sizes,  1000, [](bitvector& bv) {bv.fill(0x0000ffffffffffff);});
    test("full",  sizes,  1000, [](bitvector& bv) {bv.fill(0xffffffffffffffff);});
    test("rand",  sizes,  1000, [](bitvector& bv) {bv.fill_random(80);});
    test("rand2", sizes,  1000, [](bitvector& bv) {bv.fill_random(5);});
    return 0;
}

<|endoftext|>