<commit_before>/*
 *
 * Copyright (c) 2014, Laurens van der Maaten (Delft University of Technology)
 * 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the Delft University of Technology.
 * 4. Neither the name of the Delft University of Technology nor the names of
 *    its contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY LAURENS VAN DER MAATEN ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL LAURENS VAN DER MAATEN 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.
 *
 */

#include <math.h>
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#include "sptree.h"

// Constructs cell
Cell::Cell(unsigned int inp_dimension) {
    dimension = inp_dimension;
    corner = (double*) malloc(dimension * sizeof(double));
    width  = (double*) malloc(dimension * sizeof(double));
}

Cell::Cell(unsigned int inp_dimension, double* inp_corner, double* inp_width) {
    dimension = inp_dimension;
    corner = (double*) malloc(dimension * sizeof(double));
    width  = (double*) malloc(dimension * sizeof(double));
    for(int d = 0; d < dimension; d++) setCorner(d, inp_corner[d]);
    for(int d = 0; d < dimension; d++) setWidth( d,  inp_width[d]);
}

// Destructs cell
Cell::~Cell() {
    free(corner);
    free(width);
}

double Cell::getCorner(unsigned int d) {
    return corner[d];
}

double Cell::getWidth(unsigned int d) {
    return width[d];
}

void Cell::setCorner(unsigned int d, double val) {
    corner[d] = val;
}

void Cell::setWidth(unsigned int d, double val) {
    width[d] = val;
}

// Checks whether a point lies in a cell
bool Cell::containsPoint(double point[])
{
    for(int d = 0; d < dimension; d++) {
        if(corner[d] - width[d] > point[d]) return false;
        if(corner[d] + width[d] < point[d]) return false;
    }
    return true;
}

// Default constructor for SPTree -- build tree, too!
SPTree::SPTree(unsigned int D, double* inp_data, unsigned int N)
{

    // Compute mean, width, and height of current map (boundaries of SPTree)
    int nD = 0;
    double* mean_Y = (double*) calloc(D,  sizeof(double));
    double*  min_Y = (double*) malloc(D * sizeof(double)); for(unsigned int d = 0; d < D; d++)  min_Y[d] =  DBL_MAX;
    double*  max_Y = (double*) malloc(D * sizeof(double)); for(unsigned int d = 0; d < D; d++)  max_Y[d] = -DBL_MAX;
    for(unsigned int n = 0; n < N; n++) {
        for(unsigned int d = 0; d < D; d++) {
            mean_Y[d] += inp_data[n * D + d];
            if(inp_data[nD + d] < min_Y[d]) min_Y[d] = inp_data[nD + d];
            if(inp_data[nD + d] > max_Y[d]) max_Y[d] = inp_data[nD + d];
        }
        nD += D;
    }
    for(int d = 0; d < D; d++) mean_Y[d] /= (double) N;

    // Construct SPTree
    double* width = (double*) malloc(D * sizeof(double));
    for(int d = 0; d < D; d++) width[d] = fmax(max_Y[d] - mean_Y[d], mean_Y[d] - min_Y[d]) + 1e-5;
    init(NULL, D, inp_data, mean_Y, width);
    fill(N);

    // Clean up memory
    free(mean_Y);
    free(max_Y);
    free(min_Y);
    free(width);
}

// Constructor for SPTree with particular size and parent -- build the tree, too!
SPTree::SPTree(unsigned int D, double* inp_data, unsigned int N, double* inp_corner, double* inp_width)
{
    init(NULL, D, inp_data, inp_corner, inp_width);
    fill(N);
}

// Constructor for SPTree with particular size (do not fill the tree)
SPTree::SPTree(unsigned int D, double* inp_data, double* inp_corner, double* inp_width)
{
    init(NULL, D, inp_data, inp_corner, inp_width);
}

// Constructor for SPTree with particular size and parent (do not fill tree)
SPTree::SPTree(SPTree* inp_parent, unsigned int D, double* inp_data, double* inp_corner, double* inp_width) {
    init(inp_parent, D, inp_data, inp_corner, inp_width);
}

// Constructor for SPTree with particular size and parent -- build the tree, too!
SPTree::SPTree(SPTree* inp_parent, unsigned int D, double* inp_data, unsigned int N, double* inp_corner, double* inp_width)
{
    init(inp_parent, D, inp_data, inp_corner, inp_width);
    fill(N);
}

// Main initialization function
void SPTree::init(SPTree* inp_parent, unsigned int D, double* inp_data, double* inp_corner, double* inp_width)
{
    parent = inp_parent;
    dimension = D;
    no_children = 2;
    for(unsigned int d = 1; d < D; d++) no_children *= 2;
    data = inp_data;
    is_leaf = true;
    size = 0;
    cum_size = 0;

    boundary = new Cell(dimension);
    for(unsigned int d = 0; d < D; d++) boundary->setCorner(d, inp_corner[d]);
    for(unsigned int d = 0; d < D; d++) boundary->setWidth( d, inp_width[d]);

    children = (SPTree**) malloc(no_children * sizeof(SPTree*));
    for(unsigned int i = 0; i < no_children; i++) children[i] = NULL;

    center_of_mass = (double*) malloc(D * sizeof(double));
    for(unsigned int d = 0; d < D; d++) center_of_mass[d] = .0;

    buff = (double*) malloc(D * sizeof(double));
}

// Destructor for SPTree
SPTree::~SPTree()
{
    for(unsigned int i = 0; i < no_children; i++) {
        if(children[i] != NULL) delete children[i];
    }
    free(children);
    free(center_of_mass);
    free(buff);
    delete boundary;
}

// Update the data underlying this tree
void SPTree::setData(double* inp_data)
{
    data = inp_data;
}

// Get the parent of the current tree
SPTree* SPTree::getParent()
{
    return parent;
}

// Insert a point into the SPTree
bool SPTree::insert(unsigned int new_index)
{
    // Ignore objects which do not belong in this quad tree
    double* point = data + new_index * dimension;
    if(!boundary->containsPoint(point))
        return false;

    // Online update of cumulative size and center-of-mass
    cum_size++;
    double mult1 = (double) (cum_size - 1) / (double) cum_size;
    double mult2 = 1.0 / (double) cum_size;
    for(unsigned int d = 0; d < dimension; d++) center_of_mass[d] *= mult1;
    for(unsigned int d = 0; d < dimension; d++) center_of_mass[d] += mult2 * point[d];

    // If there is space in this quad tree and it is a leaf, add the object here
    if(is_leaf && size < QT_NODE_CAPACITY) {
        index[size] = new_index;
        size++;
        return true;
    }

    // Don't add duplicates for now (this is not very nice)
    bool any_duplicate = false;
    for(unsigned int n = 0; n < size; n++) {
        bool duplicate = true;
        for(unsigned int d = 0; d < dimension; d++) {
            if(point[d] != data[index[n] * dimension + d]) { duplicate = false; break; }
        }
        any_duplicate = any_duplicate | duplicate;
    }
    if(any_duplicate) return true;

    // Otherwise, we need to subdivide the current cell
    if(is_leaf) subdivide();

    // Find out where the point can be inserted
    for(unsigned int i = 0; i < no_children; i++) {
        if(children[i]->insert(new_index)) return true;
    }

    // Otherwise, the point cannot be inserted (this should never happen)
    return false;
}

// Create four children which fully divide this cell into four quads of equal area
void SPTree::subdivide() {

    // Create new children
    double* new_corner = (double*) malloc(dimension * sizeof(double));
    double* new_width  = (double*) malloc(dimension * sizeof(double));
    for(unsigned int i = 0; i < no_children; i++) {
        unsigned int div = 1;
        for(unsigned int d = 0; d < dimension; d++) {
            new_width[d] = .5 * boundary->getWidth(d);
            if((i / div) % 2 == 1) new_corner[d] = boundary->getCorner(d) - .5 * boundary->getWidth(d);
            else                   new_corner[d] = boundary->getCorner(d) + .5 * boundary->getWidth(d);
            div *= 2;
        }
        children[i] = new SPTree(this, dimension, data, new_corner, new_width);
    }
    free(new_corner);
    free(new_width);

    // Move existing points to correct children
    for(unsigned int i = 0; i < size; i++) {
        bool success = false;
        for(unsigned int j = 0; j < no_children; j++) {
            if(!success) success = children[j]->insert(index[i]);
        }
        index[i] = -1;
    }

    // Empty parent node
    size = 0;
    is_leaf = false;
}

// Build SPTree on dataset
void SPTree::fill(unsigned int N)
{
    for(unsigned int i = 0; i < N; i++) insert(i);
}

// Checks whether the specified tree is correct
bool SPTree::isCorrect()
{
    for(unsigned int n = 0; n < size; n++) {
        double* point = data + index[n] * dimension;
        if(!boundary->containsPoint(point)) return false;
    }
    if(!is_leaf) {
        bool correct = true;
        for(int i = 0; i < no_children; i++) correct = correct && children[i]->isCorrect();
        return correct;
    }
    else return true;
}

// Build a list of all indices in SPTree
void SPTree::getAllIndices(unsigned int* indices)
{
    getAllIndices(indices, 0);
}

// Build a list of all indices in SPTree
unsigned int SPTree::getAllIndices(unsigned int* indices, unsigned int loc)
{

    // Gather indices in current quadrant
    for(unsigned int i = 0; i < size; i++) indices[loc + i] = index[i];
    loc += size;

    // Gather indices in children
    if(!is_leaf) {
        for(int i = 0; i < no_children; i++) loc = children[i]->getAllIndices(indices, loc);
    }
    return loc;
}

unsigned int SPTree::getDepth() {
    if(is_leaf) return 1;
    int depth = 0;
    for(unsigned int i = 0; i < no_children; i++) depth = fmax(depth, children[i]->getDepth());
    return 1 + depth;
}

// Compute non-edge forces using Barnes-Hut algorithm
void SPTree::computeNonEdgeForces(unsigned int point_index, double theta, double neg_f[], double* sum_Q)
{

    // Make sure that we spend no time on empty nodes or self-interactions
    if(cum_size == 0 || (is_leaf && size == 1 && index[0] == point_index)) return;

    // Compute distance between point and center-of-mass
    double D = .0;
    unsigned int ind = point_index * dimension;
    for(unsigned int d = 0; d < dimension; d++) buff[d] = data[ind + d] - center_of_mass[d];
    for(unsigned int d = 0; d < dimension; d++) D += buff[d] * buff[d];

    // Check whether we can use this node as a "summary"
    double max_width = 0.0;
    double cur_width;
    for(unsigned int d = 0; d < dimension; d++) {
        cur_width = boundary->getWidth(d);
        max_width = (max_width > cur_width) ? max_width : cur_width;
    }
    if(is_leaf || max_width / sqrt(D) < theta) {

        // Compute and add t-SNE force between point and current node
        D = 1.0 / (1.0 + D);
        double mult = cum_size * D;
        *sum_Q += mult;
        mult *= D;
        for(unsigned int d = 0; d < dimension; d++) neg_f[d] += mult * buff[d];
    }
    else {

        // Recursively apply Barnes-Hut to children
        for(unsigned int i = 0; i < no_children; i++) children[i]->computeNonEdgeForces(point_index, theta, neg_f, sum_Q);
    }
}

// Computes edge forces
void SPTree::computeEdgeForces(unsigned int* row_P, unsigned int* col_P, double* val_P, int N, double* pos_f)
{

    // Loop over all edges in the graph
    unsigned int ind1 = 0;
    unsigned int ind2 = 0;
    double D;
    for(unsigned int n = 0; n < N; n++) {
        for(unsigned int i = row_P[n]; i < row_P[n + 1]; i++) {

            // Compute pairwise distance and Q-value
            D = 1.0;
            ind2 = col_P[i] * dimension;
            for(unsigned int d = 0; d < dimension; d++) buff[d] = data[ind1 + d] - data[ind2 + d];
            for(unsigned int d = 0; d < dimension; d++) D += buff[d] * buff[d];
            D = val_P[i] / D;

            // Sum positive force
            for(unsigned int d = 0; d < dimension; d++) pos_f[ind1 + d] += D * buff[d];
        }
        ind1 += dimension;
    }
}

// Print out tree
void SPTree::print()
{
    if(cum_size == 0) {
        printf("Empty node\n");
        return;
    }

    if(is_leaf) {
        printf("Leaf node; data = [");
        for(int i = 0; i < size; i++) {
            double* point = data + index[i] * dimension;
            for(int d = 0; d < dimension; d++) printf("%f, ", point[d]);
            printf(" (index = %d)", index[i]);
            if(i < size - 1) printf("\n");
            else printf("]\n");
        }
    }
    else {
        printf("Intersection node with center-of-mass = [");
        for(int d = 0; d < dimension; d++) printf("%f, ", center_of_mass[d]);
        printf("]; children are:\n");
        for(int i = 0; i < no_children; i++) children[i]->print();
    }
}

<commit_msg>Delete sptree.cpp<commit_after><|endoftext|>


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

#include "include/internal/cef_string_multimap.h"
#include "base/logging.h"
#include <map>

typedef std::multimap<CefString, CefString> StringMultimap;
typedef StringMultimap::const_iterator StringMultimapIter;

CEF_EXPORT cef_string_multimap_t cef_string_multimap_alloc()
{
  return new StringMultimap;
}

CEF_EXPORT int cef_string_multimap_size(cef_string_multimap_t map)
{
  DCHECK(map);
  StringMultimap* impl = (StringMultimap*)map;
  return impl->size();
}

CEF_EXPORT int cef_string_multimap_find_count(cef_string_multimap_t map,
                                              const cef_string_t* key)
{
  DCHECK(map);
  DCHECK(key);
  StringMultimap* impl = (StringMultimap*)map;
  return impl->count(CefString(key));
}

CEF_EXPORT int cef_string_multimap_enumerate(cef_string_multimap_t map,
                                             const cef_string_t* key,
                                             int value_index,
                                             cef_string_t* value)
{
  DCHECK(map);
  DCHECK(key);
  DCHECK(value);

  StringMultimap* impl = (StringMultimap*)map;
  CefString key_str(key);

  DCHECK(value_index >= 0 && value_index < (int)impl->count(key_str));

  if(value_index < 0 || value_index >= (int)impl->count(key_str))
    return NULL;

  std::pair<StringMultimap::iterator, StringMultimap::iterator> range_it =
      impl->equal_range(key_str);

  int count = value_index;
  while (count-- && range_it.first != range_it.second)
    range_it.first++;

  if (range_it.first == range_it.second)
    return NULL;

  const CefString& val = range_it.first->second;
  return cef_string_set(val.c_str(), val.length(), value, true);
}

CEF_EXPORT int cef_string_multimap_key(cef_string_multimap_t map, int index,
                                       cef_string_t* key)
{
  DCHECK(map);
  DCHECK(key);
  StringMultimap* impl = (StringMultimap*)map;
  DCHECK(index >= 0 && index < (int)impl->size());
  if(index < 0 || index >= (int)impl->size())
    return NULL;
  StringMultimap::const_iterator it = impl->begin();
  for(int ct = 0; it != impl->end(); ++it, ct++) {
    if(ct == index)
      return cef_string_set(it->first.c_str(), it->first.length(), key, true);
  }
  return 0;
}

CEF_EXPORT int cef_string_multimap_value(cef_string_multimap_t map, int index,
                                         cef_string_t* value)
{
  DCHECK(map);
  DCHECK(value);
  StringMultimap* impl = (StringMultimap*)map;
  DCHECK(index >= 0 && index < (int)impl->size());
  if(index < 0 || index >= (int)impl->size())
    return NULL;
  StringMultimap::const_iterator it = impl->begin();
  for(int ct = 0; it != impl->end(); ++it, ct++) {
    if(ct == index) {
      return cef_string_set(it->second.c_str(), it->second.length(), value,
          true);
    }
  }
  return 0;
}

CEF_EXPORT int cef_string_multimap_append(cef_string_multimap_t map,
                                          const cef_string_t* key,
                                          const cef_string_t* value)
{
  DCHECK(map);
  StringMultimap* impl = (StringMultimap*)map;
  impl->insert(std::make_pair(CefString(key), CefString(value)));
  return 1;
}

CEF_EXPORT void cef_string_multimap_clear(cef_string_multimap_t map)
{
  DCHECK(map);
  StringMultimap* impl = (StringMultimap*)map;
  impl->clear();
}

CEF_EXPORT void cef_string_multimap_free(cef_string_multimap_t map)
{
  DCHECK(map);
  delete (StringMultimap*)map;
}
<commit_msg>Linux: Fix compile errors due to issue #386 changes.<commit_after>// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "include/internal/cef_string_multimap.h"
#include "base/logging.h"
#include <map>

typedef std::multimap<CefString, CefString> StringMultimap;
typedef StringMultimap::const_iterator StringMultimapIter;

CEF_EXPORT cef_string_multimap_t cef_string_multimap_alloc()
{
  return new StringMultimap;
}

CEF_EXPORT int cef_string_multimap_size(cef_string_multimap_t map)
{
  DCHECK(map);
  StringMultimap* impl = (StringMultimap*)map;
  return impl->size();
}

CEF_EXPORT int cef_string_multimap_find_count(cef_string_multimap_t map,
                                              const cef_string_t* key)
{
  DCHECK(map);
  DCHECK(key);
  StringMultimap* impl = (StringMultimap*)map;
  return impl->count(CefString(key));
}

CEF_EXPORT int cef_string_multimap_enumerate(cef_string_multimap_t map,
                                             const cef_string_t* key,
                                             int value_index,
                                             cef_string_t* value)
{
  DCHECK(map);
  DCHECK(key);
  DCHECK(value);

  StringMultimap* impl = (StringMultimap*)map;
  CefString key_str(key);

  DCHECK(value_index >= 0 && value_index < (int)impl->count(key_str));

  if(value_index < 0 || value_index >= (int)impl->count(key_str))
    return 0;

  std::pair<StringMultimap::iterator, StringMultimap::iterator> range_it =
      impl->equal_range(key_str);

  int count = value_index;
  while (count-- && range_it.first != range_it.second)
    range_it.first++;

  if (range_it.first == range_it.second)
    return 0;

  const CefString& val = range_it.first->second;
  return cef_string_set(val.c_str(), val.length(), value, true);
}

CEF_EXPORT int cef_string_multimap_key(cef_string_multimap_t map, int index,
                                       cef_string_t* key)
{
  DCHECK(map);
  DCHECK(key);
  StringMultimap* impl = (StringMultimap*)map;
  DCHECK(index >= 0 && index < (int)impl->size());
  if(index < 0 || index >= (int)impl->size())
    return 0;
  StringMultimap::const_iterator it = impl->begin();
  for(int ct = 0; it != impl->end(); ++it, ct++) {
    if(ct == index)
      return cef_string_set(it->first.c_str(), it->first.length(), key, true);
  }
  return 0;
}

CEF_EXPORT int cef_string_multimap_value(cef_string_multimap_t map, int index,
                                         cef_string_t* value)
{
  DCHECK(map);
  DCHECK(value);
  StringMultimap* impl = (StringMultimap*)map;
  DCHECK(index >= 0 && index < (int)impl->size());
  if(index < 0 || index >= (int)impl->size())
    return 0;
  StringMultimap::const_iterator it = impl->begin();
  for(int ct = 0; it != impl->end(); ++it, ct++) {
    if(ct == index) {
      return cef_string_set(it->second.c_str(), it->second.length(), value,
          true);
    }
  }
  return 0;
}

CEF_EXPORT int cef_string_multimap_append(cef_string_multimap_t map,
                                          const cef_string_t* key,
                                          const cef_string_t* value)
{
  DCHECK(map);
  StringMultimap* impl = (StringMultimap*)map;
  impl->insert(std::make_pair(CefString(key), CefString(value)));
  return 1;
}

CEF_EXPORT void cef_string_multimap_clear(cef_string_multimap_t map)
{
  DCHECK(map);
  StringMultimap* impl = (StringMultimap*)map;
  impl->clear();
}

CEF_EXPORT void cef_string_multimap_free(cef_string_multimap_t map)
{
  DCHECK(map);
  delete (StringMultimap*)map;
}
<|endoftext|>


<commit_before>#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

#define HERO_RECT       CCRectMake(0, 99, 102, 126)
#define ENEMY1_RECT     CCRectMake(534, 612, 57, 43)
#define BULLET_RECT     CCRectMake(1004, 987, 9, 21)

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayerColor::initWithColor( ccc4(255,255,255,255) ) )
    {
        return false;
    }

    // enable touch
    this->setTouchEnabled(true); //this->setIsTouchEnabled(true);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    this->player = CCSprite::create("shoot.png", HERO_RECT );
    this->player->setPosition( ccp(winSize.width/2, this->player->getContentSize().height/2) );
    this->addChild(this->player);

    this->schedule( schedule_selector(HelloWorld::addEnemies), 1.0 );
    this->schedule( schedule_selector(HelloWorld::fireBullets), 1.0/7.0 );
    this->schedule( schedule_selector(HelloWorld::update) );

    _enemies = new CCArray;
    _bullets = new CCArray;

    return true;
}

HelloWorld::HelloWorld():_enemies(NULL),_bullets(NULL)
{
}

HelloWorld::~HelloWorld()
{
    if (_enemies)
    {
        _enemies->release();
        _enemies = NULL;
    }

    if (_bullets)
    {
        _bullets->release();
        _bullets = NULL;
    }

    // cpp don't need to call super dealloc
    // virtual destructor will do this
}

//
// enemy
//

void HelloWorld::addEnemies(float dt)
{
    this->addEnemy();
}

void HelloWorld::addEnemy()
{
    CCSprite *enemy = CCSprite::create("shoot.png", ENEMY1_RECT);

    // Determine where to spawn the target along the X axis
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    int minX = enemy->getContentSize().width/2;
    int maxX = winSize.width - enemy->getContentSize().width/2;
    int rangeX = maxX - minX;
    // srand( TimGetTicks() );
    int actualX = ( rand() % rangeX ) + minX;

    // Create the target slightly off-screen along the top edge,
    // and along a random position along the X axis as calculated
    enemy->setPosition( ccp(actualX, winSize.height + enemy->getContentSize().height/2) );
    this->addChild(enemy);

    // Determine speed of the target
    int minDuration = (int)3.0;
    int maxDuration = (int)6.0;
    int rangeDuration = maxDuration - minDuration;
    // srand( TimGetTicks() );
    int actualDuration = ( rand() % rangeDuration ) + minDuration;

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create((float)actualDuration,
                                                      ccp( actualX, 0 - enemy->getContentSize().height/2) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::enemyMoveFinished));
    enemy->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    enemy->setTag(1);
    _enemies->addObject(enemy);
}

void HelloWorld::enemyMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true);
    _enemies->removeObject(sprite);
}

//
// bullets
//

void HelloWorld::fireBullets(float dt)
{
    this->fireBullet();
}

void HelloWorld::fireBullet()
{
    CCSprite *bullet = CCSprite::create("shoot.png", BULLET_RECT);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();

    CCPoint playerLocation = player->getPosition();
    bullet->setPosition(CCPoint(playerLocation.x, playerLocation.y + player->getContentSize().height/2));
    this->addChild(bullet);

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create(1.0f,
                                                      ccp( bullet->getPosition().x, bullet->getPosition().y + winSize.height*3/4) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::bulletMoveFinished));
    bullet->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    bullet->setTag(2);
    _bullets->addObject(bullet);
}

void HelloWorld::bulletMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true);
    _bullets->removeObject(sprite);
}

//
// hero
//

void HelloWorld::ccTouchesBegan(CCSet *touches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    CCPoint playerLocation = player->getPosition();

    this->touchOffset = CCPoint(playerLocation.x - location.x,
                                playerLocation.y - location.y);
}

void HelloWorld::ccTouchesMoved(CCSet *touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    CCSize playerSize = player->getContentSize();

    float newX = location.x + this->touchOffset.x;
    newX = newX < playerSize.width/2 ? playerSize.width/2 : newX;
    newX = newX > winSize.width - playerSize.width/2 ? winSize.width - playerSize.width/2 : newX;

    float newY = location.y + this->touchOffset.y;
    newY = newY < playerSize.height/2 ? playerSize.height/2 : newY;
    newY = newY > winSize.height - playerSize.height/2 ? winSize.height - playerSize.height/2 : newY;

    this->player->setPosition(CCPoint(newX, newY));
}

void HelloWorld::update(float dt)
{
    CCArray *bulletsToDelete = new CCArray;
    CCArray* enemiesToDelete =new CCArray;
    CCObject* it = NULL;
    CCObject* jt = NULL;

    CCARRAY_FOREACH(_bullets, it)
    {
        CCSprite *bullet = dynamic_cast<CCSprite*>(it);
        CCRect bulletRect = CCRectMake(bullet->getPosition().x - (bullet->getContentSize().width/2),
                                       bullet->getPosition().y - (bullet->getContentSize().height/2),
                                       bullet->getContentSize().width,
                                       bullet->getContentSize().height);

        CCARRAY_FOREACH(_enemies, jt)
        {
            CCSprite *enemy = dynamic_cast<CCSprite*>(jt);
            CCRect enemyRect = CCRectMake(enemy->getPosition().x - (enemy->getContentSize().width/2),
                                          enemy->getPosition().y - (enemy->getContentSize().height/2),
                                          enemy->getContentSize().width,
                                          enemy->getContentSize().height);

            if (bulletRect.intersectsRect(enemyRect))
            {
                enemiesToDelete->addObject(enemy);
                bulletsToDelete->addObject(bullet);
            }
        }
    }

    CCARRAY_FOREACH(enemiesToDelete, jt)
    {
        CCSprite *enemy = dynamic_cast<CCSprite*>(jt);
        _enemies->removeObject(enemy);
        this->removeChild(enemy, true);
    }

    CCARRAY_FOREACH(bulletsToDelete, it)
    {
        CCSprite* bullet = dynamic_cast<CCSprite*>(it);
        _bullets->removeObject(bullet);
        this->removeChild(bullet, true);
    }

    bulletsToDelete->release();
    enemiesToDelete->release();
}

<commit_msg>hero player plane animation<commit_after>#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

#define HERO1_RECT       CCRectMake(0, 99, 102, 126)
#define HERO2_RECT       CCRectMake(165, 360, 102, 126)
#define ENEMY1_RECT     CCRectMake(534, 612, 57, 43)
#define BULLET_RECT     CCRectMake(1004, 987, 9, 21)

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayerColor::initWithColor( ccc4(255,255,255,255) ) )
    {
        return false;
    }

    // enable touch
    this->setTouchEnabled(true); //this->setIsTouchEnabled(true);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    this->player = CCSprite::create("shoot.png", HERO1_RECT );
    this->player->setPosition( ccp(winSize.width/2, this->player->getContentSize().height/2) );
    this->addChild(this->player);

    CCAnimation *animation = CCAnimation::create();
    CCSpriteFrame *sframe = CCSpriteFrame::create("shoot.png", HERO2_RECT);
    animation->addSpriteFrame(sframe);
    CCSpriteFrame *sframe2 = CCSpriteFrame::create("shoot.png", HERO1_RECT);
    animation->addSpriteFrame(sframe2);
    animation->setDelayPerUnit(0.1);
    CCAnimate *animate = CCAnimate::create(animation);
    player->runAction(CCRepeatForever::create(animate));

    this->schedule( schedule_selector(HelloWorld::addEnemies), 1.0 );
    this->schedule( schedule_selector(HelloWorld::fireBullets), 1.0/7.0 );
    this->schedule( schedule_selector(HelloWorld::update) );

    _enemies = new CCArray;
    _bullets = new CCArray;

    return true;
}

HelloWorld::HelloWorld():_enemies(NULL),_bullets(NULL)
{
}

HelloWorld::~HelloWorld()
{
    if (_enemies)
    {
        _enemies->release();
        _enemies = NULL;
    }

    if (_bullets)
    {
        _bullets->release();
        _bullets = NULL;
    }

    // cpp don't need to call super dealloc
    // virtual destructor will do this
}

//
// enemy
//

void HelloWorld::addEnemies(float dt)
{
    this->addEnemy();
}

void HelloWorld::addEnemy()
{
    CCSprite *enemy = CCSprite::create("shoot.png", ENEMY1_RECT);

    // Determine where to spawn the target along the X axis
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    int minX = enemy->getContentSize().width/2;
    int maxX = winSize.width - enemy->getContentSize().width/2;
    int rangeX = maxX - minX;
    // srand( TimGetTicks() );
    int actualX = ( rand() % rangeX ) + minX;

    // Create the target slightly off-screen along the top edge,
    // and along a random position along the X axis as calculated
    enemy->setPosition( ccp(actualX, winSize.height + enemy->getContentSize().height/2) );
    this->addChild(enemy);

    // Determine speed of the target
    int minDuration = (int)3.0;
    int maxDuration = (int)6.0;
    int rangeDuration = maxDuration - minDuration;
    // srand( TimGetTicks() );
    int actualDuration = ( rand() % rangeDuration ) + minDuration;

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create((float)actualDuration,
                                                      ccp( actualX, 0 - enemy->getContentSize().height/2) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::enemyMoveFinished));
    enemy->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    enemy->setTag(1);
    _enemies->addObject(enemy);
}

void HelloWorld::enemyMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true);
    _enemies->removeObject(sprite);
}

//
// bullets
//

void HelloWorld::fireBullets(float dt)
{
    this->fireBullet();
}

void HelloWorld::fireBullet()
{
    CCSprite *bullet = CCSprite::create("shoot.png", BULLET_RECT);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();

    CCPoint playerLocation = player->getPosition();
    bullet->setPosition(CCPoint(playerLocation.x, playerLocation.y + player->getContentSize().height/2));
    this->addChild(bullet);

    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create(1.0f,
                                                      ccp( bullet->getPosition().x, bullet->getPosition().y + winSize.height*3/4) );
    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,
                                                             callfuncN_selector(HelloWorld::bulletMoveFinished));
    bullet->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );

    bullet->setTag(2);
    _bullets->addObject(bullet);
}

void HelloWorld::bulletMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true);
    _bullets->removeObject(sprite);
}

//
// hero
//

void HelloWorld::ccTouchesBegan(CCSet *touches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    CCPoint playerLocation = player->getPosition();

    this->touchOffset = CCPoint(playerLocation.x - location.x,
                                playerLocation.y - location.y);
}

void HelloWorld::ccTouchesMoved(CCSet *touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    CCSize playerSize = player->getContentSize();

    float newX = location.x + this->touchOffset.x;
    newX = newX < playerSize.width/2 ? playerSize.width/2 : newX;
    newX = newX > winSize.width - playerSize.width/2 ? winSize.width - playerSize.width/2 : newX;

    float newY = location.y + this->touchOffset.y;
    newY = newY < playerSize.height/2 ? playerSize.height/2 : newY;
    newY = newY > winSize.height - playerSize.height/2 ? winSize.height - playerSize.height/2 : newY;

    this->player->setPosition(CCPoint(newX, newY));
}

void HelloWorld::update(float dt)
{
    CCArray *bulletsToDelete = new CCArray;
    CCArray* enemiesToDelete =new CCArray;
    CCObject* it = NULL;
    CCObject* jt = NULL;

    CCARRAY_FOREACH(_bullets, it)
    {
        CCSprite *bullet = dynamic_cast<CCSprite*>(it);
        CCRect bulletRect = CCRectMake(bullet->getPosition().x - (bullet->getContentSize().width/2),
                                       bullet->getPosition().y - (bullet->getContentSize().height/2),
                                       bullet->getContentSize().width,
                                       bullet->getContentSize().height);

        CCARRAY_FOREACH(_enemies, jt)
        {
            CCSprite *enemy = dynamic_cast<CCSprite*>(jt);
            CCRect enemyRect = CCRectMake(enemy->getPosition().x - (enemy->getContentSize().width/2),
                                          enemy->getPosition().y - (enemy->getContentSize().height/2),
                                          enemy->getContentSize().width,
                                          enemy->getContentSize().height);

            if (bulletRect.intersectsRect(enemyRect))
            {
                enemiesToDelete->addObject(enemy);
                bulletsToDelete->addObject(bullet);
            }
        }
    }

    CCARRAY_FOREACH(enemiesToDelete, jt)
    {
        CCSprite *enemy = dynamic_cast<CCSprite*>(jt);
        _enemies->removeObject(enemy);
        this->removeChild(enemy, true);
    }

    CCARRAY_FOREACH(bulletsToDelete, it)
    {
        CCSprite* bullet = dynamic_cast<CCSprite*>(it);
        _bullets->removeObject(bullet);
        this->removeChild(bullet, true);
    }

    bulletsToDelete->release();
    enemiesToDelete->release();
}

<|endoftext|>


<commit_before>#include <string.h>
#include <iostream>
#include "halide_blas.h"
#include "HalideBuffer.h"

using Halide::Runtime::Buffer;

#define assert_no_error(func)                                       \
  if (func != 0) {                                                  \
    std::cerr << "ERROR! Halide kernel returned non-zero value.\n"; \
  }                                                                 \

namespace {

template<typename T>
Buffer<T> init_scalar_buffer(T *x) {
    return Buffer<T>(x, {});
}

template<typename T>
Buffer<T> init_vector_buffer(const int N, T *x, const int incx) {
    halide_dimension_t shape = {0, N, incx};
    return Buffer<T>(x, 1, &shape);
}

template<typename T>
Buffer<T> init_matrix_buffer(const int M, const int N, T *A, const int lda) {
    halide_dimension_t shape[] = {{0, M, 1}, {0, N, lda}};
    return Buffer<T>(A, 2, shape);
}

}

#ifdef __cplusplus
extern "C" {
#endif

//////////
// copy //
//////////

void hblas_scopy(const int N, const float *x, const int incx,
                 float *y, const int incy) {
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_scopy(buff_x, buff_y));
}

void hblas_dcopy(const int N, const double *x, const int incx,
                 double *y, const int incy) {
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_dcopy(buff_x, buff_y));
}

//////////
// scal //
//////////

void hblas_sscal(const int N, const float a, float *x, const int incx) {
    auto buff_x = init_vector_buffer(N, x, incx);
    assert_no_error(halide_sscal(a, buff_x));
}

void hblas_dscal(const int N, const double a, double *x, const int incx) {
    auto buff_x = init_vector_buffer(N, x, incx);
    assert_no_error(halide_dscal(a, buff_x));
}

//////////
// axpy //
//////////

void hblas_saxpy(const int N, const float a, const float *x, const int incx,
                 float *y, const int incy) {
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_saxpy(a, buff_x, buff_y));
}

void hblas_daxpy(const int N, const double a, const double *x, const int incx,
                 double *y, const int incy) {
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_daxpy(a, buff_x, buff_y));
}

//////////
// dot  //
//////////

float hblas_sdot(const int N, const float *x, const int incx,
                 const float *y, const int incy) {
    float result;
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    auto buff_dot = init_scalar_buffer(&result);
    assert_no_error(halide_sdot(buff_x, buff_y, buff_dot));
    return result;
}

double hblas_ddot(const int N, const double *x, const int incx,
                  const double *y, const int incy) {
    double result;
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    auto buff_dot = init_scalar_buffer(&result);
    assert_no_error(halide_ddot(buff_x, buff_y, buff_dot));
    return result;
}

//////////
// nrm2 //
//////////

float hblas_snrm2(const int N, const float *x, const int incx) {
    float result;
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_nrm = init_scalar_buffer(&result);
    assert_no_error(halide_sdot(buff_x, buff_x, buff_nrm));
    return std::sqrt(result);
}

double hblas_dnrm2(const int N, const double *x, const int incx) {
    double result;
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_nrm = init_scalar_buffer(&result);
    assert_no_error(halide_ddot(buff_x, buff_x, buff_nrm));
    return std::sqrt(result);
}

//////////
// asum //
//////////

float hblas_sasum(const int N, const float *x, const int incx) {
    float result;
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_sum = init_scalar_buffer(&result);
    assert_no_error(halide_sasum(buff_x, buff_sum));
    return result;
}

double hblas_dasum(const int N, const double *x, const int incx) {
    double result;
    auto buff_x = init_vector_buffer(N, x, incx);
    auto buff_sum = init_scalar_buffer(&result);
    assert_no_error(halide_dasum(buff_x, buff_sum));
    return result;
}

//////////
// gemv //
//////////

void hblas_sgemv(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE trans,
                 const int M, const int N, const float a, const float *A, const int lda,
                 const float *x, const int incx, const float b, float *y, const int incy) {
    bool t = false;
    switch (trans) {
    case HblasNoTrans:
        t = false; break;
    case HblasConjTrans:
    case HblasTrans:
        t = true; break;
    };

    auto buff_A = init_matrix_buffer(M, N, A, lda);
    auto buff_x = init_vector_buffer(t ? M : N, x, incx);
    auto buff_y = init_vector_buffer(t ? N : M, y, incy);

    assert_no_error(halide_sgemv(t, a, buff_A, buff_x, b, buff_y));
}

void hblas_dgemv(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE trans,
                 const int M, const int N, const double a, const double *A, const int lda,
                 const double *x, const int incx, const double b, double *y, const int incy) {
    bool t = false;
    switch (trans) {
    case HblasNoTrans:
        t = false; break;
    case HblasConjTrans:
    case HblasTrans:
        t = true; break;
    };

    auto buff_A = init_matrix_buffer(M, N, A, lda);
    auto buff_x = init_vector_buffer(t ? M : N, x, incx);
    auto buff_y = init_vector_buffer(t ? N : M, y, incy);

    assert_no_error(halide_dgemv(t, a, buff_A, buff_x, b, buff_y));
}

//////////
// ger  //
//////////

void hblas_sger(const enum HBLAS_ORDER order, const int M, const int N,
                const float alpha, const float *x, const int incx,
                const float *y, const int incy, float *A, const int lda)
{
    auto buff_x = init_vector_buffer(M, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    auto buff_A = init_matrix_buffer(M, N, A, lda);

    assert_no_error(halide_sger(alpha, buff_x, buff_y, buff_A));
}

void hblas_dger(const enum HBLAS_ORDER order, const int M, const int N,
                const double alpha, const double *x, const int incx,
                const double *y, const int incy, double *A, const int lda)
{
    auto buff_x = init_vector_buffer(M, x, incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    auto buff_A = init_matrix_buffer(M, N, A, lda);

    assert_no_error(halide_dger(alpha, buff_x, buff_y, buff_A));
}

//////////
// gemm //
//////////

void hblas_sgemm(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE TransA,
                 const enum HBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const float alpha, const float *A,
                 const int lda, const float *B, const int ldb,
                 const float beta, float *C, const int ldc) {
    bool tA = false, tB = false;
    switch (TransA) {
    case HblasNoTrans:
        tA = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tA = true; break;
    };

    switch (TransB) {
    case HblasNoTrans:
        tB = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tB = true; break;
    };

    auto buff_A = init_matrix_buffer(tA ? K : M, tA ? M : K, A, lda);
    auto buff_B = init_matrix_buffer(tB ? N : K, tB ? K : N, B, ldb);
    auto buff_C = init_matrix_buffer(M, N, C, ldc);

    assert_no_error(halide_sgemm(tA, tB, alpha, buff_A, buff_B, beta, buff_C));
}

void hblas_dgemm(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE TransA,
                 const enum HBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const double alpha, const double *A,
                 const int lda, const double *B, const int ldb,
                 const double beta, double *C, const int ldc) {
    bool tA = false, tB = false;
    switch (TransA) {
    case HblasNoTrans:
        tA = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tA = true; break;
    };

    switch (TransB) {
    case HblasNoTrans:
        tB = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tB = true; break;
    };

    auto buff_A = init_matrix_buffer(tA ? K : M, tA ? M : K, A, lda);
    auto buff_B = init_matrix_buffer(tB ? N : K, tB ? K : N, B, ldb);
    auto buff_C = init_matrix_buffer(M, N, C, ldc);

    assert_no_error(halide_dgemm(tA, tB, alpha, buff_A, buff_B, beta, buff_C));
}

#ifdef __cplusplus
}
#endif
<commit_msg>cast away const in construction of read-only Buffer wrapper<commit_after>#include <string.h>
#include <iostream>
#include "halide_blas.h"
#include "HalideBuffer.h"

using Halide::Runtime::Buffer;

#define assert_no_error(func)                                       \
  if (func != 0) {                                                  \
    std::cerr << "ERROR! Halide kernel returned non-zero value.\n"; \
  }                                                                 \

namespace {

template<typename T>
Buffer<T> init_scalar_buffer(T *x) {
    return Buffer<T>(x, {});
}

template<typename T>
Buffer<T> init_vector_buffer(const int N, T *x, const int incx) {
    halide_dimension_t shape = {0, N, incx};
    return Buffer<T>(x, 1, &shape);
}

template<typename T>
Buffer<T> init_matrix_buffer(const int M, const int N, T *A, const int lda) {
    halide_dimension_t shape[] = {{0, M, 1}, {0, N, lda}};
    return Buffer<T>(A, 2, shape);
}

}

#ifdef __cplusplus
extern "C" {
#endif

//////////
// copy //
//////////

void hblas_scopy(const int N, const float *x, const int incx,
                 float *y, const int incy) {
    auto buff_x = init_vector_buffer(N, const_cast<float*>(x), incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_scopy(buff_x, buff_y));
}

void hblas_dcopy(const int N, const double *x, const int incx,
                 double *y, const int incy) {
    auto buff_x = init_vector_buffer(N, const_cast<double*>(x), incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_dcopy(buff_x, buff_y));
}

//////////
// scal //
//////////

void hblas_sscal(const int N, const float a, float *x, const int incx) {
    auto buff_x = init_vector_buffer(N, x, incx);
    assert_no_error(halide_sscal(a, buff_x));
}

void hblas_dscal(const int N, const double a, double *x, const int incx) {
    auto buff_x = init_vector_buffer(N, x, incx);
    assert_no_error(halide_dscal(a, buff_x));
}

//////////
// axpy //
//////////

void hblas_saxpy(const int N, const float a, const float *x, const int incx,
                 float *y, const int incy) {
    auto buff_x = init_vector_buffer(N, const_cast<float*>(x), incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_saxpy(a, buff_x, buff_y));
}

void hblas_daxpy(const int N, const double a, const double *x, const int incx,
                 double *y, const int incy) {
    auto buff_x = init_vector_buffer(N, const_cast<double*>(x), incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    assert_no_error(halide_daxpy(a, buff_x, buff_y));
}

//////////
// dot  //
//////////

float hblas_sdot(const int N, const float *x, const int incx,
                 const float *y, const int incy) {
    float result;
    auto buff_x = init_vector_buffer(N, const_cast<float*>(x), incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    auto buff_dot = init_scalar_buffer(&result);
    assert_no_error(halide_sdot(buff_x, buff_y, buff_dot));
    return result;
}

double hblas_ddot(const int N, const double *x, const int incx,
                  const double *y, const int incy) {
    double result;
    auto buff_x = init_vector_buffer(N, const_cast<double*>(x), incx);
    auto buff_y = init_vector_buffer(N, y, incy);
    auto buff_dot = init_scalar_buffer(&result);
    assert_no_error(halide_ddot(buff_x, buff_y, buff_dot));
    return result;
}

//////////
// nrm2 //
//////////

float hblas_snrm2(const int N, const float *x, const int incx) {
    float result;
    auto buff_x = init_vector_buffer(N, const_cast<float*>(x), incx);
    auto buff_nrm = init_scalar_buffer(&result);
    assert_no_error(halide_sdot(buff_x, buff_x, buff_nrm));
    return std::sqrt(result);
}

double hblas_dnrm2(const int N, const double *x, const int incx) {
    double result;
    auto buff_x = init_vector_buffer(N, const_cast<double*>(x), incx);
    auto buff_nrm = init_scalar_buffer(&result);
    assert_no_error(halide_ddot(buff_x, buff_x, buff_nrm));
    return std::sqrt(result);
}

//////////
// asum //
//////////

float hblas_sasum(const int N, const float *x, const int incx) {
    float result;
    auto buff_x = init_vector_buffer(N, const_cast<float*>(x), incx);
    auto buff_sum = init_scalar_buffer(&result);
    assert_no_error(halide_sasum(buff_x, buff_sum));
    return result;
}

double hblas_dasum(const int N, const double *x, const int incx) {
    double result;
    auto buff_x = init_vector_buffer(N, const_cast<double*>(x), incx);
    auto buff_sum = init_scalar_buffer(&result);
    assert_no_error(halide_dasum(buff_x, buff_sum));
    return result;
}

//////////
// gemv //
//////////

void hblas_sgemv(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE trans,
                 const int M, const int N, const float a, const float *A, const int lda,
                 const float *x, const int incx, const float b, float *y, const int incy) {
    bool t = false;
    switch (trans) {
    case HblasNoTrans:
        t = false; break;
    case HblasConjTrans:
    case HblasTrans:
        t = true; break;
    };

    auto buff_A = init_matrix_buffer(M, N, const_cast<float*>(A), lda);
    auto buff_x = init_vector_buffer(t ? M : N, const_cast<float*>(x), incx);
    auto buff_y = init_vector_buffer(t ? N : M, y, incy);

    assert_no_error(halide_sgemv(t, a, buff_A, buff_x, b, buff_y));
}

void hblas_dgemv(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE trans,
                 const int M, const int N, const double a, const double *A, const int lda,
                 const double *x, const int incx, const double b, double *y, const int incy) {
    bool t = false;
    switch (trans) {
    case HblasNoTrans:
        t = false; break;
    case HblasConjTrans:
    case HblasTrans:
        t = true; break;
    };

    auto buff_A = init_matrix_buffer(M, N, const_cast<double*>(A), lda);
    auto buff_x = init_vector_buffer(t ? M : N, const_cast<double*>(x), incx);
    auto buff_y = init_vector_buffer(t ? N : M, y, incy);

    assert_no_error(halide_dgemv(t, a, buff_A, buff_x, b, buff_y));
}

//////////
// ger  //
//////////

void hblas_sger(const enum HBLAS_ORDER order, const int M, const int N,
                const float alpha, const float *x, const int incx,
                const float *y, const int incy, float *A, const int lda)
{
    auto buff_x = init_vector_buffer(M, const_cast<float*>(x), incx);
    auto buff_y = init_vector_buffer(N, const_cast<float*>(y), incy);
    auto buff_A = init_matrix_buffer(M, N, A, lda);

    assert_no_error(halide_sger(alpha, buff_x, buff_y, buff_A));
}

void hblas_dger(const enum HBLAS_ORDER order, const int M, const int N,
                const double alpha, const double *x, const int incx,
                const double *y, const int incy, double *A, const int lda)
{
    auto buff_x = init_vector_buffer(M, const_cast<double*>(x), incx);
    auto buff_y = init_vector_buffer(N, const_cast<double*>(y), incy);
    auto buff_A = init_matrix_buffer(M, N, A, lda);

    assert_no_error(halide_dger(alpha, buff_x, buff_y, buff_A));
}

//////////
// gemm //
//////////

void hblas_sgemm(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE TransA,
                 const enum HBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const float alpha, const float *A,
                 const int lda, const float *B, const int ldb,
                 const float beta, float *C, const int ldc) {
    bool tA = false, tB = false;
    switch (TransA) {
    case HblasNoTrans:
        tA = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tA = true; break;
    };

    switch (TransB) {
    case HblasNoTrans:
        tB = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tB = true; break;
    };

    auto buff_A = init_matrix_buffer(tA ? K : M, tA ? M : K, const_cast<float*>(A), lda);
    auto buff_B = init_matrix_buffer(tB ? N : K, tB ? K : N, const_cast<float*>(B), ldb);
    auto buff_C = init_matrix_buffer(M, N, C, ldc);

    assert_no_error(halide_sgemm(tA, tB, alpha, buff_A, buff_B, beta, buff_C));
}

void hblas_dgemm(const enum HBLAS_ORDER Order, const enum HBLAS_TRANSPOSE TransA,
                 const enum HBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const double alpha, const double *A,
                 const int lda, const double *B, const int ldb,
                 const double beta, double *C, const int ldc) {
    bool tA = false, tB = false;
    switch (TransA) {
    case HblasNoTrans:
        tA = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tA = true; break;
    };

    switch (TransB) {
    case HblasNoTrans:
        tB = false; break;
    case HblasConjTrans:
    case HblasTrans:
        tB = true; break;
    };

    auto buff_A = init_matrix_buffer(tA ? K : M, tA ? M : K, const_cast<double*>(A), lda);
    auto buff_B = init_matrix_buffer(tB ? N : K, tB ? K : N, const_cast<double*>(B), ldb);
    auto buff_C = init_matrix_buffer(M, N, C, ldc);

    assert_no_error(halide_dgemm(tA, tB, alpha, buff_A, buff_B, beta, buff_C));
}

#ifdef __cplusplus
}
#endif
<|endoftext|>


<commit_before>#include "ExecutionEngine.h"

#include <chrono>
#include <cstdlib>	// env options

#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#pragma warning(pop)
#pragma GCC diagnostic pop
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Host.h>

#include "Runtime.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

namespace
{
typedef ReturnCode(*EntryFuncPtr)(Runtime*);

ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
{
	// That function uses long jumps to handle "execeptions".
	// Do not create any non-POD objects here

	ReturnCode returnCode{};
	auto sj = setjmp(_runtime->getJmpBuf());
	if (sj == 0)
		returnCode = _mainFunc(_runtime);
	else
		returnCode = static_cast<ReturnCode>(sj);

	return returnCode;
}

std::string codeHash(bytes const& _code)
{
	uint32_t hash = 0;
	for (auto b : _code)
	{
		hash += b;
		hash += (hash << 10);
		hash ^= (hash >> 6);
	}
	hash += (hash << 3);
	hash ^= (hash >> 11);
	hash += (hash << 15);
	return std::to_string(hash);
}

bool getEnvOption(char const* _name, bool _default)
{
	auto var = std::getenv(_name);
	if (!var)
		return _default;
	return std::strtol(var, nullptr, 10) != 0;
}

}

ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
{
	static std::unique_ptr<llvm::ExecutionEngine> ee;  // TODO: Use Managed Objects from LLVM?
	static auto debugDumpModule = getEnvOption("EVMJIT_DUMP", false);
	static auto objectCacheEnabled = getEnvOption("EVMJIT_CACHE", true);

	auto mainFuncName = codeHash(_code);
	EntryFuncPtr entryFuncPtr{};
	Runtime runtime(_data, _env);	// TODO: I don't know why but it must be created before getFunctionAddress() calls

	if (ee && (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName)))
	{
	}
	else
	{
		auto objectCache = objectCacheEnabled ? Cache::getObjectCache() : nullptr;
		std::unique_ptr<llvm::Module> module;
		if (objectCache)
			module = Cache::getObject(mainFuncName);
		if (!module)
			module = Compiler({}).compile(_code, mainFuncName);
		if (debugDumpModule)
			module->dump();
		if (!ee)
		{
			llvm::InitializeNativeTarget();
			llvm::InitializeNativeTargetAsmPrinter();

			llvm::EngineBuilder builder(module.get());
			builder.setEngineKind(llvm::EngineKind::JIT);
			builder.setUseMCJIT(true);
			std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
			builder.setMCJITMemoryManager(memoryManager.get());
			builder.setOptLevel(llvm::CodeGenOpt::None);

			auto triple = llvm::Triple(llvm::sys::getProcessTriple());
			if (triple.getOS() == llvm::Triple::OSType::Win32)
				triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);  // MCJIT does not support COFF format
			module->setTargetTriple(triple.str());

			ee.reset(builder.create());
			if (!ee)
				return ReturnCode::LLVMConfigError;

			module.release();         // Successfully created llvm::ExecutionEngine takes ownership of the module
			memoryManager.release();  // and memory manager

			if (objectCache)
				ee->setObjectCache(objectCache);
			entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
		}
		else
		{
			if (!entryFuncPtr)
			{
				ee->addModule(module.get());
				module.release();
				entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
			}
		}
	}
	assert(entryFuncPtr);

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	auto returnCode = runEntryFunc(entryFuncPtr, &runtime);
	if (returnCode == ReturnCode::Return)
	{
		returnData = runtime.getReturnData();     // Save reference to return data
		std::swap(m_memory, runtime.getMemory()); // Take ownership of memory
	}

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms\n";

	return returnCode;
}

}
}
}
<commit_msg>change typedef to using according to preferred coding style<commit_after>#include "ExecutionEngine.h"

#include <chrono>
#include <cstdlib>	// env options

#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#pragma warning(pop)
#pragma GCC diagnostic pop
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Host.h>

#include "Runtime.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

namespace
{
using EntryFuncPtr = ReturnCode(*)(Runtime*);

ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
{
	// That function uses long jumps to handle "execeptions".
	// Do not create any non-POD objects here

	ReturnCode returnCode{};
	auto sj = setjmp(_runtime->getJmpBuf());
	if (sj == 0)
		returnCode = _mainFunc(_runtime);
	else
		returnCode = static_cast<ReturnCode>(sj);

	return returnCode;
}

std::string codeHash(bytes const& _code)
{
	uint32_t hash = 0;
	for (auto b : _code)
	{
		hash += b;
		hash += (hash << 10);
		hash ^= (hash >> 6);
	}
	hash += (hash << 3);
	hash ^= (hash >> 11);
	hash += (hash << 15);
	return std::to_string(hash);
}

bool getEnvOption(char const* _name, bool _default)
{
	auto var = std::getenv(_name);
	if (!var)
		return _default;
	return std::strtol(var, nullptr, 10) != 0;
}

}

ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
{
	static std::unique_ptr<llvm::ExecutionEngine> ee;  // TODO: Use Managed Objects from LLVM?
	static auto debugDumpModule = getEnvOption("EVMJIT_DUMP", false);
	static auto objectCacheEnabled = getEnvOption("EVMJIT_CACHE", true);

	auto mainFuncName = codeHash(_code);
	EntryFuncPtr entryFuncPtr{};
	Runtime runtime(_data, _env);	// TODO: I don't know why but it must be created before getFunctionAddress() calls

	if (ee && (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName)))
	{
	}
	else
	{
		auto objectCache = objectCacheEnabled ? Cache::getObjectCache() : nullptr;
		std::unique_ptr<llvm::Module> module;
		if (objectCache)
			module = Cache::getObject(mainFuncName);
		if (!module)
			module = Compiler({}).compile(_code, mainFuncName);
		if (debugDumpModule)
			module->dump();
		if (!ee)
		{
			llvm::InitializeNativeTarget();
			llvm::InitializeNativeTargetAsmPrinter();

			llvm::EngineBuilder builder(module.get());
			builder.setEngineKind(llvm::EngineKind::JIT);
			builder.setUseMCJIT(true);
			std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
			builder.setMCJITMemoryManager(memoryManager.get());
			builder.setOptLevel(llvm::CodeGenOpt::None);

			auto triple = llvm::Triple(llvm::sys::getProcessTriple());
			if (triple.getOS() == llvm::Triple::OSType::Win32)
				triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);  // MCJIT does not support COFF format
			module->setTargetTriple(triple.str());

			ee.reset(builder.create());
			if (!ee)
				return ReturnCode::LLVMConfigError;

			module.release();         // Successfully created llvm::ExecutionEngine takes ownership of the module
			memoryManager.release();  // and memory manager

			if (objectCache)
				ee->setObjectCache(objectCache);
			entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
		}
		else
		{
			if (!entryFuncPtr)
			{
				ee->addModule(module.get());
				module.release();
				entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
			}
		}
	}
	assert(entryFuncPtr);

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	auto returnCode = runEntryFunc(entryFuncPtr, &runtime);
	if (returnCode == ReturnCode::Return)
	{
		returnData = runtime.getReturnData();     // Save reference to return data
		std::swap(m_memory, runtime.getMemory()); // Take ownership of memory
	}

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms\n";

	return returnCode;
}

}
}
}
<|endoftext|>


<commit_before>/**
 * Test for Performance Simulation
 * Copyright 2018 MIPT-MIPS
 */

#include "../perf_sim.h"

// Catch2
#include <catch.hpp>

// Module
#include <memory/elf/elf_loader.h>
#include <mips/mips.h>
#include <modules/writeback/writeback.h>

static const std::string valid_elf_file = TEST_PATH "/tt.core32.out";
static const std::string smc_code = TEST_PATH "/smc.out";

TEST_CASE( "PerfSim: create empty memory and get lost")
{
    auto m = FuncMemory::create_hierarchied_memory();
    PerfSim<MIPS32> sim( false);
    sim.set_memory( m);
    CHECK_THROWS_AS( sim.run_no_limit(), Deadlock);
}

TEST_CASE( "Perf_Sim_init: Process_Correct_Args_Of_Constr")
{
    // Just call a constructor
    PerfSim<MIPS32> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    CHECK_NOTHROW(sim.set_memory( mem));
}

TEST_CASE( "Perf_Sim_init: Make_A_Step")
{
    // Call constructor and run one instr
    PerfSim<MIPS32> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim.set_memory( mem);
    ElfLoader elf( valid_elf_file);
    elf.load_to( mem.get());
    sim.init_checker();
    sim.set_pc( elf.get_startPC());
    CHECK_NOTHROW( sim.run( 1) );
}

TEST_CASE( "Perf_Sim: Register R/W")
{
    PerfSim<MIPS32> sim( false);

    /* Signed */
    sim.write_cpu_register( 1, narrow_cast<uint64>( -1337));
    CHECK( narrow_cast<int32>( sim.read_cpu_register( 1)) == -1337 );
    /* Unsigned */
    sim.write_cpu_register( 1, uint64{ MAX_VAL32});
    CHECK( sim.read_cpu_register( 1) == MAX_VAL32 );
}

TEST_CASE( "Perf_Sim: Register size")
{
    CHECK( PerfSim<MIPS32>( false).sizeof_register() == bytewidth<uint32>);
    CHECK( PerfSim<MIPS64>( false).sizeof_register() == bytewidth<uint64>);
}

TEST_CASE( "Torture_Test: Perf_Sim , MIPS 64, Core 64")
{
    PerfSim<MIPS64> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim.set_memory( mem);
    ElfLoader elf( TEST_PATH "/tt.core64.out");
    elf.load_to( mem.get());
    sim.init_checker();
    sim.set_pc( elf.get_startPC());
    CHECK_NOTHROW( sim.run_no_limit() );
}

TEST_CASE( "Perf_Sim: Run_SMC_Trace_WithoutChecker")
{
    PerfSim<MIPS32> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim.set_memory( mem);
    ElfLoader elf( smc_code);
    elf.load_to( mem.get());
    sim.set_pc( elf.get_startPC());
    CHECK( sim.run_no_limit( ) == Trap::NO_TRAP);
}

TEST_CASE( "Perf_Sim: Run_SMC_Trace_WithChecker")
{
    PerfSim<MIPS32> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim.set_memory( mem);
    ElfLoader elf( smc_code);
    elf.load_to( mem.get());
    sim.init_checker();
    sim.set_pc( elf.get_startPC());

    CHECK_THROWS_AS( sim.run_no_limit( ), CheckerMismatch);
}
<commit_msg>Remove some complicated PerfSim tests (#715)<commit_after>/**
 * Test for Performance Simulation
 * Copyright 2018 MIPT-MIPS
 */

#include "../perf_sim.h"

// Catch2
#include <catch.hpp>

// Module
#include <memory/elf/elf_loader.h>
#include <mips/mips.h>
#include <modules/writeback/writeback.h>

TEST_CASE( "Perf_Sim_init: Process_Correct_Args_Of_Constr")
{
    // Just call a constructor
    PerfSim<MIPS32> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    CHECK_NOTHROW(sim.set_memory( mem));
}

TEST_CASE( "Perf_Sim_init: push a nop")
{
    PerfSim<MIPS32> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim.set_memory( mem);
    sim.init_checker();
    sim.set_pc( 0x10);
    CHECK_NOTHROW( sim.run( 1) );
}

TEST_CASE( "PerfSim: create empty memory and get lost")
{
    auto m = FuncMemory::create_hierarchied_memory();
    PerfSim<MIPS32> sim( false);
    sim.set_memory( m);
    CHECK_THROWS_AS( sim.run_no_limit(), Deadlock);
}

TEST_CASE( "Perf_Sim: unsigned register R/W")
{
    PerfSim<MIPS32> sim( false);
    sim.write_cpu_register( 1, uint64{ MAX_VAL32});
    CHECK( sim.read_cpu_register( 1) == MAX_VAL32 );
}

TEST_CASE( "Perf_Sim: signed register R/W")
{
    PerfSim<MIPS32> sim( false);
    sim.write_cpu_register( 1, narrow_cast<uint64>( -1337));
    CHECK( narrow_cast<int32>( sim.read_cpu_register( 1)) == -1337 );
}

TEST_CASE( "Perf_Sim: Register size")
{
    CHECK( PerfSim<MIPS32>( false).sizeof_register() == bytewidth<uint32>);
    CHECK( PerfSim<MIPS64>( false).sizeof_register() == bytewidth<uint64>);
}

TEST_CASE( "Torture_Test: Perf_Sim , MIPS 64, Core 64")
{
    PerfSim<MIPS64> sim( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim.set_memory( mem);
    ElfLoader elf( TEST_PATH "/tt.core64.out");
    elf.load_to( mem.get());
    sim.init_checker();
    sim.set_pc( elf.get_startPC());
    CHECK_NOTHROW( sim.run_no_limit() );
}

static auto get_smc_loaded_simulator(bool init_checker)
{
    auto sim = std::make_shared<PerfSim<MIPS32>>( false);
    auto mem = FuncMemory::create_hierarchied_memory();
    sim->set_memory( mem);
    ElfLoader elf( TEST_PATH "/smc.out");
    elf.load_to( mem.get());
    if ( init_checker)
        sim->init_checker();
    sim->set_pc( elf.get_startPC());
    return sim;
}

TEST_CASE( "Perf_Sim: Run_SMC_Trace_WithoutChecker")
{
    CHECK( get_smc_loaded_simulator( false)->run_no_limit() == Trap::NO_TRAP);
}

TEST_CASE( "Perf_Sim: Run_SMC_Trace_WithChecker")
{
    CHECK_THROWS_AS( get_smc_loaded_simulator( true)->run_no_limit(), CheckerMismatch);
}
<|endoftext|>


<commit_before>/*
*
* Copyright 2016 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker 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 Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* iot_support at tid dot es
*
* Author: Fermin Galan
*
*/
#include <string>
#include <vector>

#include "common/string.h"
#include "common/globals.h"
#include "logMsg/logMsg.h"
#include "ngsi/ContextAttribute.h"

// FIXME P5: the following could be not necessary if we optimize the valueBson() thing. See
// the next FIXME P5 comment in this file
#include "mongoBackend/safeMongo.h"
#include "mongoBackend/dbConstants.h"
#include "mongoBackend/dateExpiration.h"

/* ****************************************************************************
*
* USING
*/
using mongo::BSONObjBuilder;
using mongo::BSONArrayBuilder;
using orion::CompoundValueNode;

/* ****************************************************************************
*
* getDateExpiration -
*
* Get the ISO8601 Expiration Date information for the given
* ContextAttribute provided as parameter, in order to construct the corresponding Mongo Date_t object.
*
* It returns true, except in the case of error (in which in addition errDetail gets filled)
*/
static bool getDateExpiration
(
  const ContextAttribute*  caP,
  mongo::Date_t*           dateExpiration,
  std::string*             errDetail
)
{
  if ((caP->type == DATE_TYPE) || (caP->type == DATE_TYPE_ALT))
  {
    *dateExpiration = mongo::Date_t(caP->numberValue*1000);

    return true;
  }

  LM_E(("Runtime Error (attribute detected as date expiration but invalid type: %s)", caP->type.c_str()));
  *errDetail = "error processing date expiration attribute, see log traces";

  return false;
}

/* ****************************************************************************
*
* processDateExpirationAtEntityCreation -
*
* This function process the context attribute vector, searching for an attribute meaning
* date expiration for the entity. In that case, it fills dateExpiration value.
* If a date expiration attribute is not found dateExpiration keeps empty value set by the caller function.
*
* This function always return true (no matter if the attribute was found or not), except in an
* error situation, in which case errorDetail is filled.
*/
bool processDateExpirationAtEntityCreation
(
  const ContextAttributeVector&  caV,
  mongo::Date_t*                 dateExpiration,
  std::string*                   errDetail,
  OrionError*                    oe
)
{
  for (unsigned ix = 0; ix < caV.size(); ++ix)
  {
    const ContextAttribute* caP = caV[ix];

    if (caP->name == DATE_EXPIRES)
    {
      if (!getDateExpiration(caP, dateExpiration, errDetail))
      {
        oe->fill(SccBadRequest, *errDetail, "BadRequest");
        return false;
      }

      return true;
    }
  }

  return true;
}

/* ****************************************************************************
*
* processDateExpirationAtUpdateAttribute -
*
* If the name of the target attribute is the date expiration,
* check for a number value that will be used in the mongo::Date_t constructor.
* If it is an empty value, is interpreted as a date expiration deletion and the ACTUAL date value
* is set to 0, in order to signal the caller function.
* If valid value, also replaceDate boolean is set to true, in order to manage the new date value
* in case the update is a replace operation.
*/
bool processDateExpirationAtUpdateAttribute
(
  const ContextAttribute*  targetAttr,
  mongo::Date_t*           dateExpiration,
  bool*                    replaceDate,
  std::string*             errDetail,
  OrionError*              oe
)
{
  if (targetAttr->name == DATE_EXPIRES)
  {
    if (targetAttr->numberValue)
    {
      if (!getDateExpiration(targetAttr, dateExpiration, errDetail))
      {
        oe->fill(SccBadRequest, *errDetail, "BadRequest");
        return false;
      }
      else
      {
        *replaceDate = true;
      }
    }
    else
    {
      *dateExpiration = 0;
    }
  }

  return true;
}

/* ****************************************************************************
*
* processDateExpirationAtAppendAttribute -
*/
bool processDateExpirationAtAppendAttribute
(
  mongo::Date_t*                 dateExpiration,
  const ContextAttribute*        targetAttr,
  bool                           actualAppend,
  std::string*                   errDetail,
  OrionError*                    oe
)
{
  if (targetAttr->numberValue)
  {
  if (!getDateExpiration(targetAttr, dateExpiration, errDetail))
    {
      oe->fill(SccBadRequest, *errDetail, "BadRequest");
      return false;
    }
  }
  else
  {
    *dateExpiration = 0;
  }

  return true;
}
<commit_msg>Fixed bug when appending date attribute<commit_after>/*
*
* Copyright 2016 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker 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 Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* iot_support at tid dot es
*
* Author: Fermin Galan
*
*/
#include <string>
#include <vector>

#include "common/string.h"
#include "common/globals.h"
#include "logMsg/logMsg.h"
#include "ngsi/ContextAttribute.h"

// FIXME P5: the following could be not necessary if we optimize the valueBson() thing. See
// the next FIXME P5 comment in this file
#include "mongoBackend/safeMongo.h"
#include "mongoBackend/dbConstants.h"
#include "mongoBackend/dateExpiration.h"

/* ****************************************************************************
*
* USING
*/
using mongo::BSONObjBuilder;
using mongo::BSONArrayBuilder;
using orion::CompoundValueNode;

/* ****************************************************************************
*
* getDateExpiration -
*
* Get the ISO8601 Expiration Date information for the given
* ContextAttribute provided as parameter, in order to construct the corresponding Mongo Date_t object.
*
* It returns true, except in the case of error (in which in addition errDetail gets filled)
*/
static bool getDateExpiration
(
  const ContextAttribute*  caP,
  mongo::Date_t*           dateExpiration,
  std::string*             errDetail
)
{
  if ((caP->type == DATE_TYPE) || (caP->type == DATE_TYPE_ALT))
  {
    *dateExpiration = mongo::Date_t(caP->numberValue*1000);

    return true;
  }

  LM_E(("Runtime Error (attribute detected as date expiration but invalid type: %s)", caP->type.c_str()));
  *errDetail = "error processing date expiration attribute, see log traces";

  return false;
}

/* ****************************************************************************
*
* processDateExpirationAtEntityCreation -
*
* This function process the context attribute vector, searching for an attribute meaning
* date expiration for the entity. In that case, it fills dateExpiration value.
* If a date expiration attribute is not found dateExpiration keeps empty value set by the caller function.
*
* This function always return true (no matter if the attribute was found or not), except in an
* error situation, in which case errorDetail is filled.
*/
bool processDateExpirationAtEntityCreation
(
  const ContextAttributeVector&  caV,
  mongo::Date_t*                 dateExpiration,
  std::string*                   errDetail,
  OrionError*                    oe
)
{
  for (unsigned ix = 0; ix < caV.size(); ++ix)
  {
    const ContextAttribute* caP = caV[ix];

    if (caP->name == DATE_EXPIRES)
    {
      if (!getDateExpiration(caP, dateExpiration, errDetail))
      {
        oe->fill(SccBadRequest, *errDetail, "BadRequest");
        return false;
      }

      return true;
    }
  }

  return true;
}

/* ****************************************************************************
*
* processDateExpirationAtUpdateAttribute -
*
* If the name of the target attribute is the date expiration,
* check for a number value that will be used in the mongo::Date_t constructor.
* If it is an empty value, is interpreted as a date expiration deletion and the ACTUAL date value
* is set to 0, in order to signal the caller function.
* If valid value, also replaceDate boolean is set to true, in order to manage the new date value
* in case the update is a replace operation.
*/
bool processDateExpirationAtUpdateAttribute
(
  const ContextAttribute*  targetAttr,
  mongo::Date_t*           dateExpiration,
  bool*                    replaceDate,
  std::string*             errDetail,
  OrionError*              oe
)
{
  if (targetAttr->name == DATE_EXPIRES)
  {
    if (targetAttr->numberValue)
    {
      if (!getDateExpiration(targetAttr, dateExpiration, errDetail))
      {
        oe->fill(SccBadRequest, *errDetail, "BadRequest");
        return false;
      }
      else
      {
        *replaceDate = true;
      }
    }
    else
    {
      *dateExpiration = 0;
    }
  }

  return true;
}

/* ****************************************************************************
*
* processDateExpirationAtAppendAttribute -
*/
bool processDateExpirationAtAppendAttribute
(
  mongo::Date_t*                 dateExpiration,
  const ContextAttribute*        targetAttr,
  bool                           actualAppend,
  std::string*                   errDetail,
  OrionError*                    oe
)
{
  if (targetAttr->name == DATE_EXPIRES)
  {
    if (targetAttr->numberValue)
    {
      if (!getDateExpiration(targetAttr, dateExpiration, errDetail))
      {
        oe->fill(SccBadRequest, *errDetail, "BadRequest");
        return false;
      }
    }
    else
    {
      *dateExpiration = 0;
    }
  }

  return true;
}
<|endoftext|>


<commit_before>
#include "NanoCSP.h"
#include "../minisat/minisat_wrap.h"

namespace NanoCSP
{
	int NCSolver::AssignInt(int sz)
	{
		int top = vTop;
		vTop += sz;

		for(int i = 0; i < sz - 1; i++) {
			cond.push_back(-(top + i));
			cond.push_back(top + i + 1);
			cond.push_back(0);
		}

		return top;
	}

	bool NCSolver::solve()
	{
		for(int i=0;i<cond.size();i++) {
			printf("%d ", cond[i]);
			if(cond[i] == 0) puts("");
		}

		sol = SAT(cond);

		return sol.size() != 0;
	}

	int NCSolver::GetIntValue(NCInt& iv)
	{
		for(int i = 0; i < (iv.nMax - iv.nMin); i++) {
			if(sol[iv.vTop + i - 1]) return i + iv.nMin;
		}
		return iv.nMax;
	}

	bool NCSolver::GetBoolValue(NCBool& bv)
	{
		if(bv.vId < 0) return !sol[bv.vId - 1];
		return sol[bv.vId - 1];
	}

	void NCSolver::IntEqual(NCInt& opLeft, NCInt& opRight, std::vector<int>& prem)
	{
		LessEqualThan(opLeft, opRight, prem);
		GtrEqualThan(opLeft, opRight, prem);
	}

	void NCSolver::IntNotEqual(NCInt& opLeft, NCInt& opRight, std::vector<int>& prem)
	{
		NCBool c1(*this);
		NCBool c2(*this);

		cond.push_back(c1.vId);
		cond.push_back(c2.vId);
		cond.push_back(0);

		prem.push_back(-c1.vId);
		GtrThan(opLeft, opRight, prem);

		prem.pop_back();
		prem.push_back(-c2.vId);
		LessThan(opLeft, opRight, prem);

		prem.pop_back();
	}

	void NCSolver::IntAllDifferent(std::vector<NCInt>& vals, std::vector<int>& prem)
	{
		for(int i = 0; i < vals.size(); i++)
			for(int j = i + 1; j < vals.size(); j++)
				IntNotEqual(vals[i], vals[j], prem);
	}

	void NCSolver::LessEqualThan(NCInt& opLeft, NCInt& opRight, std::vector<int>& prem)
	{
		// opLeft <= opRight

		for(int n = opRight.nMin; n <= opRight.nMax; n++) {
			int condY = opRight.LessEqualThan(n);

			if(opLeft.AlwaysHoldsLessEqualThan(n)) continue;
			int condX = opLeft.LessEqualThan(n);

			for(int i = 0; i < prem.size(); i++) cond.push_back(prem[i]);
			if(condY != 0) cond.push_back(-condY);
			if(condX != 0) cond.push_back(condX);

			cond.push_back(0);
		}
	}

	void NCSolver::AddLessEqual(NCInt& addLeft, NCInt& addRight, NCInt& opRight, std::vector<int>& prem)
	{
		// (addLeft + addRight) <= opRight

		for(int n = opRight.nMin; n <= opRight.nMax; n++) {
			for(int m = addLeft.nMin - 1; m < addLeft.nMax; m++) {
				int condZ = opRight.LessEqualThan(n);
				int condX = addLeft.LessEqualThan(m);

				if(addRight.AlwaysHoldsLessEqualThan(n - m - 1)) continue;
				int condY = addRight.LessEqualThan(n - m - 1);

				for(int i = 0; i < prem.size(); i++) cond.push_back(prem[i]);

				if(condZ != 0) cond.push_back(-condZ);
				if(condX != 0) cond.push_back(condX);
				if(condY != 0) cond.push_back(condY);

				cond.push_back(0);
			}
		}
	}

	void NCSolver::AddGtrEqual(NCInt& addLeft, NCInt& addRight, NCInt& opRight, std::vector<int>& prem)
	{
		// (addLeft + addRight) >= opRight

		for(int n = opRight.nMin; n <= opRight.nMax; n++) {
			for(int m = addLeft.nMin + 1; m <= addLeft.nMax + 1; m++) {
				int condZ = opRight.GtrEqualThan(n);
				int condX = addLeft.GtrEqualThan(m);

				if(addRight.AlwaysHoldsGtrEqualThan(n - m + 1)) continue;
				int condY = addRight.GtrEqualThan(n - m + 1);

				for(int i = 0; i < prem.size(); i++) cond.push_back(prem[i]);

				if(condZ != 0) cond.push_back(-condZ);
				if(condX != 0) cond.push_back(condX);
				if(condY != 0) cond.push_back(condY);

				cond.push_back(0);
			}
		}
	}

	void NCSolver::AddEqual(NCInt& addLeft, NCInt& addRight, NCInt& opRight, std::vector<int>& prem)
	{
		AddLessEqual(addLeft, addRight, opRight, prem);
		AddGtrEqual(addLeft, addRight, opRight, prem);
	}
};
<commit_msg>Comment out debug code<commit_after>
#include "NanoCSP.h"
#include "../minisat/minisat_wrap.h"

namespace NanoCSP
{
	int NCSolver::AssignInt(int sz)
	{
		int top = vTop;
		vTop += sz;

		for(int i = 0; i < sz - 1; i++) {
			cond.push_back(-(top + i));
			cond.push_back(top + i + 1);
			cond.push_back(0);
		}

		return top;
	}

	bool NCSolver::solve()
	{
		/*
		for(int i=0;i<cond.size();i++) {
			printf("%d ", cond[i]);
			if(cond[i] == 0) puts("");
		}
		*/

		sol = SAT(cond);

		return sol.size() != 0;
	}

	int NCSolver::GetIntValue(NCInt& iv)
	{
		for(int i = 0; i < (iv.nMax - iv.nMin); i++) {
			if(sol[iv.vTop + i - 1]) return i + iv.nMin;
		}
		return iv.nMax;
	}

	bool NCSolver::GetBoolValue(NCBool& bv)
	{
		if(bv.vId < 0) return !sol[bv.vId - 1];
		return sol[bv.vId - 1];
	}

	void NCSolver::IntEqual(NCInt& opLeft, NCInt& opRight, std::vector<int>& prem)
	{
		LessEqualThan(opLeft, opRight, prem);
		GtrEqualThan(opLeft, opRight, prem);
	}

	void NCSolver::IntNotEqual(NCInt& opLeft, NCInt& opRight, std::vector<int>& prem)
	{
		NCBool c1(*this);
		NCBool c2(*this);

		cond.push_back(c1.vId);
		cond.push_back(c2.vId);
		cond.push_back(0);

		prem.push_back(-c1.vId);
		GtrThan(opLeft, opRight, prem);

		prem.pop_back();
		prem.push_back(-c2.vId);
		LessThan(opLeft, opRight, prem);

		prem.pop_back();
	}

	void NCSolver::IntAllDifferent(std::vector<NCInt>& vals, std::vector<int>& prem)
	{
		for(int i = 0; i < vals.size(); i++)
			for(int j = i + 1; j < vals.size(); j++)
				IntNotEqual(vals[i], vals[j], prem);
	}

	void NCSolver::LessEqualThan(NCInt& opLeft, NCInt& opRight, std::vector<int>& prem)
	{
		// opLeft <= opRight

		for(int n = opRight.nMin; n <= opRight.nMax; n++) {
			int condY = opRight.LessEqualThan(n);

			if(opLeft.AlwaysHoldsLessEqualThan(n)) continue;
			int condX = opLeft.LessEqualThan(n);

			for(int i = 0; i < prem.size(); i++) cond.push_back(prem[i]);
			if(condY != 0) cond.push_back(-condY);
			if(condX != 0) cond.push_back(condX);

			cond.push_back(0);
		}
	}

	void NCSolver::AddLessEqual(NCInt& addLeft, NCInt& addRight, NCInt& opRight, std::vector<int>& prem)
	{
		// (addLeft + addRight) <= opRight

		for(int n = opRight.nMin; n <= opRight.nMax; n++) {
			for(int m = addLeft.nMin - 1; m < addLeft.nMax; m++) {
				int condZ = opRight.LessEqualThan(n);
				int condX = addLeft.LessEqualThan(m);

				if(addRight.AlwaysHoldsLessEqualThan(n - m - 1)) continue;
				int condY = addRight.LessEqualThan(n - m - 1);

				for(int i = 0; i < prem.size(); i++) cond.push_back(prem[i]);

				if(condZ != 0) cond.push_back(-condZ);
				if(condX != 0) cond.push_back(condX);
				if(condY != 0) cond.push_back(condY);

				cond.push_back(0);
			}
		}
	}

	void NCSolver::AddGtrEqual(NCInt& addLeft, NCInt& addRight, NCInt& opRight, std::vector<int>& prem)
	{
		// (addLeft + addRight) >= opRight

		for(int n = opRight.nMin; n <= opRight.nMax; n++) {
			for(int m = addLeft.nMin + 1; m <= addLeft.nMax + 1; m++) {
				int condZ = opRight.GtrEqualThan(n);
				int condX = addLeft.GtrEqualThan(m);

				if(addRight.AlwaysHoldsGtrEqualThan(n - m + 1)) continue;
				int condY = addRight.GtrEqualThan(n - m + 1);

				for(int i = 0; i < prem.size(); i++) cond.push_back(prem[i]);

				if(condZ != 0) cond.push_back(-condZ);
				if(condX != 0) cond.push_back(condX);
				if(condY != 0) cond.push_back(condY);

				cond.push_back(0);
			}
		}
	}

	void NCSolver::AddEqual(NCInt& addLeft, NCInt& addRight, NCInt& opRight, std::vector<int>& prem)
	{
		AddLessEqual(addLeft, addRight, opRight, prem);
		AddGtrEqual(addLeft, addRight, opRight, prem);
	}
};
<|endoftext|>