<commit_before>#include <iostream>
#include <string.h>
#include <OptionList.h>
#include <SQLiteDatabase.h>
#include <NaiveSimilarityStrategy.h>
#include <Generator.h>
#include <TextOutput.h>

#define PARAMS 1

using namespace SoundCity;
using std::cout;
using std::endl;
using std::cin;
using std::string;

void
usage (char *s)
{
  fprintf(stderr, "Usage: %s <database>\n", s);

  fprintf(stderr, "Options :\n");

  fprintf(stderr, "-h : Affiche l'aide.\n");

  fprintf(stderr, "-y <startYear[1-3000]> <endYear[1-3000]> : Définit un intervalle d'années de morceaux.\n");

  fprintf(stderr, "-e <energy[0.0-1.0]> : Impose une valeur d'énergie dans la playlist générée.\n");

  fprintf(stderr, "-p <popularity[0.0-1.0]> : Impose une valeur de popularité dans la playlist générée.\n");

  fprintf(stderr, "-r <rhythm[0.0-1.0]> : Impose un rythme dans la playlist générée.\n");

  fprintf(stderr, "-m <mood[0.0-1.0]> : Impose une humeur dans la playlist générée (plus la valeur est grande plus le morceau est joyeux).\n");

  fprintf(stderr, "-s <size[1-100]> : Choix de la taille de la playlist générée (10 par défaut).\n");

  fprintf(stderr, "-o <fileName> : Choix du nom du fichier de sortie.\n");
  exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
  if (argc < PARAMS+1)
    usage(argv[0]);

  cout << "Création de la liste d'options." << endl;

  int size = 10;
  float energy = 0;
  float mood = 0;
  float rhythm = 0;
  float popularity = 0;
  int startYear = 1;
  int endYear = 3000;
  string fileName = "playlist.txt";

  //Lecture des paramètres
  for(int i = PARAMS; i < argc; ++i)
  {
    if(strcmp(argv[i],"-h") == 0) usage(argv[0]);
    else if(strcmp(argv[i],"-e") == 0) energy = atof(argv[++i]);
    else if(strcmp(argv[i],"-s") == 0) size = atoi(argv[++i]);
    else if(strcmp(argv[i],"-m") == 0) mood = atof(argv[++i]);
    else if(strcmp(argv[i],"-p") == 0) popularity = atof(argv[++i]);
    else if(strcmp(argv[i],"-r") == 0) rhythm = atof(argv[++i]);
    else if(strcmp(argv[i],"-o") == 0) fileName = argv[++i];
    else if(strcmp(argv[i],"-y") == 0)
    {
      startYear = atoi(argv[++i]);
      endYear = atoi(argv[++i]);
    }
  }

  //Création de la liste d'options
  OptionList options("",startYear,endYear,popularity,energy,rhythm,mood,size);

  cout << "Initialisation du générateur." << endl;
  NaiveSimilarityStrategy similarity;
  SQLiteDatabase database(argv[1]);
  Generator generator(database, similarity);

  if(generator.initialization() == 0)
  {
    cout << "Erreur d'initialisation." << endl;
    exit(EXIT_FAILURE);
  }

  cout << "Lancement de la génération" << endl;
  Playlist playlist = generator.generate(options);
  cout << "Génération terminée" << endl;
  if(!playlist.isValid())
  {
    cout << "La génération n'a pas été satisfaisante, voulez-vous relancer une génération ? (O/N) : ";
    char answer;
    cin >> answer;
    if(answer == 'o' || answer == 'O')
    {
      cout << "Lancement de la re-génération" << endl;
      generator.regenerate(options, playlist);
      cout << "Re-génération terminée" << endl;
    }
  }
  TextOutput output;
  output.format(fileName,playlist);
  cout << "Taille de la playlist générée : " << playlist.size() << endl;

  return EXIT_SUCCESS;
}
<commit_msg>Utilisation de la strétégie de similarité non naïve<commit_after>#include <iostream>
#include <string.h>
#include <OptionList.h>
#include <SQLiteDatabase.h>
#include <SimilarityStrategy.h>
#include <Generator.h>
#include <TextOutput.h>

#define PARAMS 1

using namespace SoundCity;
using std::cout;
using std::endl;
using std::cin;
using std::string;

void
usage (char *s)
{
  fprintf(stderr, "Usage: %s <database>\n", s);

  fprintf(stderr, "Options :\n");

  fprintf(stderr, "-h : Affiche l'aide.\n");

  fprintf(stderr, "-y <startYear[1-3000]> <endYear[1-3000]> : Définit un intervalle d'années de morceaux.\n");

  fprintf(stderr, "-e <energy[0.0-1.0]> : Impose une valeur d'énergie dans la playlist générée.\n");

  fprintf(stderr, "-p <popularity[0.0-1.0]> : Impose une valeur de popularité dans la playlist générée.\n");

  fprintf(stderr, "-r <rhythm[0.0-1.0]> : Impose un rythme dans la playlist générée.\n");

  fprintf(stderr, "-m <mood[0.0-1.0]> : Impose une humeur dans la playlist générée (plus la valeur est grande plus le morceau est joyeux).\n");

  fprintf(stderr, "-s <size[1-100]> : Choix de la taille de la playlist générée (10 par défaut).\n");

  fprintf(stderr, "-o <fileName> : Choix du nom du fichier de sortie.\n");
  exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
  if (argc < PARAMS+1)
    usage(argv[0]);

  cout << "Création de la liste d'options." << endl;

  int size = 10;
  float energy = 0;
  float mood = 0;
  float rhythm = 0;
  float popularity = 0;
  int startYear = 1;
  int endYear = 3000;
  string fileName = "playlist.txt";

  //Lecture des paramètres
  for(int i = PARAMS; i < argc; ++i)
  {
    if(strcmp(argv[i],"-h") == 0) usage(argv[0]);
    else if(strcmp(argv[i],"-e") == 0) energy = atof(argv[++i]);
    else if(strcmp(argv[i],"-s") == 0) size = atoi(argv[++i]);
    else if(strcmp(argv[i],"-m") == 0) mood = atof(argv[++i]);
    else if(strcmp(argv[i],"-p") == 0) popularity = atof(argv[++i]);
    else if(strcmp(argv[i],"-r") == 0) rhythm = atof(argv[++i]);
    else if(strcmp(argv[i],"-o") == 0) fileName = argv[++i];
    else if(strcmp(argv[i],"-y") == 0)
    {
      startYear = atoi(argv[++i]);
      endYear = atoi(argv[++i]);
    }
  }

  //Création de la liste d'options
  OptionList options("",startYear,endYear,popularity,energy,rhythm,mood,size);

  cout << "Initialisation du générateur." << endl;
  SimilarityStrategy similarity;
  SQLiteDatabase database(argv[1]);
  Generator generator(database, similarity);

  if(generator.initialization() == 0)
  {
    cout << "Erreur d'initialisation." << endl;
    exit(EXIT_FAILURE);
  }

  cout << "Lancement de la génération" << endl;
  Playlist playlist = generator.generate(options);
  cout << "Génération terminée" << endl;
  if(!playlist.isValid())
  {
    cout << "La génération n'a pas été satisfaisante, voulez-vous relancer une génération ? (O/N) : ";
    char answer;
    cin >> answer;
    if(answer == 'o' || answer == 'O')
    {
      cout << "Lancement de la re-génération" << endl;
      generator.regenerate(options, playlist);
      cout << "Re-génération terminée" << endl;
    }
  }
  TextOutput output;
  output.format(fileName,playlist);
  cout << "Taille de la playlist générée : " << playlist.size() << endl;

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>Add include guard to PPG node's header file.<commit_after>#ifndef __PATTERN_POSTURE_GENERATOR_NODE_H_INCLUDE__
#define __PATTERN_POSTURE_GENERATOR_NODE_H_INCLUDE__

#endif
<|endoftext|>


<commit_before>#include "Buffer.h"
#include "Debug.h"
#include "Error.h"
#include "JITCompiledModule.h"

namespace Halide {
namespace Internal {

namespace {
template<typename UnsignedType>
bool checked_multiply(const UnsignedType &a, const UnsignedType &c, UnsignedType &result) {
    if (a == 0) {
        result = 0;
    } else {
        UnsignedType t = a * c;
        if (t / a != c)
            return false;
        result = t;
    }
    return true;
}

template<typename UnsignedType>
bool checked_multiply_assert(const UnsignedType &a, const UnsignedType &b, UnsignedType &result) {
    bool no_overflow = checked_multiply(a, b, result);
    internal_assert(no_overflow) << "Overflow in checked multiply\n";
    return no_overflow;
}
}

struct BufferContents {
    /** The buffer_t object we're wrapping. */
    buffer_t buf;

    /** The type of the allocation. buffer_t's don't currently track this so we do it here. */
    Type type;

    /** If we made the allocation ourselves via a Buffer constructor,
     * and hence should delete it when this buffer dies, then this
     * pointer is set to the memory we need to free. Otherwise it's
     * NULL. */
    uint8_t *allocation;

    /** How many Buffer objects point to this BufferContents */
    mutable RefCount ref_count;

    /** What is the name of the buffer? Useful for debugging symbols. */
    std::string name;

    /** If this buffer was generated by a jit-compiled module, we need
     * to hang onto the module, as it may contain internal state that
     * tells us how to use this buffer. In particular, if the buffer
     * was generated on the gpu and hasn't been copied back yet, only
     * the module knows how to do that, so we'd better keep the module
     * alive. */
    JITCompiledModule source_module;

    BufferContents(Type t, int x_size, int y_size, int z_size, int w_size,
                   uint8_t* data, const std::string &n) :
        type(t), allocation(NULL), name(n.empty() ? unique_name('b') : n) {
        user_assert(t.width == 1) << "Can't create of a buffer of a vector type";
        buf.elem_size = t.bytes();
        size_t size = 1;
        if (x_size)
            checked_multiply_assert<size_t>(size, x_size, size);
        if (y_size)
            checked_multiply_assert<size_t>(size, y_size, size);
        if (z_size)
            checked_multiply_assert<size_t>(size, z_size, size);
        if (w_size)
            checked_multiply_assert<size_t>(size, w_size, size);
        if (!data) {
            checked_multiply_assert<size_t>(size, buf.elem_size, size);
            user_assert(size < ((1UL << 31) - 1)) << "Total size of buffer " << name << " exceeds 2^31 - 1\n";
            size = size + 32;
            allocation = (uint8_t *)calloc(1, size);
            user_assert(allocation) << "Out of memory allocating buffer " << name << " of size " << size << "\n";
            buf.host = allocation;
            while ((size_t)(buf.host) & 0x1f) buf.host++;
        } else {
            buf.host = data;
        }
        buf.dev = 0;
        buf.host_dirty = false;
        buf.dev_dirty = false;
        buf.extent[0] = x_size;
        buf.extent[1] = y_size;
        buf.extent[2] = z_size;
        buf.extent[3] = w_size;
        buf.stride[0] = 1;
        buf.stride[1] = x_size;
        buf.stride[2] = x_size*y_size;
        buf.stride[3] = x_size*y_size*z_size;
        buf.min[0] = 0;
        buf.min[1] = 0;
        buf.min[2] = 0;
        buf.min[3] = 0;
    }

    BufferContents(Type t, const buffer_t *b, const std::string &n) :
        type(t), allocation(NULL), name(n.empty() ? unique_name('b') : n) {
        buf = *b;
        user_assert(t.width == 1) << "Can't create of a buffer of a vector type";
    }
};

template<>
RefCount &ref_count<BufferContents>(const BufferContents *p) {
    return p->ref_count;
}

template<>
void destroy<BufferContents>(const BufferContents *p) {
    // Free any device-side allocation
    if (p->source_module.free_dev_buffer) {
        p->source_module.free_dev_buffer(NULL, const_cast<buffer_t *>(&p->buf));
    }
    free(p->allocation);

    delete p;
}

}

namespace {
int32_t size_or_zero(const std::vector<int32_t> &sizes, size_t index) {
    return (index < sizes.size()) ? sizes[index] : 0;
}

std::string make_buffer_name(const std::string &n, Buffer *b) {
    if (n.empty()) {
        return Internal::make_entity_name(b, "Halide::Buffer", 'b');
    } else {
        return n;
    }
}
}

Buffer::Buffer(Type t, int x_size, int y_size, int z_size, int w_size,
               uint8_t* data, const std::string &name) :
    contents(new Internal::BufferContents(t, x_size, y_size, z_size, w_size, data,
                                          make_buffer_name(name, this))) {
}

Buffer::Buffer(Type t, const std::vector<int32_t> &sizes,
               uint8_t* data, const std::string &name) :
    contents(new Internal::BufferContents(t,
                                          size_or_zero(sizes, 0),
                                          size_or_zero(sizes, 1),
                                          size_or_zero(sizes, 2),
                                          size_or_zero(sizes, 3),
                                          data,
                                          make_buffer_name(name, this))) {
    user_assert(sizes.size() <= 4) << "Buffer dimensions greater than 4 are not supported.";
}

Buffer::Buffer(Type t, const buffer_t *buf, const std::string &name) :
    contents(new Internal::BufferContents(t, buf,
                                          make_buffer_name(name, this))) {
}

void *Buffer::host_ptr() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return (void *)contents.ptr->buf.host;
}

buffer_t *Buffer::raw_buffer() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return &(contents.ptr->buf);
}

uint64_t Buffer::device_handle() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->buf.dev;
}

bool Buffer::host_dirty() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->buf.host_dirty;
}

void Buffer::set_host_dirty(bool dirty) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->buf.host_dirty = dirty;
}

bool Buffer::device_dirty() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->buf.dev_dirty;
}

void Buffer::set_device_dirty(bool dirty) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->buf.host_dirty = dirty;
}

int Buffer::dimensions() const {
    for (int i = 0; i < 4; i++) {
        if (extent(i) == 0) return i;
    }
    return 4;
}

int Buffer::extent(int dim) const {
    user_assert(defined()) << "Buffer is undefined\n";
    user_assert(dim >= 0 && dim < 4) << "We only support 4-dimensional buffers for now";
    return contents.ptr->buf.extent[dim];
}

int Buffer::stride(int dim) const {
    user_assert(defined());
    user_assert(dim >= 0 && dim < 4) << "We only support 4-dimensional buffers for now";
    return contents.ptr->buf.stride[dim];
}

int Buffer::min(int dim) const {
    user_assert(defined()) << "Buffer is undefined\n";
    user_assert(dim >= 0 && dim < 4) << "We only support 4-dimensional buffers for now";
    return contents.ptr->buf.min[dim];
}

void Buffer::set_min(int m0, int m1, int m2, int m3) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->buf.min[0] = m0;
    contents.ptr->buf.min[1] = m1;
    contents.ptr->buf.min[2] = m2;
    contents.ptr->buf.min[3] = m3;
}

Type Buffer::type() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->type;
}

bool Buffer::same_as(const Buffer &other) const {
    return contents.same_as(other.contents);
}

bool Buffer::defined() const {
    return contents.defined();
}

const std::string &Buffer::name() const {
    return contents.ptr->name;
}

Buffer::operator Argument() const {
    return Argument(name(), true, type());
}

void Buffer::set_source_module(const Internal::JITCompiledModule &module) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->source_module = module;
}

const Internal::JITCompiledModule &Buffer::source_module() {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->source_module;
}

void Buffer::copy_to_host() {
    void (*copy_to_host)(void *, buffer_t *) =
        contents.ptr->source_module.copy_to_host;
    if (copy_to_host) {
        /* The user context is always NULL when jitting, so it's safe to
         * pass NULL here. */
        copy_to_host(NULL, raw_buffer());
    }
}

void Buffer::copy_to_dev() {
    void (*copy_to_dev)(void *, buffer_t *) =
        contents.ptr->source_module.copy_to_dev;
    if (copy_to_dev) {
        copy_to_dev(NULL, raw_buffer());
    }
}

void Buffer::free_dev_buffer() {
    void (*free_dev_buffer)(void *, buffer_t *) =
        contents.ptr->source_module.free_dev_buffer;
    if (free_dev_buffer) {
        free_dev_buffer(NULL, raw_buffer());
    }
}

}
<commit_msg>moved error for too large buffers<commit_after>#include "Buffer.h"
#include "Debug.h"
#include "Error.h"
#include "JITCompiledModule.h"

namespace Halide {
namespace Internal {

namespace {
void check_buffer_size(uint64_t bytes, const std::string &name) {
    user_assert(bytes < (1UL << 31)) << "Total size of buffer " << name << " exceeds 2^31 - 1\n";
}
}

struct BufferContents {
    /** The buffer_t object we're wrapping. */
    buffer_t buf;

    /** The type of the allocation. buffer_t's don't currently track this so we do it here. */
    Type type;

    /** If we made the allocation ourselves via a Buffer constructor,
     * and hence should delete it when this buffer dies, then this
     * pointer is set to the memory we need to free. Otherwise it's
     * NULL. */
    uint8_t *allocation;

    /** How many Buffer objects point to this BufferContents */
    mutable RefCount ref_count;

    /** What is the name of the buffer? Useful for debugging symbols. */
    std::string name;

    /** If this buffer was generated by a jit-compiled module, we need
     * to hang onto the module, as it may contain internal state that
     * tells us how to use this buffer. In particular, if the buffer
     * was generated on the gpu and hasn't been copied back yet, only
     * the module knows how to do that, so we'd better keep the module
     * alive. */
    JITCompiledModule source_module;

    BufferContents(Type t, int x_size, int y_size, int z_size, int w_size,
                   uint8_t* data, const std::string &n) :
        type(t), allocation(NULL), name(n.empty() ? unique_name('b') : n) {
        user_assert(t.width == 1) << "Can't create of a buffer of a vector type";
        buf.elem_size = t.bytes();
        uint64_t size = 1;
        if (x_size) {
            size *= x_size;
            check_buffer_size(size, name);
        }
        if (y_size) {
            size *= y_size;
            check_buffer_size(size, name);
        }
        if (z_size) {
            size *= z_size;
            check_buffer_size(size, name);
        }
        if (w_size) {
            size *= w_size;
            check_buffer_size(size, name);
        }
        size *= buf.elem_size;
        check_buffer_size(size, name);

        if (!data) {
            size = size + 32;
            check_buffer_size(size, name);
            allocation = (uint8_t *)calloc(1, (size_t)size);
            user_assert(allocation) << "Out of memory allocating buffer " << name << " of size " << size << "\n";
            buf.host = allocation;
            while ((size_t)(buf.host) & 0x1f) buf.host++;
        } else {
            buf.host = data;
        }
        buf.dev = 0;
        buf.host_dirty = false;
        buf.dev_dirty = false;
        buf.extent[0] = x_size;
        buf.extent[1] = y_size;
        buf.extent[2] = z_size;
        buf.extent[3] = w_size;
        buf.stride[0] = 1;
        buf.stride[1] = x_size;
        buf.stride[2] = x_size*y_size;
        buf.stride[3] = x_size*y_size*z_size;
        buf.min[0] = 0;
        buf.min[1] = 0;
        buf.min[2] = 0;
        buf.min[3] = 0;
    }

    BufferContents(Type t, const buffer_t *b, const std::string &n) :
        type(t), allocation(NULL), name(n.empty() ? unique_name('b') : n) {
        buf = *b;
        user_assert(t.width == 1) << "Can't create of a buffer of a vector type";
    }
};

template<>
RefCount &ref_count<BufferContents>(const BufferContents *p) {
    return p->ref_count;
}

template<>
void destroy<BufferContents>(const BufferContents *p) {
    // Free any device-side allocation
    if (p->source_module.free_dev_buffer) {
        p->source_module.free_dev_buffer(NULL, const_cast<buffer_t *>(&p->buf));
    }
    free(p->allocation);

    delete p;
}

}

namespace {
int32_t size_or_zero(const std::vector<int32_t> &sizes, size_t index) {
    return (index < sizes.size()) ? sizes[index] : 0;
}

std::string make_buffer_name(const std::string &n, Buffer *b) {
    if (n.empty()) {
        return Internal::make_entity_name(b, "Halide::Buffer", 'b');
    } else {
        return n;
    }
}
}

Buffer::Buffer(Type t, int x_size, int y_size, int z_size, int w_size,
               uint8_t* data, const std::string &name) :
    contents(new Internal::BufferContents(t, x_size, y_size, z_size, w_size, data,
                                          make_buffer_name(name, this))) {
}

Buffer::Buffer(Type t, const std::vector<int32_t> &sizes,
               uint8_t* data, const std::string &name) :
    contents(new Internal::BufferContents(t,
                                          size_or_zero(sizes, 0),
                                          size_or_zero(sizes, 1),
                                          size_or_zero(sizes, 2),
                                          size_or_zero(sizes, 3),
                                          data,
                                          make_buffer_name(name, this))) {
    user_assert(sizes.size() <= 4) << "Buffer dimensions greater than 4 are not supported.";
}

Buffer::Buffer(Type t, const buffer_t *buf, const std::string &name) :
    contents(new Internal::BufferContents(t, buf,
                                          make_buffer_name(name, this))) {
}

void *Buffer::host_ptr() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return (void *)contents.ptr->buf.host;
}

buffer_t *Buffer::raw_buffer() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return &(contents.ptr->buf);
}

uint64_t Buffer::device_handle() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->buf.dev;
}

bool Buffer::host_dirty() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->buf.host_dirty;
}

void Buffer::set_host_dirty(bool dirty) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->buf.host_dirty = dirty;
}

bool Buffer::device_dirty() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->buf.dev_dirty;
}

void Buffer::set_device_dirty(bool dirty) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->buf.host_dirty = dirty;
}

int Buffer::dimensions() const {
    for (int i = 0; i < 4; i++) {
        if (extent(i) == 0) return i;
    }
    return 4;
}

int Buffer::extent(int dim) const {
    user_assert(defined()) << "Buffer is undefined\n";
    user_assert(dim >= 0 && dim < 4) << "We only support 4-dimensional buffers for now";
    return contents.ptr->buf.extent[dim];
}

int Buffer::stride(int dim) const {
    user_assert(defined());
    user_assert(dim >= 0 && dim < 4) << "We only support 4-dimensional buffers for now";
    return contents.ptr->buf.stride[dim];
}

int Buffer::min(int dim) const {
    user_assert(defined()) << "Buffer is undefined\n";
    user_assert(dim >= 0 && dim < 4) << "We only support 4-dimensional buffers for now";
    return contents.ptr->buf.min[dim];
}

void Buffer::set_min(int m0, int m1, int m2, int m3) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->buf.min[0] = m0;
    contents.ptr->buf.min[1] = m1;
    contents.ptr->buf.min[2] = m2;
    contents.ptr->buf.min[3] = m3;
}

Type Buffer::type() const {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->type;
}

bool Buffer::same_as(const Buffer &other) const {
    return contents.same_as(other.contents);
}

bool Buffer::defined() const {
    return contents.defined();
}

const std::string &Buffer::name() const {
    return contents.ptr->name;
}

Buffer::operator Argument() const {
    return Argument(name(), true, type());
}

void Buffer::set_source_module(const Internal::JITCompiledModule &module) {
    user_assert(defined()) << "Buffer is undefined\n";
    contents.ptr->source_module = module;
}

const Internal::JITCompiledModule &Buffer::source_module() {
    user_assert(defined()) << "Buffer is undefined\n";
    return contents.ptr->source_module;
}

void Buffer::copy_to_host() {
    void (*copy_to_host)(void *, buffer_t *) =
        contents.ptr->source_module.copy_to_host;
    if (copy_to_host) {
        /* The user context is always NULL when jitting, so it's safe to
         * pass NULL here. */
        copy_to_host(NULL, raw_buffer());
    }
}

void Buffer::copy_to_dev() {
    void (*copy_to_dev)(void *, buffer_t *) =
        contents.ptr->source_module.copy_to_dev;
    if (copy_to_dev) {
        copy_to_dev(NULL, raw_buffer());
    }
}

void Buffer::free_dev_buffer() {
    void (*free_dev_buffer)(void *, buffer_t *) =
        contents.ptr->source_module.free_dev_buffer;
    if (free_dev_buffer) {
        free_dev_buffer(NULL, raw_buffer());
    }
}

}
<|endoftext|>


<commit_before>#include <QStringList>

#include "kernel.h"
#include "raster.h"
#include "astnode.h"
#include "idnode.h"
#include "kernel.h"
#include "symboltable.h"
#include "operationnode.h"
#include "expressionnode.h"
#include "parametersnode.h"
#include "selectornode.h"
#include "termnode.h"
#include "commandhandler.h"

using namespace Ilwis;

TermNode::TermNode() : _logicalNegation(false), _numericalNegation(false)
{
}

void TermNode::setNumerical(char *num)
{
    QString s(num);
    _content = csNumerical;
    if ( s == "?") {
        _number = Ilwis::rUNDEF;
        return;
    }
    bool ok;
    double b =s.toDouble(&ok);
    _number = b;
    if(!ok) {
        _number = Ilwis::rUNDEF;
    }

}

void TermNode::setId(IDNode *node)
{
    _id = QSharedPointer<IDNode>(node)   ;
    _content = csID;
}

void TermNode::setExpression(ExpressionNode *n)
{
    _expression = QSharedPointer<ExpressionNode>(n);
    _content = csExpression;
}

void TermNode::setString(char *s)
{
    _string = QString(s);
    _content = csString;
}

void TermNode::setParameters(ParametersNode *n)
{
    _parameters = QSharedPointer<ParametersNode>(n);
    _content = csMethod;
}

QString TermNode::nodeType() const
{
    return "term";
}

void TermNode::setLogicalNegation(bool yesno)
{
    _logicalNegation = yesno;
}

void TermNode::setNumericalNegation(bool yesno)
{
    _numericalNegation = yesno;
}

bool TermNode::evaluate(SymbolTable &symbols, int scope, ExecutionContext *ctx)
{
    if ( _content == csExpression)  {
        if (_expression->evaluate(symbols, scope, ctx)) {
            _value = {_expression->value(), NodeValue::ctExpression};
            return true;
        }
    } else if (_content == csNumerical) {
        if ( _numericalNegation)
            _value = {-_number, NodeValue::ctNumerical};
        else
            _value = {_number, NodeValue::ctNumerical};
        return true;

    } else if ( _content == csString) {
        _value = {_string, NodeValue::ctString};
        return true;

    } else if ( _content == csMethod) {
        QString parms = "(";
        for(int i=0; i < _parameters->noOfChilderen(); ++i) {
            bool ok = _parameters->child(i)->evaluate(symbols, scope, ctx);
            if (!ok)
                return false;
            QString name = getName(_parameters->child(i)->value());
            if ( i != 0)
                parms += ",";
            parms += name;

        }
        parms += ")";
        QString expression = _id->id() + parms;
        bool ok = Ilwis::commandhandler()->execute(expression, ctx, symbols);
        if ( !ok || ctx->_results.size() != 1)
            throw ScriptExecutionError(TR("Expression execution error in script; script aborted. See log for further details"));

        _value = {symbols.getValue(ctx->_results[0]), ctx->_results[0], NodeValue::ctMethod};
        return true;

    } else if ( _content == csID) {
        _id->evaluate(symbols, scope, ctx);
        QString value;
        if ( _id->isReference()) {
            if ( symbols.getSymbol(_id->id(),scope).isValid())
                value = _id->id();
            else
                return false;
        }
        else
            value = _id->id();
        if ( _selectors.size() > 0) {
            // selectors are handled by successive calls to the selection operation and in the end giving the temp object to the value
            for(QSharedPointer<Selector> selector: _selectors)  {
                QString selectordef;
                if ( !selector->box().isNull())
                    selectordef = QString("\"box=%1 %2, %3 %4\"").arg(selector->box().min_corner().x).arg(selector->box().min_corner().y).
                                                                arg(selector->box().max_corner().x).arg(selector->box().max_corner().y);
                else if (selector->selectorType() == "index") {
                    selectordef = "\"index=" + selector->variable() + "\"";
                } else if (selector->selectorType() == "columnrange") {
                    selectordef = QString("\"columnrange=%1,%2").arg(selector->beginCol()).arg(selector->endCol());
                    if ( selector->keyColumns() != sUNDEF)
                        selectordef += "," + selector->keyColumns();
                    selectordef += "\"";
                }else if (selector->selectorType() == "recordrange") {
                    selectordef = QString("\"recordrange=%1,%2").arg(selector->beginRec()).arg(selector->endRec());
                    selectordef += "\"";
                }else if (selector->selectorType() == "columnrecordrange") {
                    selectordef = QString("\"columnrecordrange=%1,%2,%3, %4").arg(selector->beginCol()).
                                                                              arg(selector->endCol()).
                                                                              arg(selector->beginRec()).
                                                                              arg(selector->endRec());
                    if ( selector->keyColumns() != sUNDEF)
                        selectordef += "," + selector->keyColumns();
                    selectordef += "\"";
                }
                else if ( selector->variable() != sUNDEF)
                    selectordef = "\"attribute=" + selector->variable() + "\"";
                QString outname = ANONYMOUS_PREFIX;
                QString expression = QString("%1=selection(%2,%3)").arg(outname).arg(value).arg(selectordef);
                if(!Ilwis::commandhandler()->execute(expression, ctx, symbols)) {
                    throw ScriptExecutionError(TR("Expression execution error in script; script aborted. See log for further details"));
                }
                QString outgc = ctx->_results[0];
                value = outgc;
            }
        }
        _value = {value, NodeValue::ctID};
        return value != "" && value != sUNDEF;

    }
    return false;
}

QString TermNode::getName(const NodeValue& var) const {
    QString name = var.toString();
    if (name != sUNDEF)
        return name;
//    QString typeName = var.typeName();
//    if ( typeName == "Ilwis::IRasterCoverage") {
//        Ilwis::IRasterCoverage raster = var.value<Ilwis::IRasterCoverage>();
//        name = raster->name();
//    }
//    if ( typeName == "Coordinate") {
//        name = var.id();
//    }
//    if ( typeName == "Voxel") {
//        name = var.id();
//    }
    return var.id();
}

void TermNode::addSelector(Selector *n)
{
    _selectors.push_back(QSharedPointer<Selector>(n));
}
<commit_msg>added handling of auto parameters<commit_after>#include <QStringList>

#include "kernel.h"
#include "raster.h"
#include "astnode.h"
#include "idnode.h"
#include "kernel.h"
#include "symboltable.h"
#include "operationnode.h"
#include "expressionnode.h"
#include "parametersnode.h"
#include "selectornode.h"
#include "selectnode.h"
#include "termnode.h"
#include "commandhandler.h"

using namespace Ilwis;

TermNode::TermNode() : _logicalNegation(false), _numericalNegation(false)
{
}

void TermNode::setNumerical(char *num)
{
    QString s(num);
    _content = csNumerical;
    if ( s == "?") {
        _number = Ilwis::rUNDEF;
        return;
    }
    bool ok;
    double b =s.toDouble(&ok);
    _number = b;
    if(!ok) {
        _number = Ilwis::rUNDEF;
    }

}

void TermNode::setId(IDNode *node)
{
    _id = QSharedPointer<IDNode>(node)   ;
    _content = csID;
}

void TermNode::setExpression(ExpressionNode *n)
{
    _expression = QSharedPointer<ExpressionNode>(n);
    _content = csExpression;
}

void TermNode::setString(char *s)
{
    _string = QString(s);
    _content = csString;
}

void TermNode::setParameters(ParametersNode *n)
{
    _parameters = QSharedPointer<ParametersNode>(n);
    _content = csMethod;
}

QString TermNode::nodeType() const
{
    return "term";
}

void TermNode::setLogicalNegation(bool yesno)
{
    _logicalNegation = yesno;
}

void TermNode::setNumericalNegation(bool yesno)
{
    _numericalNegation = yesno;
}

bool TermNode::evaluate(SymbolTable &symbols, int scope, ExecutionContext *ctx)
{
    if ( _content == csExpression)  {
        if (_expression->evaluate(symbols, scope, ctx)) {
            _value = {_expression->value(), NodeValue::ctExpression};
            return true;
        }
    } else if (_content == csNumerical) {
        if ( _numericalNegation)
            _value = {-_number, NodeValue::ctNumerical};
        else
            _value = {_number, NodeValue::ctNumerical};
        return true;
    } else if ( _content == csString) {
        _value = {_string, NodeValue::ctString};
        return true;

    } else if ( _content == csMethod) {
        QString parms = "(";
        for(int i=0; i < ctx->_additionalInfo.size() && ctx->_useAdditionalParameters; ++i){
            QString extrapar = "extra" + QString::number(i);
            auto iter = ctx->_additionalInfo.find(extrapar);
            if ( iter != ctx->_additionalInfo.end()){
                if ( parms.size() > 1)
                    parms += ",";
                parms += (*iter).second;
            }
        }
        for(int i=0; i < _parameters->noOfChilderen(); ++i) {
            bool ok = _parameters->child(i)->evaluate(symbols, scope, ctx);

            if (!ok)
                return false;
            QString name = getName(_parameters->child(i)->value());
            if ( parms.size() > 1)
                parms += ",";
            parms += name;

        }
        parms += ")";
        QString expression = _id->id() + parms;
        bool ok = Ilwis::commandhandler()->execute(expression, ctx, symbols);
        if ( !ok || ctx->_results.size() != 1)
            throw ScriptExecutionError(TR("Expression execution error in script; script aborted. See log for further details"));

        _value = {symbols.getValue(ctx->_results[0]), ctx->_results[0], NodeValue::ctMethod};
        return true;

    } else if ( _content == csID) {
        _id->evaluate(symbols, scope, ctx);
        QString value;
        if ( _id->isReference()) {
            if ( symbols.getSymbol(_id->id(),scope).isValid())
                value = _id->id();
            else
                return false;
        }
        else
            value = _id->id();
        if ( _selectors.size() > 0) {
            // selectors are handled by successive calls to the selection operation and in the end giving the temp object to the value
            for(QSharedPointer<Selector> selector: _selectors)  {
                QString selectordef;
                if ( !selector->box().isNull())
                    selectordef = QString("\"box=%1 %2, %3 %4\"").arg(selector->box().min_corner().x).arg(selector->box().min_corner().y).
                                                                arg(selector->box().max_corner().x).arg(selector->box().max_corner().y);
                else if (selector->selectorType() == "index") {
                    selectordef = "\"index=" + selector->variable() + "\"";
                } else if (selector->selectorType() == "columnrange") {
                    selectordef = QString("\"columnrange=%1,%2").arg(selector->beginCol()).arg(selector->endCol());
                    if ( selector->keyColumns() != sUNDEF)
                        selectordef += "," + selector->keyColumns();
                    selectordef += "\"";
                }else if (selector->selectorType() == "recordrange") {
                    selectordef = QString("\"recordrange=%1,%2").arg(selector->beginRec()).arg(selector->endRec());
                    selectordef += "\"";
                }else if (selector->selectorType() == "columnrecordrange") {
                    selectordef = QString("\"columnrecordrange=%1,%2,%3, %4").arg(selector->beginCol()).
                                                                              arg(selector->endCol()).
                                                                              arg(selector->beginRec()).
                                                                              arg(selector->endRec());
                    if ( selector->keyColumns() != sUNDEF)
                        selectordef += "," + selector->keyColumns();
                    selectordef += "\"";
                }
                else if ( selector->variable() != sUNDEF)
                    selectordef = "\"attribute=" + selector->variable() + "\"";
                QString outname = ANONYMOUS_PREFIX;
                QString expression = QString("%1=selection(%2,%3)").arg(outname).arg(value).arg(selectordef);
                if(!Ilwis::commandhandler()->execute(expression, ctx, symbols)) {
                    throw ScriptExecutionError(TR("Expression execution error in script; script aborted. See log for further details"));
                }
                QString outgc = ctx->_results[0];
                value = outgc;
            }
        }
        _value = {value, NodeValue::ctID};
        return value != "" && value != sUNDEF;

    }
    return false;
}

QString TermNode::getName(const NodeValue& var) const {
    QString name = var.toString();
    if (name != sUNDEF)
        return name;
//    QString typeName = var.typeName();
//    if ( typeName == "Ilwis::IRasterCoverage") {
//        Ilwis::IRasterCoverage raster = var.value<Ilwis::IRasterCoverage>();
//        name = raster->name();
//    }
//    if ( typeName == "Coordinate") {
//        name = var.id();
//    }
//    if ( typeName == "Voxel") {
//        name = var.id();
//    }
    return var.id();
}

void TermNode::addSelector(Selector *n)
{
    _selectors.push_back(QSharedPointer<Selector>(n));
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/common/cyclic_barrier.hpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Emanuel Jbstl <emanuel.joebstl@gmail.com>
 *
 * This file has no license. Only Timo Bingmann can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_COMMON_CYCLIC_BARRIER_HEADER
#define C7A_COMMON_CYCLIC_BARRIER_HEADER

#include <mutex>
#include <atomic>
#include <condition_variable>

namespace c7a {
namespace common {

/**
 * @brief Implements a cyclic barrier that can be shared between threads.
 */
class Barrier
{
    std::mutex m;
    std::condition_variable_any event;
    const int threadCount;
    int counts[2];
    int current;

public:
    /**
     * @brief Creates a new barrier that waits for n threads.
     *
     * @param n The count of threads to wait for.
     */
    Barrier(int n) : threadCount(n), current(0) {
        counts[0] = 0;
        counts[1] = 0;
    }

    /**
     * @brief Waits for n threads to arrive.
     * @details This method blocks and returns as soon as n threads are waiting inside the method.
     */
    void await() {
        std::atomic_thread_fence(std::memory_order_release);
        m.lock();
        int localCurrent = current;
        counts[localCurrent]++;

        if (counts[localCurrent] < threadCount) {
            while (counts[localCurrent] < threadCount) {
                event.wait(m);
            }
        }
        else {
            current = current ? 0 : 1;
            counts[current] = 0;
            event.notify_all();
        }
        m.unlock();
    }
};
} // namespace common
} // namespace c7a

#endif // !C7A_COMMON_CYCLIC_BARRIER_HEADER

/******************************************************************************/
<commit_msg>make member variables private<commit_after>/*******************************************************************************
 * c7a/common/cyclic_barrier.hpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Emanuel Jbstl <emanuel.joebstl@gmail.com>
 *
 * This file has no license. Only Timo Bingmann can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_COMMON_CYCLIC_BARRIER_HEADER
#define C7A_COMMON_CYCLIC_BARRIER_HEADER

#include <mutex>
#include <atomic>
#include <condition_variable>

namespace c7a {
namespace common {

/**
 * @brief Implements a cyclic barrier that can be shared between threads.
 */
class Barrier
{

private:
    std::mutex m;
    std::condition_variable_any event;
    const int threadCount;
    int counts[2];
    int current;

public:
    /**
     * @brief Creates a new barrier that waits for n threads.
     *
     * @param n The count of threads to wait for.
     */
    Barrier(int n) : threadCount(n), current(0) {
        counts[0] = 0;
        counts[1] = 0;
    }

    /**
     * @brief Waits for n threads to arrive.
     * @details This method blocks and returns as soon as n threads are waiting inside the method.
     */
    void await() {
        std::atomic_thread_fence(std::memory_order_release);
        m.lock();
        int localCurrent = current;
        counts[localCurrent]++;

        if (counts[localCurrent] < threadCount) {
            while (counts[localCurrent] < threadCount) {
                event.wait(m);
            }
        }
        else {
            current = current ? 0 : 1;
            counts[current] = 0;
            event.notify_all();
        }
        m.unlock();
    }
};
} // namespace common
} // namespace c7a

#endif // !C7A_COMMON_CYCLIC_BARRIER_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>//
//  Camera.cpp
//  Cinder-EDSDK
//
//  Created by Jean-Pierre Mouilleseaux on 08 Dec 2013.
//  Copyright 2013-2014 Chorded Constructions. All rights reserved.
//

#include "Camera.h"
#include "CameraBrowser.h"

using namespace ci;
using namespace ci::app;

namespace Cinder { namespace EDSDK {

#pragma mark CAMERA FILE

CameraFileRef CameraFile::create(EdsDirectoryItemRef directoryItem) {
    return CameraFileRef(new CameraFile(directoryItem))->shared_from_this();
}

CameraFile::CameraFile(EdsDirectoryItemRef directoryItem) {
    if (!directoryItem) {
        throw Exception();
    }

    EdsRetain(directoryItem);
    mDirectoryItem = directoryItem;

    EdsError error = EdsGetDirectoryItemInfo(mDirectoryItem, &mDirectoryItemInfo);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get directory item info" << std::endl;
        throw Exception();
    }
}

CameraFile::~CameraFile() {
    EdsRelease(mDirectoryItem);
    mDirectoryItem = NULL;
}

std::string CameraFile::getName() const {
    return std::string(mDirectoryItemInfo.szFileName);
}

uint32_t CameraFile::getSize() const {
    return mDirectoryItemInfo.size;
}

#pragma mark - CAMERA

CameraRef Camera::create(EdsCameraRef camera) {
    return CameraRef(new Camera(camera))->shared_from_this();
}

Camera::Camera(EdsCameraRef camera) {
    if (!camera) {
        throw Exception();
    }

    EdsRetain(camera);
    mCamera = camera;

    EdsError error = EdsGetDeviceInfo(mCamera, &mDeviceInfo);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get device info" << std::endl;
        // TODO - NULL out mDeviceInfo
    }

    mHasOpenSession = false;

    // set event handlers
    error = EdsSetObjectEventHandler(mCamera, kEdsObjectEvent_All, Camera::handleObjectEvent, this);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set object event handler" << std::endl;
    }
    error = EdsSetPropertyEventHandler(mCamera, kEdsPropertyEvent_All, Camera::handlePropertyEvent, this);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set property event handler" << std::endl;
    }
    error = EdsSetCameraStateEventHandler(mCamera, kEdsStateEvent_All, Camera::handleStateEvent, this);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set object event handler" << std::endl;
    }
}

Camera::~Camera() {
    mRemovedHandler = NULL;
    mFileAddedHandler = NULL;

    if (mHasOpenSession) {
        requestCloseSession();
    }

    // NB - after EDSDK 2.10 releasing the EdsCameraRef will cause an EXC_BAD_ACCESS (code=EXC_I386_GPFLT) at the end of the runloop
//    EdsRelease(mCamera);
    mCamera = NULL;
}

#pragma mark -

void Camera::connectRemovedHandler(const std::function<void(CameraRef)>& handler) {
    mRemovedHandler = handler;
}

void Camera::connectFileAddedHandler(const std::function<void(CameraRef, CameraFileRef)>& handler) {
    mFileAddedHandler = handler;
}

std::string Camera::getName() const {
    return std::string(mDeviceInfo.szDeviceDescription);
}

std::string Camera::getPortName() const {
    return std::string(mDeviceInfo.szPortName);
}

bool Camera::hasOpenSession() const {
    return mHasOpenSession;
}

EdsError Camera::requestOpenSession(const Settings &settings) {
    if (mHasOpenSession) {
        return EDS_ERR_SESSION_ALREADY_OPEN;
    }

    EdsError error = EdsOpenSession(mCamera);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to open camera session" << std::endl;
        return error;
    }
    mHasOpenSession = true;

    mShouldKeepAlive = settings.getShouldKeepAlive();
    EdsUInt32 saveTo = settings.getPictureSaveLocation();
    error = EdsSetPropertyData(mCamera, kEdsPropID_SaveTo, 0, sizeof(saveTo) , &saveTo);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set save destination host/device" << std::endl;
        return error;
    }

    if (saveTo == kEdsSaveTo_Host) {
        // ??? - requires UI lock?
        EdsCapacity capacity = {0x7FFFFFFF, 0x1000, 1};
        error = EdsSetCapacity(mCamera, capacity);
        if (error != EDS_ERR_OK) {
            console() << "ERROR - failed to set capacity of host" << std::endl;
            return error;
        }
    }

    return EDS_ERR_OK;
}

EdsError Camera::requestCloseSession() {
    if (!mHasOpenSession) {
        return EDS_ERR_SESSION_NOT_OPEN;
    }

    EdsError error = EdsCloseSession(mCamera);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to close camera session" << std::endl;
        return error;
    }

    mHasOpenSession = false;
    return EDS_ERR_OK;
}

EdsError Camera::requestTakePicture() {
    if (!mHasOpenSession) {
        return EDS_ERR_SESSION_NOT_OPEN;
    }

    EdsError error = EdsSendCommand(mCamera, kEdsCameraCommand_TakePicture, 0);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to take picture" << std::endl;
    }
    return error;
}

void Camera::requestDownloadFile(const CameraFileRef file, const fs::path destinationFolderPath, std::function<void(EdsError error, ci::fs::path outputFilePath)> callback) {
    // check if destination exists and create if not
    if (!fs::exists(destinationFolderPath)) {
        bool status = fs::create_directories(destinationFolderPath);
        if (!status) {
            console() << "ERROR - failed to create destination folder path '" << destinationFolderPath << "'" << std::endl;
            return callback(EDS_ERR_INTERNAL_ERROR, NULL);
        }
    }

    fs::path filePath = destinationFolderPath / file->getName();

    EdsStreamRef stream = NULL;
    EdsError error = EdsCreateFileStream(filePath.generic_string().c_str(), kEdsFileCreateDisposition_CreateAlways, kEdsAccess_ReadWrite, &stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to create file stream" << std::endl;
        goto download_cleanup;
    }

    error = EdsDownload(file->mDirectoryItem, file->getSize(), stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to download" << std::endl;
        goto download_cleanup;
    }

    error = EdsDownloadComplete(file->mDirectoryItem);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to mark download as complete" << std::endl;
        goto download_cleanup;
    }

download_cleanup:
    if (stream) {
        EdsRelease(stream);
    }

    callback(error, filePath);
}

void Camera::requestReadFile(const CameraFileRef file, std::function<void(EdsError error, ci::Surface8u surface)> callback) {
    Buffer buffer = NULL;
    ci::Surface surface;

    EdsStreamRef stream = NULL;
    EdsError error = EdsCreateMemoryStream(0, &stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to create memory stream" << std::endl;
        goto read_cleanup;
    }

    error = EdsDownload(file->mDirectoryItem, file->getSize(), stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to download" << std::endl;
        goto read_cleanup;
    }

    error = EdsDownloadComplete(file->mDirectoryItem);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to mark download as complete" << std::endl;
        goto read_cleanup;
    }

    void* data;
    error = EdsGetPointer(stream, (EdsVoid**)&data);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get pointer from stream" << std::endl;
        goto read_cleanup;
    }

    EdsUInt32 length;
    error = EdsGetLength(stream, &length);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get stream length" << std::endl;
        goto read_cleanup;
    }

    buffer = Buffer(data, length);
    surface = Surface8u(loadImage(DataSourceBuffer::create(buffer), ImageSource::Options(), "jpg"));

read_cleanup:
    if (stream) {
        EdsRelease(stream);
    }

    callback(error, surface);
}

#pragma mark - CALLBACKS

EdsError EDSCALLBACK Camera::handleObjectEvent(EdsUInt32 inEvent, EdsBaseRef inRef, EdsVoid* inContext) {
    Camera* c = (Camera*)inContext;
    CameraRef camera = CameraBrowser::instance()->cameraForPortName(c->getPortName());
    switch (inEvent) {
        case kEdsObjectEvent_DirItemRequestTransfer: {
            EdsDirectoryItemRef directoryItem = (EdsDirectoryItemRef)inRef;
            CameraFileRef file = NULL;
            try {
                file = CameraFile::create(directoryItem);
            } catch (...) {
                EdsRelease(directoryItem);
                break;
            }
            EdsRelease(directoryItem);
            directoryItem = NULL;
            if (camera->mFileAddedHandler) {
                camera->mFileAddedHandler(camera, file);
            }
            break;
        }
        default:
            if (inRef) {
                EdsRelease(inRef);
                inRef = NULL;
            }
            break;
    }
    return EDS_ERR_OK;
}

EdsError EDSCALLBACK Camera::handlePropertyEvent(EdsUInt32 inEvent, EdsUInt32 inPropertyID, EdsUInt32 inParam, EdsVoid* inContext) {
    return EDS_ERR_OK;
}

EdsError EDSCALLBACK Camera::handleStateEvent(EdsUInt32 inEvent, EdsUInt32 inParam, EdsVoid* inContext) {
    Camera* c = (Camera*)inContext;
    CameraRef camera = CameraBrowser::instance()->cameraForPortName(c->getPortName());
    switch (inEvent) {
        case kEdsStateEvent_WillSoonShutDown:
            if (camera->mHasOpenSession && camera->mShouldKeepAlive) {
                EdsError error = EdsSendCommand(camera->mCamera, kEdsCameraCommand_ExtendShutDownTimer, 0);
                if (error != EDS_ERR_OK) {
                    console() << "ERROR - failed to extend shut down timer" << std::endl;
                }
            }
            break;
        case kEdsStateEvent_Shutdown:
            camera->requestCloseSession();
            // send handler and browser removal notices
            if (camera->mRemovedHandler) {
                camera->mRemovedHandler(camera);
            }
            CameraBrowser::instance()->removeCamera(camera);
            break;
        default:
            break;
    }
    return EDS_ERR_OK;
}

}}
<commit_msg>clarify crash on release comment<commit_after>//
//  Camera.cpp
//  Cinder-EDSDK
//
//  Created by Jean-Pierre Mouilleseaux on 08 Dec 2013.
//  Copyright 2013-2014 Chorded Constructions. All rights reserved.
//

#include "Camera.h"
#include "CameraBrowser.h"

using namespace ci;
using namespace ci::app;

namespace Cinder { namespace EDSDK {

#pragma mark CAMERA FILE

CameraFileRef CameraFile::create(EdsDirectoryItemRef directoryItem) {
    return CameraFileRef(new CameraFile(directoryItem))->shared_from_this();
}

CameraFile::CameraFile(EdsDirectoryItemRef directoryItem) {
    if (!directoryItem) {
        throw Exception();
    }

    EdsRetain(directoryItem);
    mDirectoryItem = directoryItem;

    EdsError error = EdsGetDirectoryItemInfo(mDirectoryItem, &mDirectoryItemInfo);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get directory item info" << std::endl;
        throw Exception();
    }
}

CameraFile::~CameraFile() {
    EdsRelease(mDirectoryItem);
    mDirectoryItem = NULL;
}

std::string CameraFile::getName() const {
    return std::string(mDirectoryItemInfo.szFileName);
}

uint32_t CameraFile::getSize() const {
    return mDirectoryItemInfo.size;
}

#pragma mark - CAMERA

CameraRef Camera::create(EdsCameraRef camera) {
    return CameraRef(new Camera(camera))->shared_from_this();
}

Camera::Camera(EdsCameraRef camera) {
    if (!camera) {
        throw Exception();
    }

    EdsRetain(camera);
    mCamera = camera;

    EdsError error = EdsGetDeviceInfo(mCamera, &mDeviceInfo);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get device info" << std::endl;
        // TODO - NULL out mDeviceInfo
    }

    mHasOpenSession = false;

    // set event handlers
    error = EdsSetObjectEventHandler(mCamera, kEdsObjectEvent_All, Camera::handleObjectEvent, this);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set object event handler" << std::endl;
    }
    error = EdsSetPropertyEventHandler(mCamera, kEdsPropertyEvent_All, Camera::handlePropertyEvent, this);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set property event handler" << std::endl;
    }
    error = EdsSetCameraStateEventHandler(mCamera, kEdsStateEvent_All, Camera::handleStateEvent, this);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set object event handler" << std::endl;
    }
}

Camera::~Camera() {
    mRemovedHandler = NULL;
    mFileAddedHandler = NULL;

    if (mHasOpenSession) {
        requestCloseSession();
    }

    // NB - starting with EDSDK 2.10, this release will cause an EXC_BAD_ACCESS (code=EXC_I386_GPFLT) at the end of the runloop
//    EdsRelease(mCamera);
    mCamera = NULL;
}

#pragma mark -

void Camera::connectRemovedHandler(const std::function<void(CameraRef)>& handler) {
    mRemovedHandler = handler;
}

void Camera::connectFileAddedHandler(const std::function<void(CameraRef, CameraFileRef)>& handler) {
    mFileAddedHandler = handler;
}

std::string Camera::getName() const {
    return std::string(mDeviceInfo.szDeviceDescription);
}

std::string Camera::getPortName() const {
    return std::string(mDeviceInfo.szPortName);
}

bool Camera::hasOpenSession() const {
    return mHasOpenSession;
}

EdsError Camera::requestOpenSession(const Settings &settings) {
    if (mHasOpenSession) {
        return EDS_ERR_SESSION_ALREADY_OPEN;
    }

    EdsError error = EdsOpenSession(mCamera);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to open camera session" << std::endl;
        return error;
    }
    mHasOpenSession = true;

    mShouldKeepAlive = settings.getShouldKeepAlive();
    EdsUInt32 saveTo = settings.getPictureSaveLocation();
    error = EdsSetPropertyData(mCamera, kEdsPropID_SaveTo, 0, sizeof(saveTo) , &saveTo);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to set save destination host/device" << std::endl;
        return error;
    }

    if (saveTo == kEdsSaveTo_Host) {
        // ??? - requires UI lock?
        EdsCapacity capacity = {0x7FFFFFFF, 0x1000, 1};
        error = EdsSetCapacity(mCamera, capacity);
        if (error != EDS_ERR_OK) {
            console() << "ERROR - failed to set capacity of host" << std::endl;
            return error;
        }
    }

    return EDS_ERR_OK;
}

EdsError Camera::requestCloseSession() {
    if (!mHasOpenSession) {
        return EDS_ERR_SESSION_NOT_OPEN;
    }

    EdsError error = EdsCloseSession(mCamera);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to close camera session" << std::endl;
        return error;
    }

    mHasOpenSession = false;
    return EDS_ERR_OK;
}

EdsError Camera::requestTakePicture() {
    if (!mHasOpenSession) {
        return EDS_ERR_SESSION_NOT_OPEN;
    }

    EdsError error = EdsSendCommand(mCamera, kEdsCameraCommand_TakePicture, 0);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to take picture" << std::endl;
    }
    return error;
}

void Camera::requestDownloadFile(const CameraFileRef file, const fs::path destinationFolderPath, std::function<void(EdsError error, ci::fs::path outputFilePath)> callback) {
    // check if destination exists and create if not
    if (!fs::exists(destinationFolderPath)) {
        bool status = fs::create_directories(destinationFolderPath);
        if (!status) {
            console() << "ERROR - failed to create destination folder path '" << destinationFolderPath << "'" << std::endl;
            return callback(EDS_ERR_INTERNAL_ERROR, NULL);
        }
    }

    fs::path filePath = destinationFolderPath / file->getName();

    EdsStreamRef stream = NULL;
    EdsError error = EdsCreateFileStream(filePath.generic_string().c_str(), kEdsFileCreateDisposition_CreateAlways, kEdsAccess_ReadWrite, &stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to create file stream" << std::endl;
        goto download_cleanup;
    }

    error = EdsDownload(file->mDirectoryItem, file->getSize(), stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to download" << std::endl;
        goto download_cleanup;
    }

    error = EdsDownloadComplete(file->mDirectoryItem);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to mark download as complete" << std::endl;
        goto download_cleanup;
    }

download_cleanup:
    if (stream) {
        EdsRelease(stream);
    }

    callback(error, filePath);
}

void Camera::requestReadFile(const CameraFileRef file, std::function<void(EdsError error, ci::Surface8u surface)> callback) {
    Buffer buffer = NULL;
    ci::Surface surface;

    EdsStreamRef stream = NULL;
    EdsError error = EdsCreateMemoryStream(0, &stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to create memory stream" << std::endl;
        goto read_cleanup;
    }

    error = EdsDownload(file->mDirectoryItem, file->getSize(), stream);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to download" << std::endl;
        goto read_cleanup;
    }

    error = EdsDownloadComplete(file->mDirectoryItem);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to mark download as complete" << std::endl;
        goto read_cleanup;
    }

    void* data;
    error = EdsGetPointer(stream, (EdsVoid**)&data);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get pointer from stream" << std::endl;
        goto read_cleanup;
    }

    EdsUInt32 length;
    error = EdsGetLength(stream, &length);
    if (error != EDS_ERR_OK) {
        console() << "ERROR - failed to get stream length" << std::endl;
        goto read_cleanup;
    }

    buffer = Buffer(data, length);
    surface = Surface8u(loadImage(DataSourceBuffer::create(buffer), ImageSource::Options(), "jpg"));

read_cleanup:
    if (stream) {
        EdsRelease(stream);
    }

    callback(error, surface);
}

#pragma mark - CALLBACKS

EdsError EDSCALLBACK Camera::handleObjectEvent(EdsUInt32 inEvent, EdsBaseRef inRef, EdsVoid* inContext) {
    Camera* c = (Camera*)inContext;
    CameraRef camera = CameraBrowser::instance()->cameraForPortName(c->getPortName());
    switch (inEvent) {
        case kEdsObjectEvent_DirItemRequestTransfer: {
            EdsDirectoryItemRef directoryItem = (EdsDirectoryItemRef)inRef;
            CameraFileRef file = NULL;
            try {
                file = CameraFile::create(directoryItem);
            } catch (...) {
                EdsRelease(directoryItem);
                break;
            }
            EdsRelease(directoryItem);
            directoryItem = NULL;
            if (camera->mFileAddedHandler) {
                camera->mFileAddedHandler(camera, file);
            }
            break;
        }
        default:
            if (inRef) {
                EdsRelease(inRef);
                inRef = NULL;
            }
            break;
    }
    return EDS_ERR_OK;
}

EdsError EDSCALLBACK Camera::handlePropertyEvent(EdsUInt32 inEvent, EdsUInt32 inPropertyID, EdsUInt32 inParam, EdsVoid* inContext) {
    return EDS_ERR_OK;
}

EdsError EDSCALLBACK Camera::handleStateEvent(EdsUInt32 inEvent, EdsUInt32 inParam, EdsVoid* inContext) {
    Camera* c = (Camera*)inContext;
    CameraRef camera = CameraBrowser::instance()->cameraForPortName(c->getPortName());
    switch (inEvent) {
        case kEdsStateEvent_WillSoonShutDown:
            if (camera->mHasOpenSession && camera->mShouldKeepAlive) {
                EdsError error = EdsSendCommand(camera->mCamera, kEdsCameraCommand_ExtendShutDownTimer, 0);
                if (error != EDS_ERR_OK) {
                    console() << "ERROR - failed to extend shut down timer" << std::endl;
                }
            }
            break;
        case kEdsStateEvent_Shutdown:
            camera->requestCloseSession();
            // send handler and browser removal notices
            if (camera->mRemovedHandler) {
                camera->mRemovedHandler(camera);
            }
            CameraBrowser::instance()->removeCamera(camera);
            break;
        default:
            break;
    }
    return EDS_ERR_OK;
}

}}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
// Author: François Faure, INRIA-UJF, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
#include <sofa/component/odesolver/EulerImplicitSolver.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/core/ObjectFactory.h>
#include <math.h>
#include <iostream>
#include "sofa/helper/system/thread/CTime.h"

namespace sofa
{

namespace component
{

namespace odesolver
{

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

EulerImplicitSolver::EulerImplicitSolver()
    : f_rayleighStiffness( initData(&f_rayleighStiffness,0.1,"rayleighStiffness","Rayleigh damping coefficient related to stiffness") )
    , f_rayleighMass( initData(&f_rayleighMass,0.1,"rayleighMass","Rayleigh damping coefficient related to mass"))
    , f_velocityDamping( initData(&f_velocityDamping,0.,"vdamping","Velocity decay coefficient (no decay if null)") )
    , f_verbose( initData(&f_verbose,false,"verbose","Dump system state at each iteration") )
{
}

void EulerImplicitSolver::init()
{
    if (!this->getTags().empty())
    {
        sout << "EulerImplicitSolver: responsible for the following objects with tags " << this->getTags() << " :" << sendl;
        helper::vector<core::objectmodel::BaseObject*> objs;
        this->getContext()->get<core::objectmodel::BaseObject>(&objs,this->getTags(),sofa::core::objectmodel::BaseContext::SearchDown);
        for (unsigned int i=0; i<objs.size(); ++i)
            sout << "  " << objs[i]->getClassName() << ' ' << objs[i]->getName() << sendl;
    }
}

void EulerImplicitSolver::solve(double dt, sofa::core::componentmodel::behavior::BaseMechanicalState::VecId xResult, sofa::core::componentmodel::behavior::BaseMechanicalState::VecId vResult)
{
    MultiVector pos(this, VecId::position());
    MultiVector vel(this, VecId::velocity());
    MultiVector f(this, VecId::force());
    MultiVector b(this, VecId::V_DERIV);
    //MultiVector p(this, VecId::V_DERIV);
    //MultiVector q(this, VecId::V_DERIV);
    //MultiVector q2(this, VecId::V_DERIV);
    //MultiVector r(this, VecId::V_DERIV);
    MultiVector x(this, VecId::V_DERIV);

    double h = dt;
    //const bool printLog = f_printLog.getValue();
    const bool verbose  = f_verbose.getValue();

    //projectResponse(vel);          // initial velocities are projected to the constrained space

    // compute the right-hand term of the equation system
    // accumulation through mappings is disabled as it will be done by addMBKv after all factors are computed
    computeForce(b, true, false);             // b = f0

    // new more powerful visitors
    // b += (h+rs)df/dx v - rd M v
    // values are not cleared so that contributions from computeForces are kept and accumulated through mappings once at the end
    addMBKv(b, (f_rayleighMass.getValue() == 0.0 ? 0.0 : -f_rayleighMass.getValue()), 0, h+f_rayleighStiffness.getValue(), false, true);

    b.teq(h);                           // b = h(f0 + (h+rs)df/dx v - rd M v)

    if( verbose )
        serr<<"EulerImplicitSolver, f0 = "<< b <<sendl;

    projectResponse(b);          // b is projected to the constrained space

    if( verbose )
        serr<<"EulerImplicitSolver, projected f0 = "<< b <<sendl;

    MultiMatrix matrix(this);
    matrix = MechanicalMatrix::K * (-h*(h+f_rayleighStiffness.getValue())) + MechanicalMatrix::M * (1+h*f_rayleighMass.getValue());

    //if( verbose )
//	serr<<"EulerImplicitSolver, matrix = "<< (MechanicalMatrix::K * (-h*(h+f_rayleighStiffness.getValue())) + MechanicalMatrix::M * (1+h*f_rayleighMass.getValue())) << " = " << matrix <<sendl;

    matrix.solve(x, b);
    // projectResponse(x);
    // x is the solution of the system

    // apply the solution

    MultiVector newPos(this, xResult);
    MultiVector newVel(this, vResult);
#ifdef SOFA_NO_VMULTIOP // unoptimized version
    //vel.peq( x );                       // vel = vel + x
    newVel.eq(vel, x);
    //pos.peq( vel, h );                  // pos = pos + h vel
    newPos.eq(pos, newVel, h);

#else // single-operation optimization
    {
        typedef core::componentmodel::behavior::BaseMechanicalState::VMultiOp VMultiOp;
        VMultiOp ops;
        ops.resize(2);
        ops[0].first = (VecId)newVel;
        ops[0].second.push_back(std::make_pair((VecId)vel,1.0));
        ops[0].second.push_back(std::make_pair((VecId)x,1.0));
        ops[1].first = (VecId)newPos;
        ops[1].second.push_back(std::make_pair((VecId)pos,1.0));
        ops[1].second.push_back(std::make_pair((VecId)newVel,h));
        simulation::MechanicalVMultiOpVisitor vmop(ops);
        vmop.setTags(this->getTags());
        vmop.execute(this->getContext());
    }
#endif

    addSeparateGravity(dt, newVel);	// v += dt*g . Used if mass wants to added G separately from the other forces to v.
    if (f_velocityDamping.getValue()!=0.0)
        newVel *= exp(-h*f_velocityDamping.getValue());

    if( verbose )
    {
        serr<<"EulerImplicitSolver, final x = "<< newPos <<sendl;
        serr<<"EulerImplicitSolver, final v = "<< newVel <<sendl;
    }

#ifdef SOFA_HAVE_LAPACK
    applyConstraints();
#endif

}

SOFA_DECL_CLASS(EulerImplicitSolver)

int EulerImplicitSolverClass = core::RegisterObject("Implicit time integrator using backward Euler scheme")
        .add< EulerImplicitSolver >()
        .addAlias("EulerImplicit");
.addAlias("ImplicitEulerSolver");
.addAlias("ImplicitEuler");
;

} // namespace odesolver

} // namespace component

} // namespace sofa

<commit_msg>r4166/sofa-dev : fix compil<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
// Author: François Faure, INRIA-UJF, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
#include <sofa/component/odesolver/EulerImplicitSolver.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/core/ObjectFactory.h>
#include <math.h>
#include <iostream>
#include "sofa/helper/system/thread/CTime.h"

namespace sofa
{

namespace component
{

namespace odesolver
{

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

EulerImplicitSolver::EulerImplicitSolver()
    : f_rayleighStiffness( initData(&f_rayleighStiffness,0.1,"rayleighStiffness","Rayleigh damping coefficient related to stiffness") )
    , f_rayleighMass( initData(&f_rayleighMass,0.1,"rayleighMass","Rayleigh damping coefficient related to mass"))
    , f_velocityDamping( initData(&f_velocityDamping,0.,"vdamping","Velocity decay coefficient (no decay if null)") )
    , f_verbose( initData(&f_verbose,false,"verbose","Dump system state at each iteration") )
{
}

void EulerImplicitSolver::init()
{
    if (!this->getTags().empty())
    {
        sout << "EulerImplicitSolver: responsible for the following objects with tags " << this->getTags() << " :" << sendl;
        helper::vector<core::objectmodel::BaseObject*> objs;
        this->getContext()->get<core::objectmodel::BaseObject>(&objs,this->getTags(),sofa::core::objectmodel::BaseContext::SearchDown);
        for (unsigned int i=0; i<objs.size(); ++i)
            sout << "  " << objs[i]->getClassName() << ' ' << objs[i]->getName() << sendl;
    }
}

void EulerImplicitSolver::solve(double dt, sofa::core::componentmodel::behavior::BaseMechanicalState::VecId xResult, sofa::core::componentmodel::behavior::BaseMechanicalState::VecId vResult)
{
    MultiVector pos(this, VecId::position());
    MultiVector vel(this, VecId::velocity());
    MultiVector f(this, VecId::force());
    MultiVector b(this, VecId::V_DERIV);
    //MultiVector p(this, VecId::V_DERIV);
    //MultiVector q(this, VecId::V_DERIV);
    //MultiVector q2(this, VecId::V_DERIV);
    //MultiVector r(this, VecId::V_DERIV);
    MultiVector x(this, VecId::V_DERIV);

    double h = dt;
    //const bool printLog = f_printLog.getValue();
    const bool verbose  = f_verbose.getValue();

    //projectResponse(vel);          // initial velocities are projected to the constrained space

    // compute the right-hand term of the equation system
    // accumulation through mappings is disabled as it will be done by addMBKv after all factors are computed
    computeForce(b, true, false);             // b = f0

    // new more powerful visitors
    // b += (h+rs)df/dx v - rd M v
    // values are not cleared so that contributions from computeForces are kept and accumulated through mappings once at the end
    addMBKv(b, (f_rayleighMass.getValue() == 0.0 ? 0.0 : -f_rayleighMass.getValue()), 0, h+f_rayleighStiffness.getValue(), false, true);

    b.teq(h);                           // b = h(f0 + (h+rs)df/dx v - rd M v)

    if( verbose )
        serr<<"EulerImplicitSolver, f0 = "<< b <<sendl;

    projectResponse(b);          // b is projected to the constrained space

    if( verbose )
        serr<<"EulerImplicitSolver, projected f0 = "<< b <<sendl;

    MultiMatrix matrix(this);
    matrix = MechanicalMatrix::K * (-h*(h+f_rayleighStiffness.getValue())) + MechanicalMatrix::M * (1+h*f_rayleighMass.getValue());

    //if( verbose )
//	serr<<"EulerImplicitSolver, matrix = "<< (MechanicalMatrix::K * (-h*(h+f_rayleighStiffness.getValue())) + MechanicalMatrix::M * (1+h*f_rayleighMass.getValue())) << " = " << matrix <<sendl;

    matrix.solve(x, b);
    // projectResponse(x);
    // x is the solution of the system

    // apply the solution

    MultiVector newPos(this, xResult);
    MultiVector newVel(this, vResult);
#ifdef SOFA_NO_VMULTIOP // unoptimized version
    //vel.peq( x );                       // vel = vel + x
    newVel.eq(vel, x);
    //pos.peq( vel, h );                  // pos = pos + h vel
    newPos.eq(pos, newVel, h);

#else // single-operation optimization
    {
        typedef core::componentmodel::behavior::BaseMechanicalState::VMultiOp VMultiOp;
        VMultiOp ops;
        ops.resize(2);
        ops[0].first = (VecId)newVel;
        ops[0].second.push_back(std::make_pair((VecId)vel,1.0));
        ops[0].second.push_back(std::make_pair((VecId)x,1.0));
        ops[1].first = (VecId)newPos;
        ops[1].second.push_back(std::make_pair((VecId)pos,1.0));
        ops[1].second.push_back(std::make_pair((VecId)newVel,h));
        simulation::MechanicalVMultiOpVisitor vmop(ops);
        vmop.setTags(this->getTags());
        vmop.execute(this->getContext());
    }
#endif

    addSeparateGravity(dt, newVel);	// v += dt*g . Used if mass wants to added G separately from the other forces to v.
    if (f_velocityDamping.getValue()!=0.0)
        newVel *= exp(-h*f_velocityDamping.getValue());

    if( verbose )
    {
        serr<<"EulerImplicitSolver, final x = "<< newPos <<sendl;
        serr<<"EulerImplicitSolver, final v = "<< newVel <<sendl;
    }

#ifdef SOFA_HAVE_LAPACK
    applyConstraints();
#endif

}

SOFA_DECL_CLASS(EulerImplicitSolver)

int EulerImplicitSolverClass = core::RegisterObject("Implicit time integrator using backward Euler scheme")
        .add< EulerImplicitSolver >()
        .addAlias("EulerImplicit")
        .addAlias("ImplicitEulerSolver")
        .addAlias("ImplicitEuler")
        ;

} // namespace odesolver

} // namespace component

} // namespace sofa

<|endoftext|>


<commit_before>#include "math/SIMD.h"
#include "GapsRunner.h"

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::List cogaps_cpp(const Rcpp::NumericMatrix &D,
const Rcpp::NumericMatrix &S, unsigned nFactor, unsigned nEquil,
unsigned nEquilCool, unsigned nSample, unsigned nOutputs, unsigned nSnapshots,
float alphaA, float alphaP, float maxGibbmassA, float maxGibbmassP,
unsigned seed, bool messages, bool singleCellRNASeq, char whichMatrixFixed,
const Rcpp::NumericMatrix &FP, unsigned checkpointInterval,
const std::string &cptFile, unsigned pumpThreshold, unsigned nPumpSamples,
unsigned nCores)
{
    // create internal state from parameters and run from there
    GapsRunner runner(D, S, nFactor, nEquil, nEquilCool, nSample,
        nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed,
        messages, singleCellRNASeq, checkpointInterval, cptFile,
        whichMatrixFixed, FP, nCores);
    return runner.run();
}

// TODO add checksum to verify D,S matrices
// [[Rcpp::export]]
Rcpp::List cogapsFromCheckpoint_cpp(const Rcpp::NumericMatrix &D,
const Rcpp::NumericMatrix &S, unsigned nFactor, unsigned nEquil,
unsigned nSample, const std::string &fileName, const std::string &cptFile)
{
    GapsRunner runner(D, S, nFactor, nEquil, nSample, cptFile);
    return runner.run();
}

// used to convert defined macro values into strings
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

// [[Rcpp::export]]
std::string getBuildReport_cpp()
{
#if defined( __clang__ )
    std::string compiler = "Compiled with Clang\n";
#elif defined( __INTEL_COMPILER )
    std::string compiler = "Compiled with Intel ICC/ICPC\n";
#elif defined( __GNUC__ )
    std::string compiler = "Compiled with GCC v" + std::string(STR( __GNUC__ ))
    + "." + std::string(STR( __GNUC_MINOR__ )) + '\n';
#elif defined( _MSC_VER )
    std::string compiler = "Compiled with Microsoft Visual Studio\n";
#endif

#if defined( __GAPS_AVX__ )
    std::string simd = "AVX enabled\n";
#elif defined( __GAPS_SSE__ )
    std::string simd = "SSE enabled\n";
#else
    std::string simd = "SIMD not enabled\n";
#endif

#if defined(_OPENMP)
    std::string openmp = "Compiled with OpenMP\n";
#else
    std::string openmp = "Compiler did not support OpenMP\n";
#endif

    return compiler + simd + openmp;
}
<commit_msg>status message about number of cores<commit_after>#include "math/SIMD.h"
#include "GapsRunner.h"

#include <Rcpp.h>
#include <omp.h>

// [[Rcpp::export]]
Rcpp::List cogaps_cpp(const Rcpp::NumericMatrix &D,
const Rcpp::NumericMatrix &S, unsigned nFactor, unsigned nEquil,
unsigned nEquilCool, unsigned nSample, unsigned nOutputs, unsigned nSnapshots,
float alphaA, float alphaP, float maxGibbmassA, float maxGibbmassP,
unsigned seed, bool messages, bool singleCellRNASeq, char whichMatrixFixed,
const Rcpp::NumericMatrix &FP, unsigned checkpointInterval,
const std::string &cptFile, unsigned pumpThreshold, unsigned nPumpSamples,
unsigned nCores)
{
    unsigned availableCores = omp_get_max_threads();
    Rprintf("Running on %d out of %d available cores\n", nCores, availableCores);

    // create internal state from parameters and run from there
    GapsRunner runner(D, S, nFactor, nEquil, nEquilCool, nSample,
        nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed,
        messages, singleCellRNASeq, checkpointInterval, cptFile,
        whichMatrixFixed, FP, nCores);
    return runner.run();
}

// TODO add checksum to verify D,S matrices
// [[Rcpp::export]]
Rcpp::List cogapsFromCheckpoint_cpp(const Rcpp::NumericMatrix &D,
const Rcpp::NumericMatrix &S, unsigned nFactor, unsigned nEquil,
unsigned nSample, const std::string &fileName, const std::string &cptFile)
{
    GapsRunner runner(D, S, nFactor, nEquil, nSample, cptFile);
    return runner.run();
}

// used to convert defined macro values into strings
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

// [[Rcpp::export]]
std::string getBuildReport_cpp()
{
#if defined( __clang__ )
    std::string compiler = "Compiled with Clang\n";
#elif defined( __INTEL_COMPILER )
    std::string compiler = "Compiled with Intel ICC/ICPC\n";
#elif defined( __GNUC__ )
    std::string compiler = "Compiled with GCC v" + std::string(STR( __GNUC__ ))
    + "." + std::string(STR( __GNUC_MINOR__ )) + '\n';
#elif defined( _MSC_VER )
    std::string compiler = "Compiled with Microsoft Visual Studio\n";
#endif

#if defined( __GAPS_AVX__ )
    std::string simd = "AVX enabled\n";
#elif defined( __GAPS_SSE__ )
    std::string simd = "SSE enabled\n";
#else
    std::string simd = "SIMD not enabled\n";
#endif

#if defined(_OPENMP)
    std::string openmp = "Compiled with OpenMP\n";
#else
    std::string openmp = "Compiler did not support OpenMP\n";
#endif

    return compiler + simd + openmp;
}
<|endoftext|>


<commit_before>/**
 * @file    Config.cpp
 * @ingroup LoggerCpp
 * @brief   Configuration for an Output object
 *
 * Copyright (c) 2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include "Config.h"
#include "Stream.h"

namespace Log
{

// Constructor
Config::Config(const char* apName) :
    mName(apName)
{
}

// Destructor
Config::~Config(void)
{
}

// Get a string value
const std::string& Config::getString(const char* apKey) const
{
    Config::Values::const_iterator iValue = mValues.find(apKey);
    if (mValues.end() == iValue)
    {
        /// @todo use a specific Exception class
        throw std::runtime_error(Stream() << "Config::getString(\"" << apKey << "\") no existing value");
    }
    return iValue->second;
}

} // namespace Log
<commit_msg>Fixed Linux compilation<commit_after>/**
 * @file    Config.cpp
 * @ingroup LoggerCpp
 * @brief   Configuration for an Output object
 *
 * Copyright (c) 2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include "Config.h"
#include "Stream.h"

#include <stdexcept>

namespace Log
{

// Constructor
Config::Config(const char* apName) :
    mName(apName)
{
}

// Destructor
Config::~Config(void)
{
}

// Get a string value
const std::string& Config::getString(const char* apKey) const
{
    Config::Values::const_iterator iValue = mValues.find(apKey);
    if (mValues.end() == iValue)
    {
        /// @todo use a specific Exception class
        throw std::runtime_error(Stream() << "Config::getString(\"" << apKey << "\") no existing value");
    }
    return iValue->second;
}

} // namespace Log
<|endoftext|>


<commit_before>
#include <dronecore/dronecore.h>
#include <iostream>
#include <thread>
#include <chrono>
#include <cstdint>

using std::this_thread::sleep_for;
using std::chrono::milliseconds;
using namespace dronecore;

#define ERROR_CONSOLE_TEXT "\033[31m" //Turn text on console red
#define TELEMETRY_CONSOLE_TEXT "\033[34m" //Turn text on console blue
#define NORMAL_CONSOLE_TEXT "\033[0m"  //Restore normal console colour

int main(int /*argc*/, char ** /*argv*/)
{
    DroneCore dc;

    bool discovered_device = false;

    DroneCore::ConnectionResult connection_result = dc.add_udp_connection();

    if (connection_result != DroneCore::ConnectionResult::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Connection failed: "
                  << DroneCore::connection_result_str(connection_result)
                  << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    std::cout << "Waiting to discover device..." << std::endl;
    dc.register_on_discover([&discovered_device](uint64_t uuid) {
        std::cout << "Discovered device with UUID: " << uuid << std::endl;
        discovered_device = true;
    });

    // We usually receive heartbeats at 1Hz, therefore we should find a device after around 2 seconds.
    std::this_thread::sleep_for(std::chrono::seconds(2));

    if (!discovered_device) {
        std::cout << ERROR_CONSOLE_TEXT << "No device found, exiting." << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // We don't need to specify the UUID if it's only one device anyway.
    // If there were multiple, we could specify it with:
    // dc.device(uint64_t uuid);
    Device &device = dc.device();

    // We want to listen to the altitude of the drone at 1 Hz.
    const Telemetry::Result set_rate_result = dc.device().telemetry().set_rate_position(1.0);
    if (set_rate_result != Telemetry::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Setting rate failed:" << Telemetry::result_str(
                      set_rate_result) << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Set up callback to monitor altitude while the vehicle is in flight
    device.telemetry().position_async([](Telemetry::Position position) {
        std::cout << TELEMETRY_CONSOLE_TEXT // set to blue
                  << "Altitude: " << position.relative_altitude_m << " m"
                  << NORMAL_CONSOLE_TEXT // set to default color again
                  << std::endl;
    });

    // Check if vehicle is ready to arm
    if (device.telemetry().health_all_ok() != true) {
        std::cout << ERROR_CONSOLE_TEXT << "Vehicle not ready to arm" << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Arm vehicle
    std::cout << "Arming..." << std::endl;
    const Action::Result arm_result = device.action().arm();

    if (arm_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Arming failed:" << Action::result_str(
                      arm_result) << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Take off
    std::cout << "Taking off..." << std::endl;
    const Action::Result takeoff_result = device.action().takeoff();
    if (takeoff_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Takeoff failed:" << Action::result_str(
                      takeoff_result) << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(10));

    // Change to FW
    const Action::Result fw_result = device.action().transition_to_fixedwing();

    if (fw_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Transition to fixed wing failed: " << Action::result_str(
                      fw_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(10));

    // Change to VTOL
    const Action::Result mc_result = device.action().transition_to_multicopter();
    if (mc_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Transition to multi copter failed:" << Action::result_str(
                      mc_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //    return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(5));

    // Return to launch
    const Action::Result rtl_result = device.action().return_to_launch();
    if (rtl_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Returning to launch failed:" << Action::result_str(
                      rtl_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //    return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(20));

    // Land
    std::cout << "Landing..." << std::endl;
    const Action::Result land_result = device.action().land();
    if (land_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Land failed:" << Action::result_str(
                      land_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //    return 1;
    }

    // We are relying on auto-disarming but let's keep watching the telemetry for a bit longer.
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Finished..." << std::endl;
    return 0;
}
<commit_msg>example: added some printfs for what is going on<commit_after>
#include <dronecore/dronecore.h>
#include <iostream>
#include <thread>
#include <chrono>
#include <cstdint>

using std::this_thread::sleep_for;
using std::chrono::milliseconds;
using namespace dronecore;

#define ERROR_CONSOLE_TEXT "\033[31m" //Turn text on console red
#define TELEMETRY_CONSOLE_TEXT "\033[34m" //Turn text on console blue
#define NORMAL_CONSOLE_TEXT "\033[0m"  //Restore normal console colour

int main(int /*argc*/, char ** /*argv*/)
{
    DroneCore dc;

    bool discovered_device = false;

    DroneCore::ConnectionResult connection_result = dc.add_udp_connection();

    if (connection_result != DroneCore::ConnectionResult::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Connection failed: "
                  << DroneCore::connection_result_str(connection_result)
                  << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    std::cout << "Waiting to discover device..." << std::endl;
    dc.register_on_discover([&discovered_device](uint64_t uuid) {
        std::cout << "Discovered device with UUID: " << uuid << std::endl;
        discovered_device = true;
    });

    // We usually receive heartbeats at 1Hz, therefore we should find a device after around 2 seconds.
    std::this_thread::sleep_for(std::chrono::seconds(2));

    if (!discovered_device) {
        std::cout << ERROR_CONSOLE_TEXT << "No device found, exiting." << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // We don't need to specify the UUID if it's only one device anyway.
    // If there were multiple, we could specify it with:
    // dc.device(uint64_t uuid);
    Device &device = dc.device();

    // We want to listen to the altitude of the drone at 1 Hz.
    const Telemetry::Result set_rate_result = dc.device().telemetry().set_rate_position(1.0);
    if (set_rate_result != Telemetry::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Setting rate failed:" << Telemetry::result_str(
                      set_rate_result) << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Set up callback to monitor altitude while the vehicle is in flight
    device.telemetry().position_async([](Telemetry::Position position) {
        std::cout << TELEMETRY_CONSOLE_TEXT // set to blue
                  << "Altitude: " << position.relative_altitude_m << " m"
                  << NORMAL_CONSOLE_TEXT // set to default color again
                  << std::endl;
    });

    // Check if vehicle is ready to arm
    if (device.telemetry().health_all_ok() != true) {
        std::cout << ERROR_CONSOLE_TEXT << "Vehicle not ready to arm" << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Arm vehicle
    std::cout << "Arming..." << std::endl;
    const Action::Result arm_result = device.action().arm();

    if (arm_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Arming failed:" << Action::result_str(
                      arm_result) << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Take off
    std::cout << "Taking off..." << std::endl;
    const Action::Result takeoff_result = device.action().takeoff();
    if (takeoff_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Takeoff failed:" << Action::result_str(
                      takeoff_result) << NORMAL_CONSOLE_TEXT << std::endl;
        return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(10));

    std::cout << "Transition to fixedwing..." << std::endl;
    const Action::Result fw_result = device.action().transition_to_fixedwing();

    if (fw_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Transition to fixed wing failed: " << Action::result_str(
                      fw_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(10));

    // Change to VTOL
    std::cout << "Transition back to multicopter..." << std::endl;
    const Action::Result mc_result = device.action().transition_to_multicopter();
    if (mc_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Transition to multi copter failed:" << Action::result_str(
                      mc_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //    return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(5));

    // Return to launch
    std::cout << "Return to launch..." << std::endl;
    const Action::Result rtl_result = device.action().return_to_launch();
    if (rtl_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Returning to launch failed:" << Action::result_str(
                      rtl_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //    return 1;
    }

    // Wait
    std::this_thread::sleep_for(std::chrono::seconds(20));

    // Land
    std::cout << "Landing..." << std::endl;
    const Action::Result land_result = device.action().land();
    if (land_result != Action::Result::SUCCESS) {
        std::cout << ERROR_CONSOLE_TEXT << "Land failed:" << Action::result_str(
                      land_result) << NORMAL_CONSOLE_TEXT << std::endl;
        //    return 1;
    }

    // We are relying on auto-disarming but let's keep watching the telemetry for a bit longer.
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Finished..." << std::endl;
    return 0;
}
<|endoftext|>