<commit_before>#include "common.h"

static uv_async_t g_async;
static int g_watch_count;
static uv_sem_t g_semaphore;
static uv_thread_t g_thread;

static EVENT_TYPE g_type;
static WatcherHandle g_handle;
static std::vector<char> g_new_path;
static std::vector<char> g_old_path;
static Persistent<Function> g_callback;

static void CommonThread(void* handle) {
  WaitForMainThread();
  PlatformThread();
}

#if NODE_VERSION_AT_LEAST(0, 11, 13)
static void MakeCallbackInMainThread(uv_async_t* handle) {
#else
static void MakeCallbackInMainThread(uv_async_t* handle, int status) {
#endif
  Nan::HandleScope scope;

  if (!g_callback.IsEmpty()) {
    Handle<String> type;
    switch (g_type) {
      case EVENT_CHANGE:
        type = Nan::New("change").ToLocalChecked();
        break;
      case EVENT_DELETE:
        type = Nan::New("delete").ToLocalChecked();
        break;
      case EVENT_RENAME:
        type = Nan::New("rename").ToLocalChecked();
        break;
      case EVENT_CHILD_CREATE:
        type = Nan::New("child-create").ToLocalChecked();
        break;
      case EVENT_CHILD_CHANGE:
        type = Nan::New("child-change").ToLocalChecked();
        break;
      case EVENT_CHILD_DELETE:
        type = Nan::New("child-delete").ToLocalChecked();
        break;
      case EVENT_CHILD_RENAME:
        type = Nan::New("child-rename").ToLocalChecked();
        break;
      default:
        type = Nan::New("unknown").ToLocalChecked();
        return;
    }

    Handle<Value> argv[] = {
        type,
        WatcherHandleToV8Value(g_handle),
        Nan::New(g_new_path.data(), g_new_path.size()),
        Nan::New(g_old_path.data(), g_old_path.size()),
    };
    Nan::New(g_callback)->Call(Nan::GetCurrentContext()->Global(), 4, argv);
  }

  WakeupNewThread();
}

static void SetRef(bool value) {
  uv_handle_t* h = reinterpret_cast<uv_handle_t*>(&g_async);
  if (value) {
    uv_ref(h);
  } else {
    uv_unref(h);
  }
}

void CommonInit() {
  uv_sem_init(&g_semaphore, 0);
  uv_async_init(uv_default_loop(), &g_async, MakeCallbackInMainThread);
  // As long as any uv_ref'd uv_async_t handle remains active, the node
  // process will never exit, so we must call uv_unref here (#47).
  SetRef(false);
  g_watch_count = 0;
  uv_thread_create(&g_thread, &CommonThread, NULL);
}

void WaitForMainThread() {
  uv_sem_wait(&g_semaphore);
}

void WakeupNewThread() {
  uv_sem_post(&g_semaphore);
}

void PostEventAndWait(EVENT_TYPE type,
                      WatcherHandle handle,
                      const std::vector<char>& new_path,
                      const std::vector<char>& old_path) {
  // FIXME should not pass args by settings globals.
  g_type = type;
  g_handle = handle;
  g_new_path = new_path;
  g_old_path = old_path;

  uv_async_send(&g_async);
  WaitForMainThread();
}

NAN_METHOD(SetCallback) {
  Nan::HandleScope scope;

  if (!info[0]->IsFunction())
    return Nan::ThrowTypeError("Function required");

  g_callback.Reset( Local<Function>::Cast(info[0]));
  return;
}

NAN_METHOD(Watch) {
  Nan::HandleScope scope;

  if (!info[0]->IsString())
    return Nan::ThrowTypeError("String required");

  Handle<String> path = info[0]->ToString();
  WatcherHandle handle = PlatformWatch(*String::Utf8Value(path));
  if (!PlatformIsHandleValid(handle)) {
    int error_number = PlatformInvalidHandleToErrorNumber(handle);
    v8::Local<v8::Value> err =
      v8::Exception::Error(Nan::New<v8::String>("Unable to watch path").ToLocalChecked());
    v8::Local<v8::Object> err_obj = err.As<v8::Object>();
    if (error_number != 0) {
      err_obj->Set(Nan::New<v8::String>("errno").ToLocalChecked(),
                   Nan::New<v8::Integer>(error_number));
#if NODE_VERSION_AT_LEAST(0, 11, 5)
      // Node 0.11.5 is the first version to contain libuv v0.11.6, which
      // contains https://github.com/libuv/libuv/commit/3ee4d3f183 which changes
      // uv_err_name from taking a struct uv_err_t (whose uv_err_code `code` is
      // a difficult-to-produce uv-specific errno) to just take an int which is
      // a negative errno.
      err_obj->Set(Nan::New<v8::String>("code").ToLocalChecked(),
                   Nan::New<v8::String>(uv_err_name(-error_number))).ToLocalChecked();
#endif
    }
    return Nan::ThrowError(err);
  }

  if (g_watch_count++ == 0)
    SetRef(true);

  info.GetReturnValue().Set(WatcherHandleToV8Value(handle));
}

NAN_METHOD(Unwatch) {
  Nan::HandleScope scope;

  if (!IsV8ValueWatcherHandle(info[0]))
    return Nan::ThrowTypeError("Handle type required");

  PlatformUnwatch(V8ValueToWatcherHandle(info[0]));

  if (--g_watch_count == 0)
    SetRef(false);

  return;
}
<commit_msg>Fix up calls to Set<commit_after>#include "common.h"

static uv_async_t g_async;
static int g_watch_count;
static uv_sem_t g_semaphore;
static uv_thread_t g_thread;

static EVENT_TYPE g_type;
static WatcherHandle g_handle;
static std::vector<char> g_new_path;
static std::vector<char> g_old_path;
static Persistent<Function> g_callback;

static void CommonThread(void* handle) {
  WaitForMainThread();
  PlatformThread();
}

#if NODE_VERSION_AT_LEAST(0, 11, 13)
static void MakeCallbackInMainThread(uv_async_t* handle) {
#else
static void MakeCallbackInMainThread(uv_async_t* handle, int status) {
#endif
  Nan::HandleScope scope;

  if (!g_callback.IsEmpty()) {
    Handle<String> type;
    switch (g_type) {
      case EVENT_CHANGE:
        type = Nan::New("change").ToLocalChecked();
        break;
      case EVENT_DELETE:
        type = Nan::New("delete").ToLocalChecked();
        break;
      case EVENT_RENAME:
        type = Nan::New("rename").ToLocalChecked();
        break;
      case EVENT_CHILD_CREATE:
        type = Nan::New("child-create").ToLocalChecked();
        break;
      case EVENT_CHILD_CHANGE:
        type = Nan::New("child-change").ToLocalChecked();
        break;
      case EVENT_CHILD_DELETE:
        type = Nan::New("child-delete").ToLocalChecked();
        break;
      case EVENT_CHILD_RENAME:
        type = Nan::New("child-rename").ToLocalChecked();
        break;
      default:
        type = Nan::New("unknown").ToLocalChecked();
        return;
    }

    Handle<Value> argv[] = {
        type,
        WatcherHandleToV8Value(g_handle),
        Nan::New(g_new_path.data(), g_new_path.size()).ToLocalChecked(),
        Nan::New(g_old_path.data(), g_old_path.size()).ToLocalChecked(),
    };
    Nan::New(g_callback)->Call(Nan::GetCurrentContext()->Global(), 4, argv);
  }

  WakeupNewThread();
}

static void SetRef(bool value) {
  uv_handle_t* h = reinterpret_cast<uv_handle_t*>(&g_async);
  if (value) {
    uv_ref(h);
  } else {
    uv_unref(h);
  }
}

void CommonInit() {
  uv_sem_init(&g_semaphore, 0);
  uv_async_init(uv_default_loop(), &g_async, MakeCallbackInMainThread);
  // As long as any uv_ref'd uv_async_t handle remains active, the node
  // process will never exit, so we must call uv_unref here (#47).
  SetRef(false);
  g_watch_count = 0;
  uv_thread_create(&g_thread, &CommonThread, NULL);
}

void WaitForMainThread() {
  uv_sem_wait(&g_semaphore);
}

void WakeupNewThread() {
  uv_sem_post(&g_semaphore);
}

void PostEventAndWait(EVENT_TYPE type,
                      WatcherHandle handle,
                      const std::vector<char>& new_path,
                      const std::vector<char>& old_path) {
  // FIXME should not pass args by settings globals.
  g_type = type;
  g_handle = handle;
  g_new_path = new_path;
  g_old_path = old_path;

  uv_async_send(&g_async);
  WaitForMainThread();
}

NAN_METHOD(SetCallback) {
  Nan::HandleScope scope;

  if (!info[0]->IsFunction())
    return Nan::ThrowTypeError("Function required");

  g_callback.Reset( Local<Function>::Cast(info[0]));
  return;
}

NAN_METHOD(Watch) {
  Nan::HandleScope scope;

  if (!info[0]->IsString())
    return Nan::ThrowTypeError("String required");

  Handle<String> path = info[0]->ToString();
  WatcherHandle handle = PlatformWatch(*String::Utf8Value(path));
  if (!PlatformIsHandleValid(handle)) {
    int error_number = PlatformInvalidHandleToErrorNumber(handle);
    v8::Local<v8::Value> err =
      v8::Exception::Error(Nan::New<v8::String>("Unable to watch path").ToLocalChecked());
    v8::Local<v8::Object> err_obj = err.As<v8::Object>();
    if (error_number != 0) {
      err_obj->Set(Nan::New<v8::String>("errno").ToLocalChecked(),
                   Nan::New<v8::Integer>(error_number));
#if NODE_VERSION_AT_LEAST(0, 11, 5)
      // Node 0.11.5 is the first version to contain libuv v0.11.6, which
      // contains https://github.com/libuv/libuv/commit/3ee4d3f183 which changes
      // uv_err_name from taking a struct uv_err_t (whose uv_err_code `code` is
      // a difficult-to-produce uv-specific errno) to just take an int which is
      // a negative errno.
      err_obj->Set(Nan::New<v8::String>("code").ToLocalChecked(),
                   Nan::New<v8::String>(uv_err_name(-error_number)).ToLocalChecked());
#endif
    }
    return Nan::ThrowError(err);
  }

  if (g_watch_count++ == 0)
    SetRef(true);

  info.GetReturnValue().Set(WatcherHandleToV8Value(handle));
}

NAN_METHOD(Unwatch) {
  Nan::HandleScope scope;

  if (!IsV8ValueWatcherHandle(info[0]))
    return Nan::ThrowTypeError("Handle type required");

  PlatformUnwatch(V8ValueToWatcherHandle(info[0]));

  if (--g_watch_count == 0)
    SetRef(false);

  return;
}
<|endoftext|>


<commit_before>#include <examples/fastcgi/fastcgi.h>
#include <muduo/base/Logging.h>

struct FastCgiCodec::RecordHeader
{
  uint8_t version;
  uint8_t type;
  uint16_t id;
  uint16_t length;
  uint8_t padding;
  uint8_t unused;
};

const unsigned FastCgiCodec::kRecordHeader = sizeof(FastCgiCodec::RecordHeader);

enum FcgiType
{
  kFcgiInvalid = 0,
  kFcgiBeginRequest = 1,
  kFcgiAbortRequest = 2,
  kFcgiEndRequest = 3,
  kFcgiParams = 4,
  kFcgiStdin = 5,
  kFcgiStdout = 6,
  kFcgiStderr = 7,
  kFcgiData = 8,
  kFcgiGetValues = 9,
  kFcgiGetValuesResult = 10,
};

enum FcgiRole
{
  // kFcgiInvalid = 0,
  kFcgiResponder = 1,
  kFcgiAuthorizer = 2,
};

enum FcgiConstant
{
  kFcgiKeepConn = 1,
};

using namespace muduo::net;

bool FastCgiCodec::onParams(const char* content, uint16_t length)
{
  if (length > 0)
  {
    paramsStream_.append(content, length);
  }
  else if (!parseAllParams())
  {
    LOG_ERROR << "parseAllParams() failed";
    return false;
  }
  return true;
}

void FastCgiCodec::onStdin(const char* content, uint16_t length)
{
  if (length > 0)
  {
    stdin_.append(content, length);
  }
  else
  {
    gotRequest_ = true;
  }
}

bool FastCgiCodec::parseAllParams()
{
  while (paramsStream_.readableBytes() > 0)
  {
    uint32_t nameLen = readLen();
    if (nameLen == static_cast<uint32_t>(-1))
      return false;
    uint32_t valueLen = readLen();
    if (valueLen == static_cast<uint32_t>(-1))
      return false;
    if (paramsStream_.readableBytes() >= nameLen+valueLen)
    {
      string name = paramsStream_.retrieveAsString(nameLen);
      params_[name] = paramsStream_.retrieveAsString(valueLen);
    }
    else
    {
      return false;
    }
  }
  return true;
}

uint32_t FastCgiCodec::readLen()
{
  if (paramsStream_.readableBytes() >= 1)
  {
    uint8_t byte = paramsStream_.peekInt8();
    if (byte & 0x80)
    {
      if (paramsStream_.readableBytes() >= sizeof(uint32_t))
      {
        return paramsStream_.readInt32() & 0x7fffffff;
      }
      else
      {
        return -1;
      }
    }
    else
    {
      return paramsStream_.readInt8();
    }
  }
  else
  {
    return -1;
  }
}

using muduo::net::Buffer;

void FastCgiCodec::endStdout(Buffer* buf)
{
  RecordHeader header =
  {
    1,
    kFcgiStdout,
    htons(1),
    0,
    0,
    0,
  };
  buf->append(&header, kRecordHeader);
}

void FastCgiCodec::endRequest(Buffer* buf)
{
  RecordHeader header =
  {
    1,
    kFcgiEndRequest,
    htons(1),
    htons(kRecordHeader),
    0,
    0,
  };
  buf->append(&header, kRecordHeader);
  buf->appendInt32(0);
  buf->appendInt32(0);
}

void FastCgiCodec::respond(Buffer* response)
{
  if (response->readableBytes() < 65536
      && response->prependableBytes() >= kRecordHeader)
  {
    RecordHeader header =
    {
      1,
      kFcgiStdout,
      htons(1),
      htons(static_cast<uint16_t>(response->readableBytes())),
      static_cast<uint8_t>(-response->readableBytes() & 7),
      0,
    };
    response->prepend(&header, kRecordHeader);
    response->append("\0\0\0\0\0\0\0\0", header.padding);
  }
  else
  {
    // FIXME:
  }

  endStdout(response);
  endRequest(response);
}

bool FastCgiCodec::parseRequest(Buffer* buf)
{
  while (buf->readableBytes() >= kRecordHeader)
  {
    RecordHeader header;
    memcpy(&header, buf->peek(), kRecordHeader);
    header.id = ntohs(header.id);
    header.length = ntohs(header.length);
    size_t total = kRecordHeader + header.length + header.padding;
    if (buf->readableBytes() >= total)
    {
      switch (header.type)
      {
        case kFcgiBeginRequest:
          onBeginRequest(header, buf);
          // FIXME: check
          break;
        case kFcgiParams:
          onParams(buf->peek() + kRecordHeader, header.length);
          // FIXME: check
          break;
        case kFcgiStdin:
          onStdin(buf->peek() + kRecordHeader, header.length);
          break;
        case kFcgiData:
          // FIXME:
          break;
        case kFcgiGetValues:
          // FIXME:
          break;
        default:
          // FIXME:
          break;
      }
      buf->retrieve(total);
    }
    else
    {
      break;
    }
  }
  return true;
}

uint16_t readInt16(const void* p)
{
  uint16_t be16 = 0;
  ::memcpy(&be16, p, sizeof be16);
  return ntohs(be16);
}

bool FastCgiCodec::onBeginRequest(const RecordHeader& header, const Buffer* buf)
{
  assert(buf->readableBytes() >= header.length);
  assert(header.type == kFcgiBeginRequest);

  if (header.length >= kRecordHeader)
  {
    uint16_t role = readInt16(buf->peek()+kRecordHeader);
    uint8_t flags = buf->peek()[kRecordHeader + sizeof(int16_t)];
    if (role == kFcgiResponder)
    {
      keepConn_ = flags == kFcgiKeepConn;
      return true;
    }
  }
  return false;
}
<commit_msg>fix build on 32-bit.<commit_after>#include <examples/fastcgi/fastcgi.h>
#include <muduo/base/Logging.h>
#include <muduo/net/Endian.h>

struct FastCgiCodec::RecordHeader
{
  uint8_t version;
  uint8_t type;
  uint16_t id;
  uint16_t length;
  uint8_t padding;
  uint8_t unused;
};

const unsigned FastCgiCodec::kRecordHeader = sizeof(FastCgiCodec::RecordHeader);

enum FcgiType
{
  kFcgiInvalid = 0,
  kFcgiBeginRequest = 1,
  kFcgiAbortRequest = 2,
  kFcgiEndRequest = 3,
  kFcgiParams = 4,
  kFcgiStdin = 5,
  kFcgiStdout = 6,
  kFcgiStderr = 7,
  kFcgiData = 8,
  kFcgiGetValues = 9,
  kFcgiGetValuesResult = 10,
};

enum FcgiRole
{
  // kFcgiInvalid = 0,
  kFcgiResponder = 1,
  kFcgiAuthorizer = 2,
};

enum FcgiConstant
{
  kFcgiKeepConn = 1,
};

using namespace muduo::net;

bool FastCgiCodec::onParams(const char* content, uint16_t length)
{
  if (length > 0)
  {
    paramsStream_.append(content, length);
  }
  else if (!parseAllParams())
  {
    LOG_ERROR << "parseAllParams() failed";
    return false;
  }
  return true;
}

void FastCgiCodec::onStdin(const char* content, uint16_t length)
{
  if (length > 0)
  {
    stdin_.append(content, length);
  }
  else
  {
    gotRequest_ = true;
  }
}

bool FastCgiCodec::parseAllParams()
{
  while (paramsStream_.readableBytes() > 0)
  {
    uint32_t nameLen = readLen();
    if (nameLen == static_cast<uint32_t>(-1))
      return false;
    uint32_t valueLen = readLen();
    if (valueLen == static_cast<uint32_t>(-1))
      return false;
    if (paramsStream_.readableBytes() >= nameLen+valueLen)
    {
      string name = paramsStream_.retrieveAsString(nameLen);
      params_[name] = paramsStream_.retrieveAsString(valueLen);
    }
    else
    {
      return false;
    }
  }
  return true;
}

uint32_t FastCgiCodec::readLen()
{
  if (paramsStream_.readableBytes() >= 1)
  {
    uint8_t byte = paramsStream_.peekInt8();
    if (byte & 0x80)
    {
      if (paramsStream_.readableBytes() >= sizeof(uint32_t))
      {
        return paramsStream_.readInt32() & 0x7fffffff;
      }
      else
      {
        return -1;
      }
    }
    else
    {
      return paramsStream_.readInt8();
    }
  }
  else
  {
    return -1;
  }
}

using muduo::net::Buffer;

void FastCgiCodec::endStdout(Buffer* buf)
{
  RecordHeader header =
  {
    1,
    kFcgiStdout,
    sockets::hostToNetwork16(1),
    0,
    0,
    0,
  };
  buf->append(&header, kRecordHeader);
}

void FastCgiCodec::endRequest(Buffer* buf)
{
  RecordHeader header =
  {
    1,
    kFcgiEndRequest,
    sockets::hostToNetwork16(1),
    sockets::hostToNetwork16(kRecordHeader),
    0,
    0,
  };
  buf->append(&header, kRecordHeader);
  buf->appendInt32(0);
  buf->appendInt32(0);
}

void FastCgiCodec::respond(Buffer* response)
{
  if (response->readableBytes() < 65536
      && response->prependableBytes() >= kRecordHeader)
  {
    RecordHeader header =
    {
      1,
      kFcgiStdout,
      sockets::hostToNetwork16(1),
      sockets::hostToNetwork16(static_cast<uint16_t>(response->readableBytes())),
      static_cast<uint8_t>(-response->readableBytes() & 7),
      0,
    };
    response->prepend(&header, kRecordHeader);
    response->append("\0\0\0\0\0\0\0\0", header.padding);
  }
  else
  {
    // FIXME:
  }

  endStdout(response);
  endRequest(response);
}

bool FastCgiCodec::parseRequest(Buffer* buf)
{
  while (buf->readableBytes() >= kRecordHeader)
  {
    RecordHeader header;
    memcpy(&header, buf->peek(), kRecordHeader);
    header.id = sockets::networkToHost16(header.id);
    header.length = sockets::networkToHost16(header.length);
    size_t total = kRecordHeader + header.length + header.padding;
    if (buf->readableBytes() >= total)
    {
      switch (header.type)
      {
        case kFcgiBeginRequest:
          onBeginRequest(header, buf);
          // FIXME: check
          break;
        case kFcgiParams:
          onParams(buf->peek() + kRecordHeader, header.length);
          // FIXME: check
          break;
        case kFcgiStdin:
          onStdin(buf->peek() + kRecordHeader, header.length);
          break;
        case kFcgiData:
          // FIXME:
          break;
        case kFcgiGetValues:
          // FIXME:
          break;
        default:
          // FIXME:
          break;
      }
      buf->retrieve(total);
    }
    else
    {
      break;
    }
  }
  return true;
}

uint16_t readInt16(const void* p)
{
  uint16_t be16 = 0;
  ::memcpy(&be16, p, sizeof be16);
  return sockets::networkToHost16(be16);
}

bool FastCgiCodec::onBeginRequest(const RecordHeader& header, const Buffer* buf)
{
  assert(buf->readableBytes() >= header.length);
  assert(header.type == kFcgiBeginRequest);

  if (header.length >= kRecordHeader)
  {
    uint16_t role = readInt16(buf->peek()+kRecordHeader);
    uint8_t flags = buf->peek()[kRecordHeader + sizeof(int16_t)];
    if (role == kFcgiResponder)
    {
      keepConn_ = flags == kFcgiKeepConn;
      return true;
    }
  }
  return false;
}
<|endoftext|>


<commit_before>#include <iostream>

#include <getopt.h>
#include <stdlib.h>
#include <assert.h>

#include <omp.h>

#include "qtree.h"
#include "util.h"

using namespace std;

bool smallTest = false;

size_t getTid() {
  int tid = omp_get_thread_num();

  assert(tid >= 0);

  return (size_t) tid;
}

size_t getP() {
  int p = omp_get_num_threads();

  assert(p > 0);

  return (size_t) p;
}

void nbody(point_t const* const points, const size_t l, float* u) {
  midlvl_t* mids = new midlvl_t[l];
  size_t* idxs = new size_t[l];

  for (size_t i = 0; i < l; i++)
    mids[i] = toMid(points[i], 1);

  sortByMid(mids, l, idxs);

  size_t p;
  QTree** trees;
  size_t* treeSizes;

  #pragma omp parallel
  {
    size_t tid = getTid();

    if (!tid) {
      p = getP();
      trees = new QTree*[p];
      treeSizes = new size_t[p];
    }
  }

  #pragma omp parallel
  {
    size_t tid = getTid();
    size_t tl = l / p;

    trees[tid] = new QTree(points);
    trees[tid]->insert(&idxs[tl * tid], tl);

    treeSizes[tid] = 0;

    for (QTree::iterator i = trees[tid]->begin(); i != trees[tid]->end(); i++)
      treeSizes[tid]++;
  }

  size_t tl = 0; // tree length (total length of all trees)
  for (size_t i = 0; i < p; i++)
    tl += treeSizes[i];

  midlvl_t* treeMids = new midlvl_t[tl];

  #pragma omp parallel
  {
    size_t tid = getTid();
    size_t myStart = 0;

    for (size_t i = 0; i < tid; i++)
      myStart += treeSizes[i];

    size_t offset = 0;

    for (QTree::iterator i = trees[tid]->begin(); i != trees[tid]->end(); i++)
      treeMids[myStart + ++offset] = i->toMid();
  }

  if (smallTest) {
    for (size_t i = 0; i < p; i++) {
      cout << "==================== thread " << i << " tree" << endl;
      _print_hierarchy(*trees[i]);
    }
  }

  delete[] mids;
  delete[] idxs;
  for (size_t i = 0; i < p; i++)
    delete trees[i];
  delete[] trees;
  delete[] treeSizes;
  delete[] treeMids;
}

int main(int argc, char* argv[]) {
  size_t l = 1 << 10;
  int opt;

  while ((opt = getopt(argc, argv, "n:s")) != -1) {
    switch (opt) {
      case 'n': // problem size
        if (!smallTest)
          l = atoi(optarg);
        break;
      case 's': // just do a small test
        smallTest = true;
        l = 16;
        break;
      default: /* '?' */
        cerr << "USAGE: " << argv[0]
          << " [-n number-of-points]"
          << " [-s]"
          << endl;
        exit(EXIT_FAILURE);
    }
  }

  point_t* points = new point_t[l];
  float* u = new float[l];

  if (smallTest) {
    // same as in test.cpp
    float rawPoints[(1 << 4) * 3] = {0.582333, 0.269646, 0.1, 0.943668,
      0.227026, 0.1, 0.62133, 0.687648, 0.1, 0.307982, 0.259371, 0.1, 0.241987,
      0.0781364, 0.1, 0.238763, 0.881891, 0.1, 0.943446, 0.501017, 0.1,
      0.584999, 0.0834366, 0.1, 0.318576, 0.301914, 0.1, 0.276723, 0.889071,
      0.1, 0.608897, 0.731815, 0.1, 0.610775, 0.297957, 0.1, 0.76092, 0.777598,
      0.1, 0.0899074, 0.0728559, 0.1, 0.48988, 0.405702, 0.1, 0.625613,
      0.675141, 0.1};

    points = (point_t*) rawPoints;

  } else {
    for (size_t i = 0; i < l; i++) {
      points[i].x = ((float) rand()) / ((float) RAND_MAX);
      points[i].y = ((float) rand()) / ((float) RAND_MAX);
      points[i].weight = (float) rand();
    }
  }

  nbody(points, l, u);

  cout << "generating problem of size " << l << endl;

  return 0;
}
<commit_msg>added a fake 'merge and remove dupes' step<commit_after>#include <iostream>

#include <getopt.h>
#include <stdlib.h>
#include <assert.h>

#include <omp.h>

#include "qtree.h"
#include "util.h"

using namespace std;

bool smallTest = false;

size_t getTid() {
  int tid = omp_get_thread_num();

  assert(tid >= 0);

  return (size_t) tid;
}

size_t getP() {
  int p = omp_get_num_threads();

  assert(p > 0);

  return (size_t) p;
}

void nbody(point_t const* const points, const size_t l, float* u) {
  midlvl_t* mids = new midlvl_t[l];
  size_t* idxs = new size_t[l];

  for (size_t i = 0; i < l; i++)
    mids[i] = toMid(points[i], 1);

  sortByMid(mids, l, idxs);

  size_t p;
  QTree** trees;
  size_t* treeSizes;

  #pragma omp parallel
  {
    size_t tid = getTid();

    if (!tid) {
      p = getP();
      trees = new QTree*[p];
      treeSizes = new size_t[p];
    }
  }

  #pragma omp parallel
  {
    size_t tid = getTid();
    size_t tl = l / p;

    trees[tid] = new QTree(points);
    trees[tid]->insert(&idxs[tl * tid], tl);

    treeSizes[tid] = 0;

    for (QTree::iterator i = trees[tid]->begin(); i != trees[tid]->end(); i++)
      treeSizes[tid]++;
  }

  size_t tl = 0; // tree length (total length of all trees)
  for (size_t i = 0; i < p; i++)
    tl += treeSizes[i];

  // we could get rid of the treeMids allocation if we have a function like
  // sortByMid but for QTree pointers
  midlvl_t* treeMids = new midlvl_t[tl];
  QTree** treeNodes = new QTree*[tl];
  size_t* treeIdxs = new size_t[tl];

  #pragma omp parallel
  {
    size_t tid = getTid();
    size_t myStart = 0;

    for (size_t i = 0; i < tid; i++)
      myStart += treeSizes[i];

    size_t offset = 0;

    for (QTree::iterator it = trees[tid]->begin(); it != trees[tid]->end();
        it++) {
      size_t i = myStart + offset++;

      treeMids[i] = it->toMid();
      // get a pointer to the actual QTree instance, not the iterator
      treeNodes[i] = &(*it);
      treeIdxs[i] = i;
    }
  }

  if (smallTest) {
    for (size_t i = 0; i < p; i++) {
      cout << "==================== thread " << i << " tree" << endl;
      _print_hierarchy(*trees[i]);
    }

    cout << endl << "==================== full tree before sorting" << endl;

    for (size_t i = 0; i < tl; i++) {
      cout.width(3);
      cout << i << ": ";
      cout.width(20);
      cout << treeNodes[treeIdxs[i]]->toMid() << " " << *treeNodes[treeIdxs[i]] << endl;
    }

    cout << endl;
  }

  sortByMid(treeMids, tl, treeIdxs);

  if (smallTest) {
    cout << "==================== full tree after sorting" << endl;

    for (size_t i = 0; i < tl; i++) {
      cout.width(3);
      cout << i << ": ";
      cout.width(20);
      cout << treeNodes[treeIdxs[i]]->toMid() << " " << *treeNodes[treeIdxs[i]] << endl;
    }

    cout << endl;
  }

  delete[] mids;
  delete[] idxs;
  for (size_t i = 0; i < p; i++)
    delete trees[i];
  delete[] trees;
  delete[] treeSizes;
  delete[] treeMids;
}

int main(int argc, char* argv[]) {
  size_t l = 1 << 10;
  int opt;

  while ((opt = getopt(argc, argv, "n:s")) != -1) {
    switch (opt) {
      case 'n': // problem size
        if (!smallTest)
          l = atoi(optarg);
        break;
      case 's': // just do a small test
        smallTest = true;
        l = 16;
        break;
      default: /* '?' */
        cerr << "USAGE: " << argv[0]
          << " [-n number-of-points]"
          << " [-s]"
          << endl;
        exit(EXIT_FAILURE);
    }
  }

  point_t* points = new point_t[l];
  float* u = new float[l];

  if (smallTest) {
    // same as in test.cpp
    float rawPoints[(1 << 4) * 3] = {0.582333, 0.269646, 0.1, 0.943668,
      0.227026, 0.1, 0.62133, 0.687648, 0.1, 0.307982, 0.259371, 0.1, 0.241987,
      0.0781364, 0.1, 0.238763, 0.881891, 0.1, 0.943446, 0.501017, 0.1,
      0.584999, 0.0834366, 0.1, 0.318576, 0.301914, 0.1, 0.276723, 0.889071,
      0.1, 0.608897, 0.731815, 0.1, 0.610775, 0.297957, 0.1, 0.76092, 0.777598,
      0.1, 0.0899074, 0.0728559, 0.1, 0.48988, 0.405702, 0.1, 0.625613,
      0.675141, 0.1};

    points = (point_t*) rawPoints;

  } else {
    for (size_t i = 0; i < l; i++) {
      points[i].x = ((float) rand()) / ((float) RAND_MAX);
      points[i].y = ((float) rand()) / ((float) RAND_MAX);
      points[i].weight = (float) rand();
    }
  }

  nbody(points, l, u);

  cout << "generating problem of size " << l << endl;

  return 0;
}
<|endoftext|>


<commit_before>#include "mmapAlignment.h"
#include "mmapGenome.h"

using namespace hal;
using namespace std;

MMapGenome *MMapAlignmentData::addGenome(MMapAlignment *alignment, const std::string &name) {
    size_t newGenomeArraySize = (_numGenomes + 1) * sizeof(MMapGenomeData);
    size_t newGenomeArrayOffset = alignment->allocateNewArray(newGenomeArraySize);
    MMapGenomeData *newGenomeArray = (MMapGenomeData *) alignment->resolveOffset(newGenomeArrayOffset, newGenomeArraySize);
    if (_numGenomes != 0) {
        // Copy over old genome data.
        MMapGenomeData *oldGenomeArray = (MMapGenomeData *) alignment->resolveOffset(_genomeArrayOffset, _numGenomes * sizeof(MMapGenomeData));
        memcpy(newGenomeArray, oldGenomeArray, _numGenomes * sizeof(MMapGenomeData));
    }
    _genomeArrayOffset = newGenomeArrayOffset;
    _numGenomes += 1;
    MMapGenomeData *data = newGenomeArray + _numGenomes;
    MMapGenome *genome = new MMapGenome(alignment, data, name);
    return genome;
}

Genome* MMapAlignment::addLeafGenome(const string& name,
                                     const string& parentName,
                                     double branchLength) {
    stTree *parentNode = getGenomeNode(parentName);
    stTree *childNode = stTree_construct();
    stTree_setLabel(childNode, name.c_str());
    stTree_setParent(childNode, parentNode);
    stTree_setBranchLength(childNode, branchLength);
    writeTree();
    MMapGenome *genome = _data->addGenome(this, name);
    _openGenomes[name] = genome;
    return genome;
}

Genome* MMapAlignment::addRootGenome(const string& name,
                                     double branchLength) {
    if (_tree != NULL) {
        // FIXME
        throw hal_exception("adding a new root when one is already defined is unimplemented");
    } else {
        _tree = stTree_construct();
        stTree_setLabel(_tree, name.c_str());
        stTree_setBranchLength(_tree, branchLength);
        MMapGenome *genome = _data->addGenome(this, name);
        _openGenomes[name] = genome;
        return genome;
    }
}

Genome *MMapAlignment::_openGenome(const string &name) const {
    if (_openGenomes.find(name) != _openGenomes.end()) {
        // Already loaded.
        return _openGenomes[name];
    }
    // TODO go through genome array checking names (slow, but necessary for now)
}
<commit_msg>Allow openGenome() to succeed when not already cached<commit_after>#include "mmapAlignment.h"
#include "mmapGenome.h"

using namespace hal;
using namespace std;

MMapGenome *MMapAlignmentData::addGenome(MMapAlignment *alignment, const std::string &name) {
    size_t newGenomeArraySize = (_numGenomes + 1) * sizeof(MMapGenomeData);
    size_t newGenomeArrayOffset = alignment->allocateNewArray(newGenomeArraySize);
    MMapGenomeData *newGenomeArray = (MMapGenomeData *) alignment->resolveOffset(newGenomeArrayOffset, newGenomeArraySize);
    if (_numGenomes != 0) {
        // Copy over old genome data.
        MMapGenomeData *oldGenomeArray = (MMapGenomeData *) alignment->resolveOffset(_genomeArrayOffset, _numGenomes * sizeof(MMapGenomeData));
        memcpy(newGenomeArray, oldGenomeArray, _numGenomes * sizeof(MMapGenomeData));
    }
    _genomeArrayOffset = newGenomeArrayOffset;
    _numGenomes += 1;
    MMapGenomeData *data = newGenomeArray + _numGenomes;
    MMapGenome *genome = new MMapGenome(alignment, data, name);
    return genome;
}

Genome* MMapAlignment::addLeafGenome(const string& name,
                                     const string& parentName,
                                     double branchLength) {
    stTree *parentNode = getGenomeNode(parentName);
    stTree *childNode = stTree_construct();
    stTree_setLabel(childNode, name.c_str());
    stTree_setParent(childNode, parentNode);
    stTree_setBranchLength(childNode, branchLength);
    writeTree();
    MMapGenome *genome = _data->addGenome(this, name);
    _openGenomes[name] = genome;
    return genome;
}

Genome* MMapAlignment::addRootGenome(const string& name,
                                     double branchLength) {
    if (_tree != NULL) {
        // FIXME
        throw hal_exception("adding a new root when one is already defined is unimplemented");
    } else {
        _tree = stTree_construct();
        stTree_setLabel(_tree, name.c_str());
        stTree_setBranchLength(_tree, branchLength);
        MMapGenome *genome = _data->addGenome(this, name);
        _openGenomes[name] = genome;
        return genome;
    }
}

Genome *MMapAlignment::_openGenome(const string &name) const {
    if (_openGenomes.find(name) != _openGenomes.end()) {
        // Already loaded.
        return _openGenomes[name];
    }
    // Go through the genome array and find the genome we want.
    MMapGenomeData *genomeArray = (MMapGenomeData *) resolveOffset(_data->_genomeArrayOffset, _data->_numGenomes * sizeof(MMapGenomeData));
    MMapGenome *genome = NULL;
    for (size_t i = 0; i < _data->_numGenomes; i++) {
        MMapGenome curGenome(const_cast<MMapAlignment *>(this), genomeArray + i);
        if (curGenome.getName() == name) {
            genome = new MMapGenome(const_cast<MMapAlignment *>(this), genomeArray + i);
            break;
        }
    }
    if (genome == NULL) {
        throw hal_exception("Genome " + name + "not found in alignment");
    }
    _openGenomes[name] = genome;
    return genome;
}
<|endoftext|>


<commit_before>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *  Copyright (C) 2018  David Shah <david@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "pcf.h"
#include <sstream>
#include "log.h"

NEXTPNR_NAMESPACE_BEGIN

// Read a w

// Apply PCF constraints to a pre-packing design
bool apply_pcf(Context *ctx, std::istream &in)
{
    try {
        if (!in)
            log_error("failed to open PCF file");
        std::string line;
        while (std::getline(in, line)) {
            size_t cstart = line.find("#");
            if (cstart != std::string::npos)
                line = line.substr(0, cstart);
            std::stringstream ss(line);
            std::vector<std::string> words;
            std::string tmp;
            while (ss >> tmp)
                words.push_back(tmp);
            if (words.size() == 0)
                continue;
            std::string cmd = words.at(0);
            if (cmd == "set_io") {
                size_t args_end = 1;
                while (args_end < words.size() && words.at(args_end).at(0) == '-')
                    args_end++;
                std::string cell = words.at(args_end);
                std::string pin = words.at(args_end + 1);
                auto fnd_cell = ctx->cells.find(ctx->id(cell));
                if (fnd_cell == ctx->cells.end()) {
                    log_warning("unmatched pcf constraint %s\n", cell.c_str());
                } else {
                    BelId pin_bel = ctx->getPackagePinBel(pin);
                    if (pin_bel == BelId())
                        log_error("package does not have a pin named %s\n", pin.c_str());
                    fnd_cell->second->attrs[ctx->id("BEL")] = ctx->getBelName(pin_bel).str(ctx);
                    log_info("constrained '%s' to bel '%s'\n", cell.c_str(),
                             fnd_cell->second->attrs[ctx->id("BEL")].c_str());
                }
            } else {
                log_error("unsupported pcf command '%s'\n", cmd.c_str());
            }
        }
        return true;
    } catch (log_execution_error_exception) {
        return false;
    }
}

NEXTPNR_NAMESPACE_END
<commit_msg>Fix message for pcf loading<commit_after>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *  Copyright (C) 2018  David Shah <david@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "pcf.h"
#include <sstream>
#include "log.h"

NEXTPNR_NAMESPACE_BEGIN

// Read a w

// Apply PCF constraints to a pre-packing design
bool apply_pcf(Context *ctx, std::istream &in)
{
    try {
        if (!in)
            log_error("failed to open PCF file\n");
        std::string line;
        while (std::getline(in, line)) {
            size_t cstart = line.find("#");
            if (cstart != std::string::npos)
                line = line.substr(0, cstart);
            std::stringstream ss(line);
            std::vector<std::string> words;
            std::string tmp;
            while (ss >> tmp)
                words.push_back(tmp);
            if (words.size() == 0)
                continue;
            std::string cmd = words.at(0);
            if (cmd == "set_io") {
                size_t args_end = 1;
                while (args_end < words.size() && words.at(args_end).at(0) == '-')
                    args_end++;
                std::string cell = words.at(args_end);
                std::string pin = words.at(args_end + 1);
                auto fnd_cell = ctx->cells.find(ctx->id(cell));
                if (fnd_cell == ctx->cells.end()) {
                    log_warning("unmatched pcf constraint %s\n", cell.c_str());
                } else {
                    BelId pin_bel = ctx->getPackagePinBel(pin);
                    if (pin_bel == BelId())
                        log_error("package does not have a pin named %s\n", pin.c_str());
                    fnd_cell->second->attrs[ctx->id("BEL")] = ctx->getBelName(pin_bel).str(ctx);
                    log_info("constrained '%s' to bel '%s'\n", cell.c_str(),
                             fnd_cell->second->attrs[ctx->id("BEL")].c_str());
                }
            } else {
                log_error("unsupported pcf command '%s'\n", cmd.c_str());
            }
        }
        return true;
    } catch (log_execution_error_exception) {
        return false;
    }
}

NEXTPNR_NAMESPACE_END
<|endoftext|>


<commit_before>#include <stinkee_device.h>
#include <stinkee_signal.h>

#include <portaudio.h>

#include <cassert>
#include <iostream>

namespace {

static const int            NUM_CHANNELS = 1;
static const PaSampleFormat SAMPLE_TYPE  = paFloat32;

struct CbUserData
{
    std::size_t            processed;
    const stinkee::Signal& signal;
};

int paCallback(const void                     *input,
               void                           *output,
               unsigned long                   frameCount,
               const PaStreamCallbackTimeInfo *timeInfo,
               PaStreamCallbackFlags           statusFlags,
               void                           *userData);

}  // anonymous namespace

namespace stinkee {

Device::~Device()
{
    Pa_Terminate();
}

int Device::init() const
{
    PaError rc = Pa_Initialize();
    if (rc != paNoError) {
        std::cerr << "Failed to initialize portaudio: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
    }

    return rc;
}

int Device::process(const Signal& signal) const
{
    PaError rc;
    CbUserData userData = { 0, signal };

    PaStreamParameters outputParams;
    outputParams.device = Pa_GetDefaultOutputDevice();
    if (outputParams.device == paNoDevice) {
        std::cerr << "No audio output device available" << std::endl;
        return paNoDevice;
    }

    const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(outputParams.device);
    outputParams.channelCount = NUM_CHANNELS;
    outputParams.sampleFormat = SAMPLE_TYPE;
    outputParams.suggestedLatency = deviceInfo->defaultLowOutputLatency;
    outputParams.hostApiSpecificStreamInfo = NULL;

    PaStream *audioStream;
    rc = Pa_OpenStream(
            &audioStream,
            NULL,
            &outputParams,
            Signal::SAMPLING_RATE,
            paFramesPerBufferUnspecified,
            paClipOff | paDitherOff,
            paCallback,
            &userData);

    if (rc != paNoError) {
        std::cerr << "Failed to open output stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    rc = Pa_StartStream(audioStream);
    if (rc != paNoError) {
        std::cerr << "Failed to start stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    Pa_Sleep(1000);

    rc = Pa_StopStream(audioStream);
    if (rc != paNoError) {
        std::cerr << "Failed to stop stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    rc = Pa_CloseStream(audioStream);
    if (rc != paNoError) {
        std::cerr << "Failed to close stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    assert(userData.processed == signal.frames().size());

    return 0;
}

}  // library namespace

namespace {

int paCallback(const void                     *input,
               void                           *output,
               unsigned long                   frameCount,
               const PaStreamCallbackTimeInfo *timeInfo,
               PaStreamCallbackFlags           statusFlags,
               void                           *userData)
{
    CbUserData *data = (CbUserData *)userData;
    const std::vector<float>& frames = data->signal.frames();
    float *out = (float *)output;

    for (std::size_t i = 0; i < frameCount; ++i) {
        if (data->processed < frames.size()) {
            *out = frames[data->processed++];
        }
        else {
            *out = 0.0;
        }
        ++out;
    }

    return data->processed < frames.size() ? paContinue : paComplete;
}

}  // anonymous namespace
<commit_msg>Copy signal data to audio stream with 'memcpy'<commit_after>#include <stinkee_device.h>
#include <stinkee_signal.h>

#include <portaudio.h>

#include <cassert>
#include <cstring>
#include <iostream>

namespace {

static const int            NUM_CHANNELS = 1;
static const PaSampleFormat SAMPLE_TYPE  = paFloat32;

struct CbUserData
{
    std::size_t            processed;
    const stinkee::Signal& signal;
};

int paCallback(const void                     *input,
               void                           *output,
               unsigned long                   frameCount,
               const PaStreamCallbackTimeInfo *timeInfo,
               PaStreamCallbackFlags           statusFlags,
               void                           *userData);

}  // anonymous namespace

namespace stinkee {

Device::~Device()
{
    Pa_Terminate();
}

int Device::init() const
{
    PaError rc = Pa_Initialize();
    if (rc != paNoError) {
        std::cerr << "Failed to initialize portaudio: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
    }

    return rc;
}

int Device::process(const Signal& signal) const
{
    PaError rc;
    CbUserData userData = { 0, signal };

    PaStreamParameters outputParams;
    outputParams.device = Pa_GetDefaultOutputDevice();
    if (outputParams.device == paNoDevice) {
        std::cerr << "No audio output device available" << std::endl;
        return paNoDevice;
    }

    const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(outputParams.device);
    outputParams.channelCount = NUM_CHANNELS;
    outputParams.sampleFormat = SAMPLE_TYPE;
    outputParams.suggestedLatency = deviceInfo->defaultLowOutputLatency;
    outputParams.hostApiSpecificStreamInfo = NULL;

    PaStream *audioStream;
    rc = Pa_OpenStream(
            &audioStream,
            NULL,
            &outputParams,
            Signal::SAMPLING_RATE,
            paFramesPerBufferUnspecified,
            paClipOff | paDitherOff,
            paCallback,
            &userData);

    if (rc != paNoError) {
        std::cerr << "Failed to open output stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    rc = Pa_StartStream(audioStream);
    if (rc != paNoError) {
        std::cerr << "Failed to start stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    Pa_Sleep(1000);

    rc = Pa_StopStream(audioStream);
    if (rc != paNoError) {
        std::cerr << "Failed to stop stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    rc = Pa_CloseStream(audioStream);
    if (rc != paNoError) {
        std::cerr << "Failed to close stream: "
                  << Pa_GetErrorText(rc)
                  << std::endl;
        return rc;
    }

    assert(userData.processed == signal.frames().size());

    return 0;
}

}  // library namespace

namespace {

int paCallback(const void                     *input,
               void                           *output,
               unsigned long                   frameCount,
               const PaStreamCallbackTimeInfo *timeInfo,
               PaStreamCallbackFlags           statusFlags,
               void                           *userData)
{
    CbUserData *data = (CbUserData *)userData;
    const std::vector<float>& frames = data->signal.frames();
    float *out = (float *)output;

    // Caller may request more frames than there is left in the signal buffer
    // once the end is reached
    std::size_t framesCopied = std::min(frameCount,
                                        frames.size() - data->processed);

    std::memcpy(out,
                &frames[data->processed],
                framesCopied * sizeof (float));

    // At the end of the signal, fill the rest of the buffer with silence
    std::memset(out + framesCopied,
                0,
                (frameCount - framesCopied) * sizeof (float));

    data->processed += framesCopied;
    return data->processed < frames.size() ? paContinue : paComplete;
}

}  // anonymous namespace
<|endoftext|>


<commit_before>
#include "catch.hpp"
#include <stdint.h>

#include "xorshift.hpp"

namespace {
    /*  Written in 2014-2015 by Sebastiano Vigna (vigna@acm.org)

    To the extent possible under law, the author has dedicated all copyright
    and related and neighboring rights to this software to the public domain
    worldwide. This software is distributed without any warranty.

    See <http://creativecommons.org/publicdomain/zero/1.0/>. */

    /* This is the fastest generator passing BigCrush without
       systematic failures, but due to the relatively short period it is
       acceptable only for applications with a mild amount of parallelism;
       otherwise, use a xorshift1024* generator.

       The state must be seeded so that it is not everywhere zero. If you have
       a 64-bit seed, we suggest to seed a splitmix64 generator and use its
       output to fill s. */

    uint64_t s[2];

    uint64_t next(void) {
    	uint64_t s1 = s[0];
    	const uint64_t s0 = s[1];
    	s[0] = s0;
    	s1 ^= s1 << 23; // a
    	s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
    	return s[1] + s0;
    }

    /* This is the jump function for the generator. It is equivalent
       to 2^64 calls to next(); it can be used to generate 2^64
       non-overlapping subsequences for parallel computations. */

    void jump() {
    	static const uint64_t JUMP[] = { 0x8a5cd789635d2dff, 0x121fd2155c472f96 };

    	uint64_t s0 = 0;
    	uint64_t s1 = 0;
    	for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
    		for(int b = 0; b < 64; b++) {
    			if (JUMP[i] & 1ULL << b) {
    				s0 ^= s[0];
    				s1 ^= s[1];
    			}
    			next();
    		}

    	s[0] = s0;
    	s[1] = s1;
    }
}

TEST_CASE ("Test lockfree-xorshift128") {
    SECTION ("Value should be equal to the reference implementation") {
        s [0] = 0 ;
        s [1] = 1 ;
        alignas (16) XorShift::state_t state { 0, 1 } ;

        for (int_fast32_t i = 0 ; i < 10000 ; ++i) {
            auto expected = next () ;
            auto actual = XorShift::next (state) ;
            CAPTURE (i) ;
            REQUIRE (expected == actual) ;
        }
    }

    SECTION ("Value should be equal after jump was called") {
        s [0] = 0 ;
        s [1] = 1 ;

        jump () ;
        alignas (16) XorShift::state_t state { 0, 1 } ;

        XorShift::jump (state) ;
        for (int_fast32_t i = 0 ; i < 10000 ; ++i) {
            auto expected = next () ;
            auto actual = XorShift::next (state) ;
            REQUIRE (expected == actual) ;
        }
    }

}
<commit_msg>chore: Add a test tag<commit_after>
#include "catch.hpp"
#include <stdint.h>

#include "xorshift.hpp"

namespace {
    /*  Written in 2014-2015 by Sebastiano Vigna (vigna@acm.org)

    To the extent possible under law, the author has dedicated all copyright
    and related and neighboring rights to this software to the public domain
    worldwide. This software is distributed without any warranty.

    See <http://creativecommons.org/publicdomain/zero/1.0/>. */

    /* This is the fastest generator passing BigCrush without
       systematic failures, but due to the relatively short period it is
       acceptable only for applications with a mild amount of parallelism;
       otherwise, use a xorshift1024* generator.

       The state must be seeded so that it is not everywhere zero. If you have
       a 64-bit seed, we suggest to seed a splitmix64 generator and use its
       output to fill s. */

    uint64_t s[2];

    uint64_t next(void) {
    	uint64_t s1 = s[0];
    	const uint64_t s0 = s[1];
    	s[0] = s0;
    	s1 ^= s1 << 23; // a
    	s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
    	return s[1] + s0;
    }

    /* This is the jump function for the generator. It is equivalent
       to 2^64 calls to next(); it can be used to generate 2^64
       non-overlapping subsequences for parallel computations. */

    void jump() {
    	static const uint64_t JUMP[] = { 0x8a5cd789635d2dff, 0x121fd2155c472f96 };

    	uint64_t s0 = 0;
    	uint64_t s1 = 0;
    	for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
    		for(int b = 0; b < 64; b++) {
    			if (JUMP[i] & 1ULL << b) {
    				s0 ^= s[0];
    				s1 ^= s[1];
    			}
    			next();
    		}

    	s[0] = s0;
    	s[1] = s1;
    }
}

TEST_CASE ("Test lockfree-xorshift128", "[xorshift]") {
    SECTION ("Value should be equal to the reference implementation") {
        s [0] = 0 ;
        s [1] = 1 ;
        alignas (16) XorShift::state_t state { 0, 1 } ;

        for (int_fast32_t i = 0 ; i < 10000 ; ++i) {
            auto expected = next () ;
            auto actual = XorShift::next (state) ;
            CAPTURE (i) ;
            REQUIRE (expected == actual) ;
        }
    }

    SECTION ("Value should be equal after jump was called") {
        s [0] = 0 ;
        s [1] = 1 ;

        jump () ;
        alignas (16) XorShift::state_t state { 0, 1 } ;

        XorShift::jump (state) ;
        for (int_fast32_t i = 0 ; i < 10000 ; ++i) {
            auto expected = next () ;
            auto actual = XorShift::next (state) ;
            REQUIRE (expected == actual) ;
        }
    }

}
<|endoftext|>


<commit_before>///
/// @file  BitSieve-popcnt.cpp
/// @brief Count the number of 1 bits inside a 64-bit array.
///        The vectorized popcount algorithms used in this file are
///        described in the paper "Faster Population Counts using AVX2
///        Instructions" by Wojciech Muła, Nathan Kurz, Daniel Lemire.
/// @see   https://arxiv.org/abs/1611.07612
/// @see   https://github.com/WojciechMula/sse-popcount
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <BitSieve.hpp>
#include <popcnt.hpp>

#include <stdint.h>
#include <cassert>
#include <vector>

namespace {
namespace DEFAULT {

void CSA(uint64_t& h, uint64_t& l, uint64_t a, uint64_t b, uint64_t c)
{
  uint64_t u = a ^ b;
  h = (a & b) | (u & c);
  l = u ^ c;
}

/// Harley-Seal popcount (4th iteration).
/// The Harley-Seal popcount algorithm is one of the fastest algorithms
/// for counting 1 bits in an array using only integer operations.
/// This implementation uses only 5.69 instructions per 64-bit word.
/// @see Chapter 5 in "Hacker's Delight" 2nd edition.
///
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  uint64_t total = 0;
  uint64_t ones = 0, twos = 0, fours = 0, eights = 0, sixteens = 0;
  uint64_t twosA, twosB, foursA, foursB, eightsA, eightsB;
  uint64_t limit = size - size % 16;
  uint64_t i = 0;

  for(; i < limit; i += 16)
  {
    CSA(twosA, ones, ones, data[i+0], data[i+1]);
    CSA(twosB, ones, ones, data[i+2], data[i+3]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+4], data[i+5]);
    CSA(twosB, ones, ones, data[i+6], data[i+7]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsA,fours, fours, foursA, foursB);
    CSA(twosA, ones, ones, data[i+8], data[i+9]);
    CSA(twosB, ones, ones, data[i+10], data[i+11]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+12], data[i+13]);
    CSA(twosB, ones, ones, data[i+14], data[i+15]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsB, fours, fours, foursA, foursB);
    CSA(sixteens, eights, eights, eightsA, eightsB);

    total += popcnt64(sixteens);
  }

  total *= 16;
  total += 8 * popcnt64(eights);
  total += 4 * popcnt64(fours);
  total += 2 * popcnt64(twos);
  total += 1 * popcnt64(ones);

  for(; i < size; i++)
    total += popcnt64(data[i]);

  return total;
}

} // namespace DEFAULT
} // namespace

namespace {
namespace POPCNT {

/// Count the number of 1 bits inside the data
/// array using the POPCNT instruction.
///
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  uint64_t sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
  uint64_t limit = size - size % 4;
  uint64_t i = 0;

  for (; i < limit; i += 4)
  {
    sum0 += popcnt64(data[i+0]);
    sum1 += popcnt64(data[i+1]);
    sum2 += popcnt64(data[i+2]);
    sum3 += popcnt64(data[i+3]);
  }

  uint64_t total = sum0 + sum1 + sum2 + sum3;

  for (; i < size; i++)
    total += popcnt64(data[i]);

  return total;
}

} // namespace POPCNT
} // namespace

#if defined(__x86_64__) && \
    defined(__GNUC__) && \
           (__GNUC__ > 4 || \
           (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))

#include <immintrin.h>

namespace {
namespace AVX2 {

__m256i popcnt(const __m256i v)
{
  __m256i m1 = _mm256_set1_epi8(0x55);
  __m256i m2 = _mm256_set1_epi8(0x33);
  __m256i m4 = _mm256_set1_epi8(0x0F);

  __m256i t1 = _mm256_sub_epi8(v, (_mm256_srli_epi16(v,  1) & m1));
  __m256i t2 = _mm256_add_epi8(t1 & m2, (_mm256_srli_epi16(t1, 2) & m2));
  __m256i t3 = _mm256_add_epi8(t2, _mm256_srli_epi16(t2, 4)) & m4;

  return _mm256_sad_epu8(t3, _mm256_setzero_si256());
}

void CSA(__m256i& h, __m256i& l, __m256i a, __m256i b, __m256i c)
{
  __m256i u = a ^ b;
  h = (a & b) | (u & c);
  l = u ^ c;
}

/// AVX2 Harley-Seal popcount (4th iteration).
/// The algorithm is based on the paper "Faster Population Counts
/// using AVX2 Instructions" by Daniel Lemire, Nathan Kurz and
/// Wojciech Mula (23 Nov 2016).
/// @see https://arxiv.org/abs/1611.07612
///
uint64_t popcnt(const __m256i* data, uint64_t size)
{
  __m256i total = _mm256_setzero_si256();
  __m256i ones = _mm256_setzero_si256();
  __m256i twos = _mm256_setzero_si256();
  __m256i fours = _mm256_setzero_si256();
  __m256i eights = _mm256_setzero_si256();
  __m256i sixteens = _mm256_setzero_si256();
  __m256i twosA, twosB, foursA, foursB, eightsA, eightsB;

  uint64_t limit = size - size % 16;
  uint64_t i = 0;

  for(; i < limit; i += 16)
  {
    CSA(twosA, ones, ones, data[i+0], data[i+1]);
    CSA(twosB, ones, ones, data[i+2], data[i+3]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+4], data[i+5]);
    CSA(twosB, ones, ones, data[i+6], data[i+7]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsA,fours, fours, foursA, foursB);
    CSA(twosA, ones, ones, data[i+8], data[i+9]);
    CSA(twosB, ones, ones, data[i+10], data[i+11]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+12], data[i+13]);
    CSA(twosB, ones, ones, data[i+14], data[i+15]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsB, fours, fours, foursA, foursB);
    CSA(sixteens, eights, eights, eightsA, eightsB);

    total = _mm256_add_epi64(total, popcnt(sixteens));
  }

  total = _mm256_slli_epi64(total, 4);
  total = _mm256_add_epi64(total, _mm256_slli_epi64(popcnt(eights), 3));
  total = _mm256_add_epi64(total, _mm256_slli_epi64(popcnt(fours), 2));
  total = _mm256_add_epi64(total, _mm256_slli_epi64(popcnt(twos), 1));
  total = _mm256_add_epi64(total, popcnt(ones));

  for(; i < size; i++)
    total = _mm256_add_epi64(total, popcnt(data[i]));

  uint64_t* total64 = (uint64_t*) &total;

  return total64[0] +
         total64[1] +
         total64[2] +
         total64[3];
}

/// Align memory to 32 bytes boundary
void align(const uint64_t*& data, uint64_t* size, uint64_t* total)
{
  for (; *size > 0 && (uintptr_t) data % 32 != 0; data++)
  {
    *total += popcnt64(*data);
    *size -= 1;
  }
}

/// AVX2 popcount algorithm for 64-bit arrays.
/// @param data  A 64-bit array
/// @param size  Length of data array
///
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  uint64_t total = 0;

  // AVX2 popcount is faster than POPCNT
  // for array sizes >= 1 kilobyte
  if (size * 8 >= 1024)
  {
    align(data, &size, &total);
    total += popcnt((const __m256i*) data, size / 4);
    data += size - size % 4;
    size = size % 4;
  }

  // process remaining words
  total += POPCNT::popcnt(data, size);

  return total;
}

} // namespace AVX2
} // namespace

#endif /* AVX2 */

/// Function multi-versioning is currently (February 2017)
/// only supported by GCC >= 4.8
///
#if defined(__x86_64__) && \
    defined(__GNUC__) && \
           (__GNUC__ > 4 || \
           (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))

namespace {

__attribute__ ((target ("default")))
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return DEFAULT::popcnt(data, size);
}

__attribute__ ((target ("popcnt")))
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return POPCNT::popcnt(data, size);
}

__attribute__ ((target ("avx2")))
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return AVX2::popcnt(data, size);
}

} // namespace

#else

uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return POPCNT::popcnt(data, size);
}

#endif

namespace primecount {

/// Count the number of 1 bits inside [start, stop]
uint64_t BitSieve::count(uint64_t start,
                         uint64_t stop) const
{
  if (start > stop)
    return 0;

  assert(stop < size_);

  uint64_t start_idx = start / 64;
  uint64_t stop_idx = stop / 64;
  uint64_t m1 = 0xffffffffffffffffull << (start % 64);
  uint64_t m2 = 0xffffffffffffffffull >> (63 - stop % 64);
  uint64_t bit_count;

  if (start_idx == stop_idx)
    bit_count = popcnt64(sieve_[start_idx] & (m1 & m2));
  else
  {
    bit_count = popcnt64(sieve_[start_idx] & m1);
    bit_count += popcnt(&sieve_[start_idx + 1], stop_idx - (start_idx + 1));
    bit_count += popcnt64(sieve_[stop_idx] & m2);
  }

  return bit_count;
}

} // namespace

<commit_msg>Update comment<commit_after>///
/// @file  BitSieve-popcnt.cpp
/// @brief Count the number of 1 bits inside a 64-bit array.
///        The AVX2 popcount algorithm used in this file is described
///        in the paper "Faster Population Counts using AVX2
///        Instructions" by Wojciech Muła, Nathan Kurz, Daniel Lemire.
/// @see   https://arxiv.org/abs/1611.07612
/// @see   https://github.com/WojciechMula/sse-popcount
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <BitSieve.hpp>
#include <popcnt.hpp>

#include <stdint.h>
#include <cassert>
#include <vector>

namespace {
namespace DEFAULT {

void CSA(uint64_t& h, uint64_t& l, uint64_t a, uint64_t b, uint64_t c)
{
  uint64_t u = a ^ b;
  h = (a & b) | (u & c);
  l = u ^ c;
}

/// Harley-Seal popcount (4th iteration).
/// The Harley-Seal popcount algorithm is one of the fastest algorithms
/// for counting 1 bits in an array using only integer operations.
/// This implementation uses only 5.69 instructions per 64-bit word.
/// @see Chapter 5 in "Hacker's Delight" 2nd edition.
///
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  uint64_t total = 0;
  uint64_t ones = 0, twos = 0, fours = 0, eights = 0, sixteens = 0;
  uint64_t twosA, twosB, foursA, foursB, eightsA, eightsB;
  uint64_t limit = size - size % 16;
  uint64_t i = 0;

  for(; i < limit; i += 16)
  {
    CSA(twosA, ones, ones, data[i+0], data[i+1]);
    CSA(twosB, ones, ones, data[i+2], data[i+3]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+4], data[i+5]);
    CSA(twosB, ones, ones, data[i+6], data[i+7]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsA,fours, fours, foursA, foursB);
    CSA(twosA, ones, ones, data[i+8], data[i+9]);
    CSA(twosB, ones, ones, data[i+10], data[i+11]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+12], data[i+13]);
    CSA(twosB, ones, ones, data[i+14], data[i+15]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsB, fours, fours, foursA, foursB);
    CSA(sixteens, eights, eights, eightsA, eightsB);

    total += popcnt64(sixteens);
  }

  total *= 16;
  total += 8 * popcnt64(eights);
  total += 4 * popcnt64(fours);
  total += 2 * popcnt64(twos);
  total += 1 * popcnt64(ones);

  for(; i < size; i++)
    total += popcnt64(data[i]);

  return total;
}

} // namespace DEFAULT
} // namespace

namespace {
namespace POPCNT {

/// Count the number of 1 bits inside the data
/// array using the POPCNT instruction.
///
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  uint64_t sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
  uint64_t limit = size - size % 4;
  uint64_t i = 0;

  for (; i < limit; i += 4)
  {
    sum0 += popcnt64(data[i+0]);
    sum1 += popcnt64(data[i+1]);
    sum2 += popcnt64(data[i+2]);
    sum3 += popcnt64(data[i+3]);
  }

  uint64_t total = sum0 + sum1 + sum2 + sum3;

  for (; i < size; i++)
    total += popcnt64(data[i]);

  return total;
}

} // namespace POPCNT
} // namespace

#if defined(__x86_64__) && \
    defined(__GNUC__) && \
           (__GNUC__ > 4 || \
           (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))

#include <immintrin.h>

namespace {
namespace AVX2 {

__m256i popcnt(const __m256i v)
{
  __m256i m1 = _mm256_set1_epi8(0x55);
  __m256i m2 = _mm256_set1_epi8(0x33);
  __m256i m4 = _mm256_set1_epi8(0x0F);

  __m256i t1 = _mm256_sub_epi8(v, (_mm256_srli_epi16(v,  1) & m1));
  __m256i t2 = _mm256_add_epi8(t1 & m2, (_mm256_srli_epi16(t1, 2) & m2));
  __m256i t3 = _mm256_add_epi8(t2, _mm256_srli_epi16(t2, 4)) & m4;

  return _mm256_sad_epu8(t3, _mm256_setzero_si256());
}

void CSA(__m256i& h, __m256i& l, __m256i a, __m256i b, __m256i c)
{
  __m256i u = a ^ b;
  h = (a & b) | (u & c);
  l = u ^ c;
}

/// AVX2 Harley-Seal popcount (4th iteration).
/// The algorithm is based on the paper "Faster Population Counts
/// using AVX2 Instructions" by Daniel Lemire, Nathan Kurz and
/// Wojciech Mula (23 Nov 2016).
/// @see https://arxiv.org/abs/1611.07612
///
uint64_t popcnt(const __m256i* data, uint64_t size)
{
  __m256i total = _mm256_setzero_si256();
  __m256i ones = _mm256_setzero_si256();
  __m256i twos = _mm256_setzero_si256();
  __m256i fours = _mm256_setzero_si256();
  __m256i eights = _mm256_setzero_si256();
  __m256i sixteens = _mm256_setzero_si256();
  __m256i twosA, twosB, foursA, foursB, eightsA, eightsB;

  uint64_t limit = size - size % 16;
  uint64_t i = 0;

  for(; i < limit; i += 16)
  {
    CSA(twosA, ones, ones, data[i+0], data[i+1]);
    CSA(twosB, ones, ones, data[i+2], data[i+3]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+4], data[i+5]);
    CSA(twosB, ones, ones, data[i+6], data[i+7]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsA,fours, fours, foursA, foursB);
    CSA(twosA, ones, ones, data[i+8], data[i+9]);
    CSA(twosB, ones, ones, data[i+10], data[i+11]);
    CSA(foursA, twos, twos, twosA, twosB);
    CSA(twosA, ones, ones, data[i+12], data[i+13]);
    CSA(twosB, ones, ones, data[i+14], data[i+15]);
    CSA(foursB, twos, twos, twosA, twosB);
    CSA(eightsB, fours, fours, foursA, foursB);
    CSA(sixteens, eights, eights, eightsA, eightsB);

    total = _mm256_add_epi64(total, popcnt(sixteens));
  }

  total = _mm256_slli_epi64(total, 4);
  total = _mm256_add_epi64(total, _mm256_slli_epi64(popcnt(eights), 3));
  total = _mm256_add_epi64(total, _mm256_slli_epi64(popcnt(fours), 2));
  total = _mm256_add_epi64(total, _mm256_slli_epi64(popcnt(twos), 1));
  total = _mm256_add_epi64(total, popcnt(ones));

  for(; i < size; i++)
    total = _mm256_add_epi64(total, popcnt(data[i]));

  uint64_t* total64 = (uint64_t*) &total;

  return total64[0] +
         total64[1] +
         total64[2] +
         total64[3];
}

/// Align memory to 32 bytes boundary
void align(const uint64_t*& data, uint64_t* size, uint64_t* total)
{
  for (; *size > 0 && (uintptr_t) data % 32 != 0; data++)
  {
    *total += popcnt64(*data);
    *size -= 1;
  }
}

/// AVX2 popcount algorithm for 64-bit arrays.
/// @param data  A 64-bit array
/// @param size  Length of data array
///
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  uint64_t total = 0;

  // AVX2 popcount is faster than POPCNT
  // for array sizes >= 1 kilobyte
  if (size * 8 >= 1024)
  {
    align(data, &size, &total);
    total += popcnt((const __m256i*) data, size / 4);
    data += size - size % 4;
    size = size % 4;
  }

  // process remaining words
  total += POPCNT::popcnt(data, size);

  return total;
}

} // namespace AVX2
} // namespace

#endif /* AVX2 */

/// Function multi-versioning is currently (February 2017)
/// only supported by GCC >= 4.8
///
#if defined(__x86_64__) && \
    defined(__GNUC__) && \
           (__GNUC__ > 4 || \
           (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))

namespace {

__attribute__ ((target ("default")))
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return DEFAULT::popcnt(data, size);
}

__attribute__ ((target ("popcnt")))
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return POPCNT::popcnt(data, size);
}

__attribute__ ((target ("avx2")))
uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return AVX2::popcnt(data, size);
}

} // namespace

#else

uint64_t popcnt(const uint64_t* data, uint64_t size)
{
  return POPCNT::popcnt(data, size);
}

#endif

namespace primecount {

/// Count the number of 1 bits inside [start, stop]
uint64_t BitSieve::count(uint64_t start,
                         uint64_t stop) const
{
  if (start > stop)
    return 0;

  assert(stop < size_);

  uint64_t start_idx = start / 64;
  uint64_t stop_idx = stop / 64;
  uint64_t m1 = 0xffffffffffffffffull << (start % 64);
  uint64_t m2 = 0xffffffffffffffffull >> (63 - stop % 64);
  uint64_t bit_count;

  if (start_idx == stop_idx)
    bit_count = popcnt64(sieve_[start_idx] & (m1 & m2));
  else
  {
    bit_count = popcnt64(sieve_[start_idx] & m1);
    bit_count += popcnt(&sieve_[start_idx + 1], stop_idx - (start_idx + 1));
    bit_count += popcnt64(sieve_[stop_idx] & m2);
  }

  return bit_count;
}

} // namespace

<|endoftext|>


<commit_before>#include "WPILib.h"
#include "RobotStrap.h"
#include "constants.h"

/**
 *  Constructor
 */
RobotStrap::RobotStrap() :
	// Initialize all the member objects in the same order
	// declared within the body.
	myRobot(LEFT_MOTOR_PORT, RIGHT_MOTOR_PORT),
	stick(JOYSTICK_PORT)
{
	myRobot.SetExpiration(0.1);
}

/**
 * Prints robot status to the console
 */
void RobotStrap::printStatus( void )
{
	// Get an instance of the driver station to use its API
	DriverStation* ds = DriverStation::GetInstance();

	// Get important variable data
	float voltage = ds -> GetBatteryVoltage();

	// Print the data
	printf("=======STATUS=======\n");
	printf("Battery Voltage: %f\n", voltage);
}

/**
 * Runs during test mode
 */
void RobotStrap::Test( void )
{

}

/**
 * Drive left & right motors for 2 seconds then stop
 */
void RobotStrap::Autonomous( void )
{
	myRobot.SetSafetyEnabled(false);
	myRobot.Drive(-0.5, 0.0); 	// drive forwards half speed
	Wait(2.0); 				//    for 2 seconds
	myRobot.Drive(0.0, 0.0); 	// stop robot
}

/**
 * Runs the motors with arcade steering.
 */
void RobotStrap::OperatorControl( void )
{
	// Set the safety
	myRobot.SetSafetyEnabled(true);

	// Establish arm
	Jaguar* arm = new Jaguar(ARM_MOTOR_PORT);

	// Infinite loop
	while (IsOperatorControl())
	{
		// Print status if the button is pressed
		if(stick.GetRawButton(11))
			this -> printStatus();

		// Move the arm based on buttons
		bool launchValue = stick.GetRawButton(1);
		bool rewindValue = stick.GetRawButton(2);

		// Determine the speed to throw the arm at
		float speed = (stick.getThrottle() - (-1)) / 2;

		if(launchValue)
			// make arm launch forwards
			arm -> Set(1 * speed);
		else if(rewindValue)
			// make the arm launch backwards
			arm -> Set(-1 * speed);
		else
			arm -> Set(0);

		myRobot.ArcadeDrive(stick); // drive with arcade style (use right stick)
		Wait(0.005); // wait for a motor update time
	}
}

START_ROBOT_CLASS(RobotStrap);

<commit_msg>Update RobotStrap.cpp<commit_after>#include "WPILib.h"
#include "RobotStrap.h"
#include "constants.h"

/**
 *  Constructor
 */
RobotStrap::RobotStrap() :
	// Initialize all the member objects in the same order
	// declared within the body.
	myRobot(LEFT_MOTOR_PORT, RIGHT_MOTOR_PORT),
	stick(JOYSTICK_PORT)
{
	myRobot.SetExpiration(0.1);
}

/**
 * Prints robot status to the console
 */
void RobotStrap::printStatus( void )
{
	// Get an instance of the driver station to use its API
	DriverStation* ds = DriverStation::GetInstance();

	// Get important variable data
	float voltage = ds -> GetBatteryVoltage();

	// Print the data
	printf("=======STATUS=======\n");
	printf("Battery Voltage: %f\n", voltage);
}

/**
 * Runs during test mode
 */
void RobotStrap::Test( void )
{

}

/**
 * Drive left & right motors for 2 seconds then stop
 */
void RobotStrap::Autonomous( void )
{
	myRobot.SetSafetyEnabled(false);
	myRobot.Drive(-0.5, 0.0); // drive forwards half speed
	Wait(2.0); // for 2 seconds
	myRobot.Drive(0.0, 0.0); // stop robot
}

/**
 * Runs the motors with arcade steering.
 */
void RobotStrap::OperatorControl( void )
{
	// Set the safety
	myRobot.SetSafetyEnabled(true);

	// Establish arm
	Jaguar* arm = new Jaguar(ARM_MOTOR_PORT);

	// Infinite loop
	while (IsOperatorControl())
	{
		// Fill compressor when tank is low

		// Print status if the button is pressed
		if(stick.GetRawButton(11))
			this -> printStatus();

		// Move the arm based on buttons
		bool launchValue = stick.GetRawButton(1);
		bool rewindValue = stick.GetRawButton(2);

		// Determine the speed to throw the arm at
		float speed = (stick.GetThrottle() - (-1)) / 2;

		if(launchValue)
			// make arm launch forwards
			arm -> Set(1 * speed);
		else if(rewindValue)
			// make the arm launch backwards
			arm -> Set(-1 * speed);
		else
			arm -> Set(0);

		myRobot.ArcadeDrive(stick); // drive with arcade style (use right stick)
		Wait(0.005); // wait for a motor update time
	}
}

START_ROBOT_CLASS(RobotStrap);

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/corecache/p10_hcd_core_shadows_disable.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file  p10_hcd_core_shadows_disable.C
/// @brief
///

// *HWP HWP Owner          : David Du         <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still       <stillgs@us.ibm.com>
// *HWP FW Owner           : Prem Shanker Jha <premjha2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : SBE:QME
// *HWP Level              : 2

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------

#include "p10_hcd_core_shadows_disable.H"
#include "p10_hcd_common.H"

#ifdef __PPE_QME
    #include "p10_ppe_c.H"
    using namespace scomt::ppe_c;
#else
    #include "p10_scom_c.H"
    using namespace scomt::c;
#endif

//------------------------------------------------------------------------------
// Constant Definitions
//------------------------------------------------------------------------------

enum P10_HCD_CORE_SHADOWS_DISABLE_CONSTANTS
{
    HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS   = 100000, // 10^5ns = 100us timeout
    HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_HW_NS     = 1000,   // 1us poll loop delay
    HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_SIM_CYCLE = 32000,  // 32k sim cycle delay
    HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS   = 100000, // 10^5ns = 100us timeout
    HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_HW_NS     = 1000,   // 1us poll loop delay
    HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_SIM_CYCLE = 32000,  // 32k sim cycle delay
};

//------------------------------------------------------------------------------
// Procedure: p10_hcd_core_shadows_disable
//------------------------------------------------------------------------------

fapi2::ReturnCode
p10_hcd_core_shadows_disable(
    const fapi2::Target < fapi2::TARGET_TYPE_CORE | fapi2::TARGET_TYPE_MULTICAST, fapi2::MULTICAST_AND > & i_target)
{
    fapi2::buffer<buffer_t> l_mmioData = 0;
    uint32_t                l_timeout  = 0;
    uint32_t                l_shadow_states = 0;

    FAPI_INF(">>p10_hcd_core_shadows_disable");

    FAPI_DBG("Disable CORE_SHADOW and CORE_SAMPLE via CUCR[0, 1]");
    FAPI_TRY( HCD_PUTMMIO_C( i_target, CPMS_CUCR_WO_CLEAR, MMIO_LOAD32H(BITS32(0, 2)) ) );

    FAPI_DBG("Wait for FTC/PP/DPT_SHADOW_STATE to be Idle via CUCR[33-35,40-41,45-46]");
    l_timeout = HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS /
                HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_HW_NS;

    do
    {
        FAPI_TRY( HCD_GETMMIO_C( i_target, MMIO_LOWADDR(CPMS_CUCR), l_mmioData ) );

        // use multicastAND to check 0
        MMIO_GET32L(l_shadow_states);

        if( !( l_shadow_states & ( BITS64SH(33, 3) | BITS64SH(40, 2) | BITS64SH(45, 2) ) ) )
        {
            break;
        }

        fapi2::delay(HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_HW_NS,
                     HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_SIM_CYCLE);
    }
    while( (--l_timeout) != 0 );

    FAPI_ASSERT((l_timeout != 0),
                fapi2::SHADOW_DIS_CORE_SHADOW_STATE_TIMEOUT()
                .set_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS(HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS)
                .set_CPMS_CUCR(l_mmioData)
                .set_CORE_TARGET(i_target),
                "Shadow Disable FTC/PP/DPT Shadow State Timeout");

    FAPI_DBG("Wait on XFER_RECEIVE_DONE via PCR_TFCSR[32]");
    l_timeout = HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS /
                HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_HW_NS;

    do
    {
        FAPI_TRY( HCD_GETMMIO_C( i_target, MMIO_LOWADDR(QME_TFCSR), l_mmioData ) );

        // use multicastAND to check 1
        if( MMIO_GET(MMIO_LOWBIT(32)) == 1 )
        {
            break;
        }

        fapi2::delay(HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_HW_NS,
                     HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_SIM_CYCLE);
    }
    while( (--l_timeout) != 0 );

    FAPI_ASSERT((l_timeout != 0),
                fapi2::SHADOW_DIS_XFER_RECEIVE_DONE_TIMEOUT()
                .set_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS(HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS)
                .set_QME_TFCSR(l_mmioData)
                .set_CORE_TARGET(i_target),
                "Shadow Disable Xfer Receive Done Timeout");

    FAPI_DBG("Drop XFER_RECEIVE_DONE via PCR_TFCSR[32]");
    FAPI_TRY( HCD_GETMMIO_C( i_target, MMIO_LOWADDR(QME_TFCSR_WO_CLEAR), MMIO_1BIT( MMIO_LOWBIT(32) ) ) );

    FAPI_DBG("Assert CTFS_WKUP_ENABLE via PCR_SCSR[27]");
    FAPI_TRY( HCD_PUTMMIO_C( i_target, QME_SCSR_WO_OR, MMIO_1BIT(27) ) );

fapi_try_exit:

    FAPI_INF("<<p10_hcd_core_shadows_disable");

    return fapi2::current_err;

}
<commit_msg>STOP/QME/FAPI: Tracking EPM/VBU HW Sim Changes<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/corecache/p10_hcd_core_shadows_disable.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file  p10_hcd_core_shadows_disable.C
/// @brief
///

// *HWP HWP Owner          : David Du         <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still       <stillgs@us.ibm.com>
// *HWP FW Owner           : Prem Shanker Jha <premjha2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : SBE:QME
// *HWP Level              : 2

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------

#include "p10_hcd_core_shadows_disable.H"
#include "p10_hcd_common.H"

#ifdef __PPE_QME
    #include "p10_ppe_c.H"
    using namespace scomt::ppe_c;
#else
    #include "p10_scom_c.H"
    using namespace scomt::c;
#endif

//------------------------------------------------------------------------------
// Constant Definitions
//------------------------------------------------------------------------------

enum P10_HCD_CORE_SHADOWS_DISABLE_CONSTANTS
{
    HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS   = 100000, // 10^5ns = 100us timeout
    HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_HW_NS     = 1000,   // 1us poll loop delay
    HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_SIM_CYCLE = 32000,  // 32k sim cycle delay
    HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS   = 100000, // 10^5ns = 100us timeout
    HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_HW_NS     = 1000,   // 1us poll loop delay
    HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_SIM_CYCLE = 32000,  // 32k sim cycle delay
};

//------------------------------------------------------------------------------
// Procedure: p10_hcd_core_shadows_disable
//------------------------------------------------------------------------------

fapi2::ReturnCode
p10_hcd_core_shadows_disable(
    const fapi2::Target < fapi2::TARGET_TYPE_CORE | fapi2::TARGET_TYPE_MULTICAST, fapi2::MULTICAST_AND > & i_target)
{
    fapi2::buffer<buffer_t> l_mmioData = 0;
    uint32_t                l_timeout  = 0;
    uint32_t                l_shadow_states = 0;

    FAPI_INF(">>p10_hcd_core_shadows_disable");

    FAPI_DBG("Disable CORE_SHADOW and CORE_SAMPLE via CUCR[0, 1]");
    FAPI_TRY( HCD_PUTMMIO_C( i_target, CPMS_CUCR_WO_CLEAR, MMIO_LOAD32H(BITS32(0, 2)) ) );

    FAPI_DBG("Wait for FTC/PP/DPT_SHADOW_STATE to be Idle via CUCR[33-35,40-41,45-46]");
    l_timeout = HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS /
                HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_HW_NS;

    do
    {
        FAPI_TRY( HCD_GETMMIO_C( i_target, MMIO_LOWADDR(CPMS_CUCR), l_mmioData ) );

        // use multicastAND to check 0
        MMIO_GET32L(l_shadow_states);

        if( !( l_shadow_states & ( BITS64SH(33, 3) | BITS64SH(40, 2) | BITS64SH(45, 2) ) ) )
        {
            break;
        }

        fapi2::delay(HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_HW_NS,
                     HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_DELAY_SIM_CYCLE);
    }
    while( (--l_timeout) != 0 );

    FAPI_ASSERT((l_timeout != 0),
                fapi2::SHADOW_DIS_CORE_SHADOW_STATE_TIMEOUT()
                .set_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS(HCD_SHADOW_DIS_CORE_SHADOW_STATE_POLL_TIMEOUT_HW_NS)
                .set_CPMS_CUCR(l_mmioData)
                .set_CORE_TARGET(i_target),
                "Shadow Disable FTC/PP/DPT Shadow State Timeout");

#ifndef XFER_SENT_DONE_DISABLE
    FAPI_DBG("Wait on XFER_RECEIVE_DONE via PCR_TFCSR[32]");
    l_timeout = HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS /
                HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_HW_NS;

    do
    {
        FAPI_TRY( HCD_GETMMIO_C( i_target, MMIO_LOWADDR(QME_TFCSR), l_mmioData ) );

        // use multicastAND to check 1
        if( MMIO_GET(MMIO_LOWBIT(32)) == 1 )
        {
            break;
        }

        fapi2::delay(HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_HW_NS,
                     HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_DELAY_SIM_CYCLE);
    }
    while( (--l_timeout) != 0 );

    FAPI_ASSERT((l_timeout != 0),
                fapi2::SHADOW_DIS_XFER_RECEIVE_DONE_TIMEOUT()
                .set_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS(HCD_SHADOW_DIS_XFER_RECEIVE_DONE_POLL_TIMEOUT_HW_NS)
                .set_QME_TFCSR(l_mmioData)
                .set_CORE_TARGET(i_target),
                "Shadow Disable Xfer Receive Done Timeout");

    FAPI_DBG("Drop XFER_RECEIVE_DONE via PCR_TFCSR[32]");
    FAPI_TRY( HCD_GETMMIO_C( i_target, MMIO_LOWADDR(QME_TFCSR_WO_CLEAR), MMIO_1BIT( MMIO_LOWBIT(32) ) ) );
#endif

    FAPI_DBG("Assert CTFS_WKUP_ENABLE via PCR_SCSR[27]");
    FAPI_TRY( HCD_PUTMMIO_C( i_target, QME_SCSR_WO_OR, MMIO_1BIT(27) ) );

fapi_try_exit:

    FAPI_INF("<<p10_hcd_core_shadows_disable");

    return fapi2::current_err;

}
<|endoftext|>