<commit_before>//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#include "rocksdb/utilities/write_batch_with_index.h"
#include "rocksdb/comparator.h"
#include "db/column_family.h"
#include "db/skiplist.h"
#include "util/arena.h"

namespace rocksdb {
namespace {
class ReadableWriteBatch : public WriteBatch {
 public:
  explicit ReadableWriteBatch(size_t reserved_bytes = 0)
      : WriteBatch(reserved_bytes) {}
  // Retrieve some information from a write entry in the write batch, given
  // the start offset of the write entry.
  Status GetEntryFromDataOffset(size_t data_offset, WriteType* type, Slice* Key,
                                Slice* value, Slice* blob) const;
};
}  // namespace

// Key used by skip list, as the binary searchable index of WriteBatchWithIndex.
struct WriteBatchIndexEntry {
  WriteBatchIndexEntry(size_t o, uint32_t c)
      : offset(o), column_family(c), search_key(nullptr) {}
  WriteBatchIndexEntry(const Slice* sk, uint32_t c)
      : offset(0), column_family(c), search_key(sk) {}

  size_t offset;           // offset of an entry in write batch's string buffer.
  uint32_t column_family;  // column family of the entry
  const Slice* search_key;  // if not null, instead of reading keys from
                            // write batch, use it to compare. This is used
                            // for lookup key.
};

class WriteBatchEntryComparator {
 public:
  WriteBatchEntryComparator(const Comparator* comparator,
                            const ReadableWriteBatch* write_batch)
      : comparator_(comparator), write_batch_(write_batch) {}
  // Compare a and b. Return a negative value if a is less than b, 0 if they
  // are equal, and a positive value if a is greater than b
  int operator()(const WriteBatchIndexEntry* entry1,
                 const WriteBatchIndexEntry* entry2) const;

 private:
  const Comparator* comparator_;
  const ReadableWriteBatch* write_batch_;
};

typedef SkipList<WriteBatchIndexEntry*, const WriteBatchEntryComparator&>
    WriteBatchEntrySkipList;

struct WriteBatchWithIndex::Rep {
  Rep(const Comparator* index_comparator, size_t reserved_bytes = 0)
      : write_batch(reserved_bytes),
        comparator(index_comparator, &write_batch),
        skip_list(comparator, &arena) {}
  ReadableWriteBatch write_batch;
  WriteBatchEntryComparator comparator;
  Arena arena;
  WriteBatchEntrySkipList skip_list;

  WriteBatchIndexEntry* GetEntry(ColumnFamilyHandle* column_family) {
    return GetEntryWithCfId(GetColumnFamilyID(column_family));
  }

  WriteBatchIndexEntry* GetEntryWithCfId(uint32_t column_family_id) {
    auto* mem = arena.Allocate(sizeof(WriteBatchIndexEntry));
    auto* index_entry = new (mem)
        WriteBatchIndexEntry(write_batch.GetDataSize(), column_family_id);
    return index_entry;
  }
};

class WBWIIteratorImpl : public WBWIIterator {
 public:
  WBWIIteratorImpl(uint32_t column_family_id,
                   WriteBatchEntrySkipList* skip_list,
                   const ReadableWriteBatch* write_batch)
      : column_family_id_(column_family_id),
        skip_list_iter_(skip_list),
        write_batch_(write_batch),
        valid_(false) {}

  virtual ~WBWIIteratorImpl() {}

  virtual bool Valid() const override { return valid_; }

  virtual void Seek(const Slice& key) override {
    valid_ = true;
    WriteBatchIndexEntry search_entry(&key, column_family_id_);
    skip_list_iter_.Seek(&search_entry);
    ReadEntry();
  }

  virtual void Next() override {
    skip_list_iter_.Next();
    ReadEntry();
  }

  virtual const WriteEntry& Entry() const override { return current_; }

  virtual Status status() const override { return status_; }

 private:
  uint32_t column_family_id_;
  WriteBatchEntrySkipList::Iterator skip_list_iter_;
  const ReadableWriteBatch* write_batch_;
  Status status_;
  bool valid_;
  WriteEntry current_;

  void ReadEntry() {
    if (!status_.ok() || !skip_list_iter_.Valid()) {
      valid_ = false;
      return;
    }
    const WriteBatchIndexEntry* iter_entry = skip_list_iter_.key();
    if (iter_entry == nullptr ||
        iter_entry->column_family != column_family_id_) {
      valid_ = false;
      return;
    }
    Slice blob;
    status_ = write_batch_->GetEntryFromDataOffset(
        iter_entry->offset, &current_.type, &current_.key, &current_.value,
        &blob);
    if (!status_.ok()) {
      valid_ = false;
    } else if (current_.type != kPutRecord && current_.type != kDeleteRecord &&
               current_.type != kMergeRecord) {
      valid_ = false;
      status_ = Status::Corruption("write batch index is corrupted");
    }
  }
};

Status ReadableWriteBatch::GetEntryFromDataOffset(size_t data_offset,
                                                  WriteType* type, Slice* Key,
                                                  Slice* value,
                                                  Slice* blob) const {
  if (type == nullptr || Key == nullptr || value == nullptr ||
      blob == nullptr) {
    return Status::InvalidArgument("Output parameters cannot be null");
  }

  if (data_offset >= GetDataSize()) {
    return Status::InvalidArgument("data offset exceed write batch size");
  }
  Slice input = Slice(rep_.data() + data_offset, rep_.size() - data_offset);
  char tag;
  uint32_t column_family;
  Status s =
      ReadRecordFromWriteBatch(&input, &tag, &column_family, Key, value, blob);

  switch (tag) {
    case kTypeColumnFamilyValue:
    case kTypeValue:
      *type = kPutRecord;
      break;
    case kTypeColumnFamilyDeletion:
    case kTypeDeletion:
      *type = kDeleteRecord;
      break;
    case kTypeColumnFamilyMerge:
    case kTypeMerge:
      *type = kMergeRecord;
      break;
    case kTypeLogData:
      *type = kLogDataRecord;
      break;
    default:
      return Status::Corruption("unknown WriteBatch tag");
  }
  return Status::OK();
}

WriteBatchWithIndex::WriteBatchWithIndex(const Comparator* index_comparator,
                                         size_t reserved_bytes)
    : rep(new Rep(index_comparator, reserved_bytes)) {}

WriteBatchWithIndex::~WriteBatchWithIndex() { delete rep; }

WriteBatch* WriteBatchWithIndex::GetWriteBatch() { return &rep->write_batch; }

WBWIIterator* WriteBatchWithIndex::NewIterator() {
  return new WBWIIteratorImpl(0, &(rep->skip_list), &rep->write_batch);
}

WBWIIterator* WriteBatchWithIndex::NewIterator(
    ColumnFamilyHandle* column_family) {
  return new WBWIIteratorImpl(GetColumnFamilyID(column_family),
                              &(rep->skip_list), &rep->write_batch);
}

void WriteBatchWithIndex::Put(ColumnFamilyHandle* column_family,
                              const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Put(column_family, key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Put(const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Put(key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Merge(ColumnFamilyHandle* column_family,
                                const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Merge(column_family, key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Merge(const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Merge(key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::PutLogData(const Slice& blob) {
  rep->write_batch.PutLogData(blob);
}

void WriteBatchWithIndex::Delete(ColumnFamilyHandle* column_family,
                                 const Slice& key) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Delete(column_family, key);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Delete(const Slice& key) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Delete(key);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Delete(ColumnFamilyHandle* column_family,
                                 const SliceParts& key) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Delete(column_family, key);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Delete(const SliceParts& key) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Delete(key);
  rep->skip_list.Insert(index_entry);
}

int WriteBatchEntryComparator::operator()(
    const WriteBatchIndexEntry* entry1,
    const WriteBatchIndexEntry* entry2) const {
  if (entry1->column_family > entry2->column_family) {
    return 1;
  } else if (entry1->column_family < entry2->column_family) {
    return -1;
  }

  Status s;
  Slice key1, key2;
  if (entry1->search_key == nullptr) {
    Slice value, blob;
    WriteType write_type;
    s = write_batch_->GetEntryFromDataOffset(entry1->offset, &write_type, &key1,
                                             &value, &blob);
    if (!s.ok()) {
      return 1;
    }
  } else {
    key1 = *(entry1->search_key);
  }
  if (entry2->search_key == nullptr) {
    Slice value, blob;
    WriteType write_type;
    s = write_batch_->GetEntryFromDataOffset(entry2->offset, &write_type, &key2,
                                             &value, &blob);
    if (!s.ok()) {
      return -1;
    }
  } else {
    key2 = *(entry2->search_key);
  }

  int cmp = comparator_->Compare(key1, key2);
  if (cmp != 0) {
    return cmp;
  } else if (entry1->offset > entry2->offset) {
    return 1;
  } else if (entry1->offset < entry2->offset) {
    return -1;
  }
  return 0;
}

}  // namespace rocksdb
<commit_msg>fix unity build<commit_after>//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#include "rocksdb/utilities/write_batch_with_index.h"
#include "rocksdb/comparator.h"
#include "db/column_family.h"
#include "db/skiplist.h"
#include "util/arena.h"

namespace rocksdb {
class ReadableWriteBatch : public WriteBatch {
 public:
  explicit ReadableWriteBatch(size_t reserved_bytes = 0)
      : WriteBatch(reserved_bytes) {}
  // Retrieve some information from a write entry in the write batch, given
  // the start offset of the write entry.
  Status GetEntryFromDataOffset(size_t data_offset, WriteType* type, Slice* Key,
                                Slice* value, Slice* blob) const;
};

// Key used by skip list, as the binary searchable index of WriteBatchWithIndex.
struct WriteBatchIndexEntry {
  WriteBatchIndexEntry(size_t o, uint32_t c)
      : offset(o), column_family(c), search_key(nullptr) {}
  WriteBatchIndexEntry(const Slice* sk, uint32_t c)
      : offset(0), column_family(c), search_key(sk) {}

  size_t offset;           // offset of an entry in write batch's string buffer.
  uint32_t column_family;  // column family of the entry
  const Slice* search_key;  // if not null, instead of reading keys from
                            // write batch, use it to compare. This is used
                            // for lookup key.
};

class WriteBatchEntryComparator {
 public:
  WriteBatchEntryComparator(const Comparator* comparator,
                            const ReadableWriteBatch* write_batch)
      : comparator_(comparator), write_batch_(write_batch) {}
  // Compare a and b. Return a negative value if a is less than b, 0 if they
  // are equal, and a positive value if a is greater than b
  int operator()(const WriteBatchIndexEntry* entry1,
                 const WriteBatchIndexEntry* entry2) const;

 private:
  const Comparator* comparator_;
  const ReadableWriteBatch* write_batch_;
};

typedef SkipList<WriteBatchIndexEntry*, const WriteBatchEntryComparator&>
    WriteBatchEntrySkipList;

struct WriteBatchWithIndex::Rep {
  Rep(const Comparator* index_comparator, size_t reserved_bytes = 0)
      : write_batch(reserved_bytes),
        comparator(index_comparator, &write_batch),
        skip_list(comparator, &arena) {}
  ReadableWriteBatch write_batch;
  WriteBatchEntryComparator comparator;
  Arena arena;
  WriteBatchEntrySkipList skip_list;

  WriteBatchIndexEntry* GetEntry(ColumnFamilyHandle* column_family) {
    return GetEntryWithCfId(GetColumnFamilyID(column_family));
  }

  WriteBatchIndexEntry* GetEntryWithCfId(uint32_t column_family_id) {
    auto* mem = arena.Allocate(sizeof(WriteBatchIndexEntry));
    auto* index_entry = new (mem)
        WriteBatchIndexEntry(write_batch.GetDataSize(), column_family_id);
    return index_entry;
  }
};

class WBWIIteratorImpl : public WBWIIterator {
 public:
  WBWIIteratorImpl(uint32_t column_family_id,
                   WriteBatchEntrySkipList* skip_list,
                   const ReadableWriteBatch* write_batch)
      : column_family_id_(column_family_id),
        skip_list_iter_(skip_list),
        write_batch_(write_batch),
        valid_(false) {}

  virtual ~WBWIIteratorImpl() {}

  virtual bool Valid() const override { return valid_; }

  virtual void Seek(const Slice& key) override {
    valid_ = true;
    WriteBatchIndexEntry search_entry(&key, column_family_id_);
    skip_list_iter_.Seek(&search_entry);
    ReadEntry();
  }

  virtual void Next() override {
    skip_list_iter_.Next();
    ReadEntry();
  }

  virtual const WriteEntry& Entry() const override { return current_; }

  virtual Status status() const override { return status_; }

 private:
  uint32_t column_family_id_;
  WriteBatchEntrySkipList::Iterator skip_list_iter_;
  const ReadableWriteBatch* write_batch_;
  Status status_;
  bool valid_;
  WriteEntry current_;

  void ReadEntry() {
    if (!status_.ok() || !skip_list_iter_.Valid()) {
      valid_ = false;
      return;
    }
    const WriteBatchIndexEntry* iter_entry = skip_list_iter_.key();
    if (iter_entry == nullptr ||
        iter_entry->column_family != column_family_id_) {
      valid_ = false;
      return;
    }
    Slice blob;
    status_ = write_batch_->GetEntryFromDataOffset(
        iter_entry->offset, &current_.type, &current_.key, &current_.value,
        &blob);
    if (!status_.ok()) {
      valid_ = false;
    } else if (current_.type != kPutRecord && current_.type != kDeleteRecord &&
               current_.type != kMergeRecord) {
      valid_ = false;
      status_ = Status::Corruption("write batch index is corrupted");
    }
  }
};

Status ReadableWriteBatch::GetEntryFromDataOffset(size_t data_offset,
                                                  WriteType* type, Slice* Key,
                                                  Slice* value,
                                                  Slice* blob) const {
  if (type == nullptr || Key == nullptr || value == nullptr ||
      blob == nullptr) {
    return Status::InvalidArgument("Output parameters cannot be null");
  }

  if (data_offset >= GetDataSize()) {
    return Status::InvalidArgument("data offset exceed write batch size");
  }
  Slice input = Slice(rep_.data() + data_offset, rep_.size() - data_offset);
  char tag;
  uint32_t column_family;
  Status s =
      ReadRecordFromWriteBatch(&input, &tag, &column_family, Key, value, blob);

  switch (tag) {
    case kTypeColumnFamilyValue:
    case kTypeValue:
      *type = kPutRecord;
      break;
    case kTypeColumnFamilyDeletion:
    case kTypeDeletion:
      *type = kDeleteRecord;
      break;
    case kTypeColumnFamilyMerge:
    case kTypeMerge:
      *type = kMergeRecord;
      break;
    case kTypeLogData:
      *type = kLogDataRecord;
      break;
    default:
      return Status::Corruption("unknown WriteBatch tag");
  }
  return Status::OK();
}

WriteBatchWithIndex::WriteBatchWithIndex(const Comparator* index_comparator,
                                         size_t reserved_bytes)
    : rep(new Rep(index_comparator, reserved_bytes)) {}

WriteBatchWithIndex::~WriteBatchWithIndex() { delete rep; }

WriteBatch* WriteBatchWithIndex::GetWriteBatch() { return &rep->write_batch; }

WBWIIterator* WriteBatchWithIndex::NewIterator() {
  return new WBWIIteratorImpl(0, &(rep->skip_list), &rep->write_batch);
}

WBWIIterator* WriteBatchWithIndex::NewIterator(
    ColumnFamilyHandle* column_family) {
  return new WBWIIteratorImpl(GetColumnFamilyID(column_family),
                              &(rep->skip_list), &rep->write_batch);
}

void WriteBatchWithIndex::Put(ColumnFamilyHandle* column_family,
                              const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Put(column_family, key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Put(const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Put(key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Merge(ColumnFamilyHandle* column_family,
                                const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Merge(column_family, key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Merge(const Slice& key, const Slice& value) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Merge(key, value);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::PutLogData(const Slice& blob) {
  rep->write_batch.PutLogData(blob);
}

void WriteBatchWithIndex::Delete(ColumnFamilyHandle* column_family,
                                 const Slice& key) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Delete(column_family, key);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Delete(const Slice& key) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Delete(key);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Delete(ColumnFamilyHandle* column_family,
                                 const SliceParts& key) {
  auto* index_entry = rep->GetEntry(column_family);
  rep->write_batch.Delete(column_family, key);
  rep->skip_list.Insert(index_entry);
}

void WriteBatchWithIndex::Delete(const SliceParts& key) {
  auto* index_entry = rep->GetEntryWithCfId(0);
  rep->write_batch.Delete(key);
  rep->skip_list.Insert(index_entry);
}

int WriteBatchEntryComparator::operator()(
    const WriteBatchIndexEntry* entry1,
    const WriteBatchIndexEntry* entry2) const {
  if (entry1->column_family > entry2->column_family) {
    return 1;
  } else if (entry1->column_family < entry2->column_family) {
    return -1;
  }

  Status s;
  Slice key1, key2;
  if (entry1->search_key == nullptr) {
    Slice value, blob;
    WriteType write_type;
    s = write_batch_->GetEntryFromDataOffset(entry1->offset, &write_type, &key1,
                                             &value, &blob);
    if (!s.ok()) {
      return 1;
    }
  } else {
    key1 = *(entry1->search_key);
  }
  if (entry2->search_key == nullptr) {
    Slice value, blob;
    WriteType write_type;
    s = write_batch_->GetEntryFromDataOffset(entry2->offset, &write_type, &key2,
                                             &value, &blob);
    if (!s.ok()) {
      return -1;
    }
  } else {
    key2 = *(entry2->search_key);
  }

  int cmp = comparator_->Compare(key1, key2);
  if (cmp != 0) {
    return cmp;
  } else if (entry1->offset > entry2->offset) {
    return 1;
  } else if (entry1->offset < entry2->offset) {
    return -1;
  }
  return 0;
}

}  // namespace rocksdb
<|endoftext|>


<commit_before>//
// Copyright (C) 2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Dan Petrie <dpetrie AT SIPez DOT com>

// SYSTEM INCLUDES
#include <assert.h>
#include <math.h>

// APPLICATION INCLUDES
#include <mp/MpInputDeviceManager.h>
#include <mp/MpSineWaveGeneratorDeviceDriver.h>
#include <os/OsServerTask.h>
#include <os/OsTimer.h>
#ifdef RTL_ENABLED
#   include <rtl_macro.h>
#endif

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
#ifndef M_PI
#   define M_PI 3.14159265358979323846
#endif

// 0 is the Highest priority
#define SINE_WAVE_DEVICE_PRIORITY 0

// STATIC VARIABLE INITIALIZATIONS
// PRIVATE CLASSES
class MpSineWaveGeneratorServer : public OsServerTask
{
public:
    MpSineWaveGeneratorServer(unsigned int startFrameTime,
                              unsigned int samplesPerFrame,
                              unsigned int samplesPerSecond,
                              unsigned int magnitude,
                              unsigned int periodMicroseconds,
                              int underOverRunTime,
                              MpInputDeviceHandle deviceId,
                              MpInputDeviceManager& inputDeviceManager)
    : OsServerTask("MpSineWaveGeneratorServer-%d", NULL, DEF_MAX_MSGS, SINE_WAVE_DEVICE_PRIORITY),
    mNextFrameTime(startFrameTime),
    mSamplesPerFrame(samplesPerFrame),
    mSamplesPerSecond(samplesPerSecond),
    mMagnatude(magnitude),
    mSinePeriodMicroseconds(periodMicroseconds),
    mUnderOverRunTime(underOverRunTime),
    mDeviceId(deviceId),
    mpInputDeviceManager(&inputDeviceManager),
    mpFrameData(NULL),
    mTimer(getMessageQueue(), 0)
    {
        mpFrameData = new MpAudioSample[samplesPerFrame];
    };

    virtual ~MpSineWaveGeneratorServer()
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorServer start");

        // Do not continue until the task is safely shutdown
        waitUntilShutDown();
        assert(isShutDown());

        if(mpFrameData)
        {
            delete[] mpFrameData;
            mpFrameData = NULL;
        }
        OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorServer end");
    };

    virtual UtlBoolean start(void)
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::start start");
        // start the task
        UtlBoolean result = OsServerTask::start();

        OsTime noDelay(0, 0);
        int microSecondsPerFrame =
            (mSamplesPerFrame * 1000000 / mSamplesPerSecond) -
            mUnderOverRunTime;
        assert(microSecondsPerFrame > 0);
        OsTime framePeriod(0, microSecondsPerFrame);
        // Start re-occurring timer which causes handleMessage to be called
        // periodically
        mTimer.periodicEvery(noDelay, framePeriod);
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::start end");
        return(result);
    };

    virtual void requestShutdown(void)
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::requestShutdown start");
        // Stop the timer first so it stops queuing messages
        mTimer.stop();

        // Then stop the server task
        OsServerTask::requestShutdown();
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::requestShutdown end");
    };

    UtlBoolean handleMessage(OsMsg& rMsg)
    {
#ifdef RTL_ENABLED
        RTL_BLOCK("MpSineWaveGeneratorServer.handleMessage");
#endif
        // Build a frame of signal and push it to the device manager
        assert(mpFrameData);

        for(unsigned int frameIndex = 0; frameIndex < mSamplesPerFrame; frameIndex++)
        {
            mpFrameData[frameIndex] =
                MpSineWaveGeneratorDeviceDriver::calculateSample(mNextFrameTime,
                                                                 mMagnatude,
                                                                 mSinePeriodMicroseconds,
                                                                 frameIndex,
                                                                 mSamplesPerFrame,
                                                                 mSamplesPerSecond);
        }

        mpInputDeviceManager->pushFrame(mDeviceId,
                                        mSamplesPerFrame,
                                        mpFrameData,
                                        mNextFrameTime);
        mNextFrameTime += mSamplesPerFrame * 1000 / mSamplesPerSecond;

        return(TRUE);
    }

private:
    MpFrameTime mNextFrameTime;
    unsigned int mSamplesPerFrame;
    unsigned int mSamplesPerSecond;
    unsigned int mMagnatude;
    unsigned int mSinePeriodMicroseconds;
    int mUnderOverRunTime;
    MpInputDeviceHandle mDeviceId;
    MpInputDeviceManager* mpInputDeviceManager;
    MpAudioSample* mpFrameData;
    OsTimer mTimer;
};

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
MpSineWaveGeneratorDeviceDriver::MpSineWaveGeneratorDeviceDriver(const UtlString& name,
                                                                 MpInputDeviceManager& deviceManager,
                                                                 unsigned int magnitude,
                                                                 unsigned int periodInMicroseconds,
                                                                 int underOverRunTime)
: MpInputDeviceDriver(name, deviceManager),
mMagnitude(magnitude),
mPeriodInMicroseconds(periodInMicroseconds),
mUnderOverRunTime(underOverRunTime),
mpReaderTask(NULL)
{
}

// Destructor
MpSineWaveGeneratorDeviceDriver::~MpSineWaveGeneratorDeviceDriver()
{
    OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorDeviceDriver start");
    if(mpReaderTask)
    {
        OsStatus stat = disableDevice();
        assert(stat == OS_SUCCESS);
    }
    OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorDeviceDriver end");
}

/* ============================ MANIPULATORS ============================== */

OsStatus MpSineWaveGeneratorDeviceDriver::enableDevice(unsigned samplesPerFrame,
                                                      unsigned samplesPerSec,
                                                      MpFrameTime currentFrameTime)
{
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::enableDevice start");
    OsStatus result = OS_INVALID;
    assert(mpReaderTask == NULL);

    if(mpReaderTask == NULL)
    {
        mpReaderTask =
            new MpSineWaveGeneratorServer(currentFrameTime,
                                          samplesPerFrame,
                                          samplesPerSec,
                                          mMagnitude,
                                          mPeriodInMicroseconds,
                                          mUnderOverRunTime,
                                          getDeviceId(),
                                          *mpInputDeviceManager);

        if(mpReaderTask->start())
        {
            result = OS_SUCCESS;
            mIsEnabled = TRUE;

        }
    }
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::enableDevice end");
    return(result);
}

OsStatus MpSineWaveGeneratorDeviceDriver::disableDevice()
{
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::disableDevice start");
    OsStatus result = OS_TASK_NOT_STARTED;
    //assert(mpReaderTask);

    if(mpReaderTask)
    {
        mpReaderTask->requestShutdown();
        delete mpReaderTask;
        mpReaderTask = NULL;
        result = OS_SUCCESS;
        mIsEnabled = FALSE;
    }
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::disableDevice end");
    return(result);
}

/* ============================ ACCESSORS ================================= */
MpAudioSample
MpSineWaveGeneratorDeviceDriver::calculateSample(MpFrameTime frameStartTime,
                                                 unsigned int magnitude,
                                                 unsigned int periodInMicroseconds,
                                                 unsigned int frameSampleIndex,
                                                 unsigned int samplesPerFrame,
                                                 unsigned int samplesPerSecond)
{
    double time = ((frameStartTime + frameSampleIndex * 1000.0 / samplesPerSecond)
        / ((double) periodInMicroseconds) * 1000.0 ) * 2.0 * M_PI;
    MpAudioSample sample = (MpAudioSample)(sin(time) * (double)magnitude);

    return(sample);
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */

<commit_msg>Fixed sine wave calculation to prevent integer round off.<commit_after>//
// Copyright (C) 2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Dan Petrie <dpetrie AT SIPez DOT com>

// SYSTEM INCLUDES
#include <assert.h>
#include <math.h>

// APPLICATION INCLUDES
#include <mp/MpInputDeviceManager.h>
#include <mp/MpSineWaveGeneratorDeviceDriver.h>
#include <os/OsServerTask.h>
#include <os/OsTimer.h>
#ifdef RTL_ENABLED
#   include <rtl_macro.h>
#endif

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
#ifndef M_PI
#   define M_PI 3.14159265358979323846
#endif

// 0 is the Highest priority
#define SINE_WAVE_DEVICE_PRIORITY 0

// STATIC VARIABLE INITIALIZATIONS
// PRIVATE CLASSES
class MpSineWaveGeneratorServer : public OsServerTask
{
public:
    MpSineWaveGeneratorServer(unsigned int startFrameTime,
                              unsigned int samplesPerFrame,
                              unsigned int samplesPerSecond,
                              unsigned int magnitude,
                              unsigned int periodMicroseconds,
                              int underOverRunTime,
                              MpInputDeviceHandle deviceId,
                              MpInputDeviceManager& inputDeviceManager)
    : OsServerTask("MpSineWaveGeneratorServer-%d", NULL, DEF_MAX_MSGS, SINE_WAVE_DEVICE_PRIORITY),
    mNextFrameTime(startFrameTime),
    mSamplesPerFrame(samplesPerFrame),
    mSamplesPerSecond(samplesPerSecond),
    mMagnatude(magnitude),
    mSinePeriodMicroseconds(periodMicroseconds),
    mUnderOverRunTime(underOverRunTime),
    mDeviceId(deviceId),
    mpInputDeviceManager(&inputDeviceManager),
    mpFrameData(NULL),
    mTimer(getMessageQueue(), 0)
    {
        mpFrameData = new MpAudioSample[samplesPerFrame];
    };

    virtual ~MpSineWaveGeneratorServer()
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorServer start");

        // Do not continue until the task is safely shutdown
        waitUntilShutDown();
        assert(isShutDown());

        if(mpFrameData)
        {
            delete[] mpFrameData;
            mpFrameData = NULL;
        }
        OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorServer end");
    };

    virtual UtlBoolean start(void)
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::start start");
        // start the task
        UtlBoolean result = OsServerTask::start();

        OsTime noDelay(0, 0);
        int microSecondsPerFrame =
            (mSamplesPerFrame * 1000000 / mSamplesPerSecond) -
            mUnderOverRunTime;
        assert(microSecondsPerFrame > 0);
        OsTime framePeriod(0, microSecondsPerFrame);
        // Start re-occurring timer which causes handleMessage to be called
        // periodically
        mTimer.periodicEvery(noDelay, framePeriod);
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::start end");
        return(result);
    };

    virtual void requestShutdown(void)
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::requestShutdown start");
        // Stop the timer first so it stops queuing messages
        mTimer.stop();

        // Then stop the server task
        OsServerTask::requestShutdown();
        OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorServer::requestShutdown end");
    };

    UtlBoolean handleMessage(OsMsg& rMsg)
    {
#ifdef RTL_ENABLED
        RTL_BLOCK("MpSineWaveGeneratorServer.handleMessage");
#endif
        // Build a frame of signal and push it to the device manager
        assert(mpFrameData);

        for(unsigned int frameIndex = 0; frameIndex < mSamplesPerFrame; frameIndex++)
        {
            mpFrameData[frameIndex] =
                MpSineWaveGeneratorDeviceDriver::calculateSample(mNextFrameTime,
                                                                 mMagnatude,
                                                                 mSinePeriodMicroseconds,
                                                                 frameIndex,
                                                                 mSamplesPerFrame,
                                                                 mSamplesPerSecond);
        }

        mpInputDeviceManager->pushFrame(mDeviceId,
                                        mSamplesPerFrame,
                                        mpFrameData,
                                        mNextFrameTime);
        mNextFrameTime += mSamplesPerFrame * 1000 / mSamplesPerSecond;

        return(TRUE);
    }

private:
    MpFrameTime mNextFrameTime;
    unsigned int mSamplesPerFrame;
    unsigned int mSamplesPerSecond;
    unsigned int mMagnatude;
    unsigned int mSinePeriodMicroseconds;
    int mUnderOverRunTime;
    MpInputDeviceHandle mDeviceId;
    MpInputDeviceManager* mpInputDeviceManager;
    MpAudioSample* mpFrameData;
    OsTimer mTimer;
};

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
MpSineWaveGeneratorDeviceDriver::MpSineWaveGeneratorDeviceDriver(const UtlString& name,
                                                                 MpInputDeviceManager& deviceManager,
                                                                 unsigned int magnitude,
                                                                 unsigned int periodInMicroseconds,
                                                                 int underOverRunTime)
: MpInputDeviceDriver(name, deviceManager),
mMagnitude(magnitude),
mPeriodInMicroseconds(periodInMicroseconds),
mUnderOverRunTime(underOverRunTime),
mpReaderTask(NULL)
{
}

// Destructor
MpSineWaveGeneratorDeviceDriver::~MpSineWaveGeneratorDeviceDriver()
{
    OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorDeviceDriver start");
    if(mpReaderTask)
    {
        OsStatus stat = disableDevice();
        assert(stat == OS_SUCCESS);
    }
    OsSysLog::add(FAC_MP, PRI_DEBUG,"~MpSineWaveGeneratorDeviceDriver end");
}

/* ============================ MANIPULATORS ============================== */

OsStatus MpSineWaveGeneratorDeviceDriver::enableDevice(unsigned samplesPerFrame,
                                                      unsigned samplesPerSec,
                                                      MpFrameTime currentFrameTime)
{
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::enableDevice start");
    OsStatus result = OS_INVALID;
    assert(mpReaderTask == NULL);

    if(mpReaderTask == NULL)
    {
        mpReaderTask =
            new MpSineWaveGeneratorServer(currentFrameTime,
                                          samplesPerFrame,
                                          samplesPerSec,
                                          mMagnitude,
                                          mPeriodInMicroseconds,
                                          mUnderOverRunTime,
                                          getDeviceId(),
                                          *mpInputDeviceManager);

        if(mpReaderTask->start())
        {
            result = OS_SUCCESS;
            mIsEnabled = TRUE;

        }
    }
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::enableDevice end");
    return(result);
}

OsStatus MpSineWaveGeneratorDeviceDriver::disableDevice()
{
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::disableDevice start");
    OsStatus result = OS_TASK_NOT_STARTED;
    //assert(mpReaderTask);

    if(mpReaderTask)
    {
        mpReaderTask->requestShutdown();
        delete mpReaderTask;
        mpReaderTask = NULL;
        result = OS_SUCCESS;
        mIsEnabled = FALSE;
    }
    OsSysLog::add(FAC_MP, PRI_DEBUG,"MpSineWaveGeneratorDeviceDriver::disableDevice end");
    return(result);
}

/* ============================ ACCESSORS ================================= */
MpAudioSample
MpSineWaveGeneratorDeviceDriver::calculateSample(MpFrameTime frameStartTime,
                                                 unsigned int magnitude,
                                                 unsigned int periodInMicroseconds,
                                                 unsigned int frameSampleIndex,
                                                 unsigned int samplesPerFrame,
                                                 unsigned int samplesPerSecond)
{
    double time = ((frameStartTime + frameSampleIndex * 1000.0 / (double) samplesPerSecond)
        / ((double) periodInMicroseconds) * 1000.0 ) * 2.0 * M_PI;
    MpAudioSample sample = (MpAudioSample)(sin(time) * (double)magnitude);

    return(sample);
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */

<|endoftext|>


<commit_before>#include "physics/n_body_system.hpp"

#include <memory>
#include <string>

#include "geometry/grassmann.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "physics/body.hpp"
#include "physics/frame.hpp"

using principia::geometry::Vector;

namespace principia {
namespace physics {

class NBodySystemTest : public testing::Test {
 protected:
  void SetUp() override {
    integrator_.Initialize(integrator_.Order5Optimal());

    // The Earth-Moon system, roughly.
    body1_ = new Body<InertialFrame>(6E24 * Mass::SIUnit());
    body2_ = new Body<InertialFrame>(7E22 * Mass::SIUnit());
    Vector<Length, InertialFrame> q1({0 * Length::SIUnit(),
                                      0 * Length::SIUnit(),
                                      0 * Length::SIUnit()});
    Vector<Length, InertialFrame> q2({0 * Length::SIUnit(),
                                      4E8 * Length::SIUnit(),
                                      0 * Length::SIUnit()});
    Vector<Speed, InertialFrame> p1({0 * Speed::SIUnit(),
                                     0 * Speed::SIUnit(),
                                     0 * Speed::SIUnit()});
    //TODO(phl): Despite the name, this wants a speed...
    Vector<Speed, InertialFrame> p2({1E3 * Speed::SIUnit(),
                                     0 * Speed::SIUnit(),
                                     0 * Speed::SIUnit()});
    body1_->AppendToTrajectory({q1}, {p1}, {0 * Time::SIUnit()});
    body2_->AppendToTrajectory({q2}, {p2}, {0 * Time::SIUnit()});
    system_.reset(new NBodySystem(
        new std::vector<Body<InertialFrame>*>({body1_, body2_})));
  }

  template<typename Scalar, typename Frame>
  std::string ToMathematicaString(Vector<Scalar, Frame> const& vector) {
    R3Element<Scalar> const& coordinates = vector.coordinates();
    std::string result = "{";
    result += quantities::ToString(coordinates.x);
    result += ",";
    result += quantities::ToString(coordinates.y);
    result += ",";
    result += quantities::ToString(coordinates.z);
    result += "}";
    return result;
  }

  template<typename Scalar, typename Frame>
  std::string ToMathematicaString(
      std::vector<Vector<Scalar, Frame>> const& vectors) {
    static std::string const mathematica_line =
        "(*****************************************************)";
    std::string result = mathematica_line + "\n";
    result += "ToExpression[StringReplace[\"\n{";
    std::string separator = "";
    for (const auto& vector : vectors) {
      result += separator;
      result += ToMathematicaString(vector);
      separator = ",\n";
    }
    result +=
        "}\",\n{\" m\"->\"\",\"e\"->\"*^\", \"\\n\"->\"\", \" \"->\"\"}]];\n";
    result += mathematica_line;
    return result;
  }

  Body<InertialFrame>* body1_;
  Body<InertialFrame>* body2_;
  SPRKIntegrator integrator_;
  std::unique_ptr<NBodySystem> system_;
};

TEST_F(NBodySystemTest, T) {
  std::vector<Vector<Length, InertialFrame>> positions;
  std::vector<Vector<Speed, InertialFrame>> momenta;
  std::vector<Time> times;
  system_->Integrate(integrator_, 3E6 * Time::SIUnit(), 3E4 * Time::SIUnit(), 1);
  body1_->GetTrajectory(&positions, &momenta, &times);
  LOG(ERROR) << ToMathematicaString(positions);
  body2_->GetTrajectory(&positions, &momenta, &times);
  LOG(ERROR) << ToMathematicaString(positions);
}

}  // namespace physics
}  // namespace principia<commit_msg>Trying to understand the 2-body problem.<commit_after>#include "physics/n_body_system.hpp"

#include <memory>
#include <string>

#include "geometry/grassmann.hpp"
#include "geometry/point.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "physics/body.hpp"
#include "physics/frame.hpp"
#include "quantities/constants.hpp"
#include "quantities/numbers.hpp"

using principia::constants::GravitationalConstant;
using principia::geometry::Barycentre;
using principia::geometry::Point;
using principia::geometry::Vector;

namespace principia {
namespace physics {

class NBodySystemTest : public testing::Test {
 protected:
  void SetUp() override {
    integrator_.Initialize(integrator_.Order5Optimal());

    // The Earth-Moon system, roughly.
    body1_ = new Body<InertialFrame>(6E24 * Mass::SIUnit());
    body2_ = new Body<InertialFrame>(7E22 * Mass::SIUnit());
    Point<Vector<Length, InertialFrame>> const
        q1(Vector<Length, InertialFrame>({0 * Length::SIUnit(),
                                          0 * Length::SIUnit(),
                                          0 * Length::SIUnit()}));
    Point<Vector<Length, InertialFrame>> const
        q2(Vector<Length, InertialFrame>({0 * Length::SIUnit(),
                                          4E8 * Length::SIUnit(),
                                          0 * Length::SIUnit()}));
    Point<Vector<Length, InertialFrame>> const centre_of_mass =
        Barycentre(q1, body1_->mass(), q2, body2_->mass());
    Point<Vector<Speed, InertialFrame>> const
        v1(Vector<Speed, InertialFrame>({0 * Speed::SIUnit(),
                                         0 * Speed::SIUnit(),
                                         0 * Speed::SIUnit()}));
    // 1E3 m/s puts us at the apogee at the beginning, because the speed for a
    // circular orbit with this separation would be 1006.36 m/s.
    Point<Vector<Speed, InertialFrame>> const
        v2(Vector<Speed, InertialFrame>({1E3 * Speed::SIUnit(),
                                         0 * Speed::SIUnit(),
                                         0 * Speed::SIUnit()}));
    Point<Vector<Speed, InertialFrame>> const overall_velocity =
        Barycentre(v1, body1_->mass(), v2, body2_->mass());
    body1_->AppendToTrajectory({q1 - centre_of_mass},
                               {v1 - overall_velocity},
                               {0 * Time::SIUnit()});
    body2_->AppendToTrajectory({q2 - centre_of_mass},
                               {v2 - overall_velocity},
                               {0 * Time::SIUnit()});
    Length const r2 = (q2 - centre_of_mass).Norm();
    Length const semi_major_axis =
        1 / (2 / r2 -
                 (v2 - overall_velocity).Norm().Pow<2>() /
                      (body1_->gravitational_parameter() +
                       body2_->gravitational_parameter()));
    Length const r1 = (q1 - centre_of_mass).Norm();
    Length const semi_major_axis1 =
        1 / (2 / r1 -
                 (v1 - overall_velocity).Norm().Pow<2>() /
                      (body1_->gravitational_parameter() +
                       body2_->gravitational_parameter()));
    LOG(ERROR)<<semi_major_axis<<" "<<semi_major_axis1;
    period_ = 2 * π * Sqrt(
        (semi_major_axis1 + semi_major_axis).Pow<3>() /
            (GravitationalConstant * (body1_->mass() + body2_->mass())));
    system_.reset(new NBodySystem(
        new std::vector<Body<InertialFrame>*>({body1_, body2_})));
  }

  template<typename Scalar, typename Frame>
  std::string ToMathematicaString(Vector<Scalar, Frame> const& vector) {
    R3Element<Scalar> const& coordinates = vector.coordinates();
    std::string result = "{";
    result += quantities::ToString(coordinates.x);
    result += ",";
    result += quantities::ToString(coordinates.y);
    result += ",";
    result += quantities::ToString(coordinates.z);
    result += "}";
    return result;
  }

  template<typename Scalar, typename Frame>
  std::string ToMathematicaString(
      std::vector<Vector<Scalar, Frame>> const& vectors) {
    static std::string const mathematica_line =
        "(*****************************************************)";
    std::string result = mathematica_line + "\n";
    result += "ToExpression[StringReplace[\"\n{";
    std::string separator = "";
    for (const auto& vector : vectors) {
      result += separator;
      result += ToMathematicaString(vector);
      separator = ",\n";
    }
    result +=
        "}\",\n{\" m\"->\"\",\"e\"->\"*^\", \"\\n\"->\"\", \" \"->\"\"}]];\n";
    result += mathematica_line;
    return result;
  }

  Body<InertialFrame>* body1_;
  Body<InertialFrame>* body2_;
  SPRKIntegrator integrator_;
  Time period_;
  std::unique_ptr<NBodySystem> system_;
};

TEST_F(NBodySystemTest, T) {
  std::vector<Vector<Length, InertialFrame>> positions;
  std::vector<Vector<Speed, InertialFrame>> momenta;
  std::vector<Time> times;
  LOG(ERROR)<<period_;
  system_->Integrate(integrator_, 1.1*period_, period_ / 1000, 1);
  body1_->GetTrajectory(&positions, &momenta, &times);
  LOG(ERROR) << ToMathematicaString(positions);
  body2_->GetTrajectory(&positions, &momenta, &times);
  LOG(ERROR) << ToMathematicaString(positions);
}

}  // namespace physics
}  // namespace principia<|endoftext|>


<commit_before><commit_msg>Create 1189 - Left Area.cpp<commit_after><|endoftext|>


<commit_before>#include "BombDefender.h"

#include <string.h>
#include <GLES3/gl3.h>
#include <jni.h>
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
#include <Context.h>
#include <AndroidPlatform.h>
#include <ContextAndroid.h>
#include <VBO.h>
#include <OpenGLTexture.h>

using namespace std;
using namespace gpufw;

std::shared_ptr<canvas::Context> context;
int positionX = 120;
int positionY = 120;
std::shared_ptr<canvas::Surface> yoSurface;
std::shared_ptr<canvas::OpenGLTexture> texture;

bool BombDefender::Init() {

  test_program = std::shared_ptr<gpufw::shader_program>(new gpufw::shader_program);

  test_program->loadShaders(getPlatform().getGLSLVersion(), "simple_sprite_shader.glsl");
  test_program->bindAttribLocation(0, "a_texCoord");
  test_program->bindAttribLocation(1, "a_position");
  test_program->link();

  auto contextF = getPlatform().createContextFactory();
   context = contextF->createContext(256, 256, canvas::InternalFormat::RGBA8, true);

   context->globalAlpha = 1.0f;
   context->font.size = 50;
   context->textBaseline = "top";
   yoSurface = context->createSurface("picture.jpg");
   context->drawImage(*yoSurface, 0, 0, 256, 256);

   texture = std::shared_ptr<canvas::OpenGLTexture>(new canvas::OpenGLTexture(context->getDefaultSurface()));
}

void BombDefender::onDraw() {

  Sprite sprite;
  drawSprite(sprite);
//  auto contextF = getPlatform().createContextFactory();
//  context = contextF->createContext(500, 500, canvas::InternalFormat::RGBA8, true);
//
//  context->globalAlpha = 1.0f;
//  context->font.size = 50;
//  context->textBaseline = "top";
//  yoSurface = context->createSurface("picture.jpg");
//
//  context->drawImage(*yoSurface, positionX, positionY, 200, 200);
//  positionX--;
//  positionY--;
//	__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Application ondraw");
//  dynamic_cast<AndroidPlatform&>(getPlatform()).showCanvas(dynamic_cast<canvas::ContextAndroid&>(*context));

}

void BombDefender::drawSprite(const Sprite & sprite){

  glm::mat4 projMat = glm::ortho(0.0f, 640.0f, 0.0f, 480.0f, -1000.0f, +1000.0f);
  glm::mat4 mat(1.0f);

  use(*test_program);
  test_program->setUniform("proj_mv_matrix", projMat * mat);
  test_program->setUniform("s_texture", 0);

  glDisable(GL_DEPTH_TEST);
  glDisable(GL_STENCIL_TEST);
  glDisable(GL_CULL_FACE);
  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  glDepthMask(GL_FALSE);

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texture->getTextureId());

  VBO vbo;
  vbo.quad2d(10.0f, 10.0f,
  	   500.0f, 10.0f,
  	   500.0f, 500.0f,
  	   10.0f, 500.0f);

  bind(vbo);

//	__android_log_print(ANDROID_LOG_INFO, "Sometrik", "BomdDefender vertexBufferId id: %d", vbo.getVertexBufferId());
//	__android_log_print(ANDROID_LOG_INFO, "Sometrik", "BomdDefender IndexBufferId id: %d", vbo.getIndexBufferId());

  vbo.draw();

  glBindTexture(GL_TEXTURE_2D, 0);
}

void BombDefender::onShutdown() {
}

void
BombDefender::use(const gpufw::shader_program & program) {
  int id = program.getProgramObjectId();
//  	__android_log_print(ANDROID_LOG_INFO, "Sometrik", "BomdDefender use id: %d", id);
  if (!id) {
    assert(0);
  }
    glUseProgram(id);
}

void
BombDefender::bind(const VBO & vbo) {
  if (vbo.hasVertexArrayObjects()) {
    assert(vbo.getVertexArrayId());
    glBindVertexArray(vbo.getVertexArrayId());
  } else {
    assert(vbo.getVertexBufferId() && vbo.getIndexBufferId());
    glBindBuffer(GL_ARRAY_BUFFER, vbo.getVertexBufferId());
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.getIndexBufferId());
    vbo.setPointers();
  }
}

std::shared_ptr<BombDefender> application;

void applicationMain(FWPlatformBase * platform) {
  application = std::make_shared<BombDefender>(platform);
  platform->setApplication(application.get());

}
<commit_msg>Add texture nullcheck<commit_after>#include "BombDefender.h"

#include <string.h>
#include <GLES3/gl3.h>
#include <jni.h>
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
#include <Context.h>
#include <AndroidPlatform.h>
#include <ContextAndroid.h>
#include <VBO.h>
#include <OpenGLTexture.h>

using namespace std;
using namespace gpufw;

std::shared_ptr<canvas::Context> context;
int positionX = 120;
int positionY = 120;
std::shared_ptr<canvas::Surface> yoSurface;
std::shared_ptr<canvas::OpenGLTexture> texture;

bool BombDefender::Init() {

  test_program = std::shared_ptr<gpufw::shader_program>(new gpufw::shader_program);

  test_program->loadShaders(getPlatform().getGLSLVersion(), "simple_sprite_shader.glsl");
  test_program->bindAttribLocation(0, "a_texCoord");
  test_program->bindAttribLocation(1, "a_position");
  test_program->link();

  auto contextF = getPlatform().createContextFactory();
   context = contextF->createContext(256, 256, canvas::InternalFormat::RGBA8, true);

   context->globalAlpha = 1.0f;
   context->font.size = 50;
   context->textBaseline = "top";
   yoSurface = context->createSurface("picture.jpg");
   context->drawImage(*yoSurface, 0, 0, 256, 256);

   texture = std::shared_ptr<canvas::OpenGLTexture>(new canvas::OpenGLTexture(context->getDefaultSurface()));
}

void BombDefender::onDraw() {

  if (texture.get() == NULL){
    	__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Texture is null");
  }

  Sprite sprite;
  drawSprite(sprite);
//  auto contextF = getPlatform().createContextFactory();
//  context = contextF->createContext(500, 500, canvas::InternalFormat::RGBA8, true);
//
//  context->globalAlpha = 1.0f;
//  context->font.size = 50;
//  context->textBaseline = "top";
//  yoSurface = context->createSurface("picture.jpg");
//
//  context->drawImage(*yoSurface, positionX, positionY, 200, 200);
//  positionX--;
//  positionY--;
//	__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Application ondraw");
//  dynamic_cast<AndroidPlatform&>(getPlatform()).showCanvas(dynamic_cast<canvas::ContextAndroid&>(*context));

}

void BombDefender::drawSprite(const Sprite & sprite){

  glm::mat4 projMat = glm::ortho(0.0f, 640.0f, 0.0f, 480.0f, -1000.0f, +1000.0f);
  glm::mat4 mat(1.0f);

  use(*test_program);
  test_program->setUniform("proj_mv_matrix", projMat * mat);
  test_program->setUniform("s_texture", 0);

  glDisable(GL_DEPTH_TEST);
  glDisable(GL_STENCIL_TEST);
  glDisable(GL_CULL_FACE);
  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  glDepthMask(GL_FALSE);

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texture->getTextureId());

  VBO vbo;
  vbo.quad2d(10.0f, 10.0f,
  	   500.0f, 10.0f,
  	   500.0f, 500.0f,
  	   10.0f, 500.0f);

  bind(vbo);

//	__android_log_print(ANDROID_LOG_INFO, "Sometrik", "BomdDefender texture id: %d", texture->getTextureId());
//	__android_log_print(ANDROID_LOG_INFO, "Sometrik", "BomdDefender IndexBufferId id: %d", vbo.getIndexBufferId());

  vbo.draw();

  glBindTexture(GL_TEXTURE_2D, 0);
}

void BombDefender::onShutdown() {
}

void
BombDefender::use(const gpufw::shader_program & program) {
  int id = program.getProgramObjectId();
//  	__android_log_print(ANDROID_LOG_INFO, "Sometrik", "BomdDefender use id: %d", id);
  if (!id) {
    assert(0);
  }
    glUseProgram(id);
}

void
BombDefender::bind(const VBO & vbo) {
  if (vbo.hasVertexArrayObjects()) {
    assert(vbo.getVertexArrayId());
    glBindVertexArray(vbo.getVertexArrayId());
  } else {
    assert(vbo.getVertexBufferId() && vbo.getIndexBufferId());
    glBindBuffer(GL_ARRAY_BUFFER, vbo.getVertexBufferId());
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.getIndexBufferId());
    vbo.setPointers();
  }
}

std::shared_ptr<BombDefender> application;

void applicationMain(FWPlatformBase * platform) {
  application = std::make_shared<BombDefender>(platform);
  platform->setApplication(application.get());

}
<|endoftext|>


<commit_before>#include "threads.h"
#include "console.h"
#include "memory.h"
#include "pen_string.h"
#include <pthread.h>

#include <fcntl.h>
#include <semaphore.h>
#include <unistd.h>

namespace pen
{
    typedef struct thread
    {
        pthread_t handle;
    } thread;

    typedef struct mutex
    {
        pthread_mutex_t handle;
    } mutex;

    typedef struct semaphore
    {
        sem_t* handle;
    } semaphore;

    u32 semaphone_index = 0;

    pen::thread* thread_create(PEN_THREAD_ROUTINE(thread_func), u32 stack_size, void* thread_params, thread_start_flags flags)
    {
        // allocate penthread handle
        pen::thread* new_thread = (pen::thread*)pen::memory_alloc(sizeof(pen::thread));

        // create the thread using posix
        pthread_attr_t attr;
        int            err;
        int            thread_err;

        err = pthread_attr_init(&attr);
        assert(!err);

        err = pthread_attr_setdetachstate(&attr, flags);
        assert(!err);

        thread_err = pthread_create(&new_thread->handle, &attr, thread_func, thread_params);

        err = pthread_attr_destroy(&attr);
        assert(!err);

        assert(!thread_err);

        return new_thread;
    }

    void thread_destroy(pen::thread* p_thread)
    {
        pthread_cancel(p_thread->handle);

        pen::memory_free(p_thread);
    }

    pen::mutex* thread_mutex_create()
    {
        pen::mutex* new_mutex = (pen::mutex*)pen::memory_alloc(sizeof(pen::mutex));

        int                 err;
        pthread_mutexattr_t mta;

        err = pthread_mutexattr_init(&mta);

        err = pthread_mutex_init(&new_mutex->handle, &mta);

        return new_mutex;
    }

    void thread_mutex_destroy(mutex* p_mutex)
    {
        pthread_mutex_destroy(&p_mutex->handle);

        pen::memory_free(p_mutex);
    }

    void thread_mutex_lock(mutex* p_mutex)
    {
        pthread_mutex_lock(&p_mutex->handle);
    }

    u32 thread_mutex_try_lock(mutex* p_mutex)
    {
        int err = pthread_mutex_trylock(&p_mutex->handle);

        return err == 0;
    }

    void thread_mutex_unlock(mutex* p_mutex)
    {
        pthread_mutex_unlock(&p_mutex->handle);
    }

    pen::semaphore* thread_semaphore_create(u32 initial_count, u32 max_count)
    {
        pen::semaphore* new_semaphore = (pen::semaphore*)pen::memory_alloc(sizeof(pen::semaphore));

        char name_buf[16];

        pen::string_format(&name_buf[0], 32, "sem%i", semaphone_index++);

        sem_unlink(name_buf);
        new_semaphore->handle = sem_open(name_buf, O_CREAT, 0, 0);

        assert(!(new_semaphore->handle == (void*)-1));

        return new_semaphore;
    }

    void thread_semaphore_destroy(semaphore* p_semaphore)
    {
        sem_close(p_semaphore->handle);

        pen::memory_free(p_semaphore);
    }

    bool thread_semaphore_wait(semaphore* p_semaphore)
    {
        sem_wait(p_semaphore->handle);

        return true;
    }

    bool thread_semaphore_try_wait(pen::semaphore* p_semaphore)
    {
        if (sem_trywait(p_semaphore->handle) == 0)
        {
            return true;
        }

        return false;
    }

    void thread_semaphore_signal(semaphore* p_semaphore, u32 count)
    {
        sem_post(p_semaphore->handle);
    }

    void thread_sleep_ms(u32 milliseconds)
    {
        usleep(milliseconds * 1000);
    }

    void thread_sleep_us(u32 microseconds)
    {
        usleep(microseconds);
    }
} // namespace pen
<commit_msg>change struct decls<commit_after>#include "threads.h"
#include "console.h"
#include "memory.h"
#include "pen_string.h"
#include <pthread.h>

#include <fcntl.h>
#include <semaphore.h>
#include <unistd.h>

namespace pen
{
    struct thread
    {
        pthread_t handle;
    };

    struct mutex
    {
        pthread_mutex_t handle;
    };

    struct semaphore
    {
        sem_t* handle;
    };

    u32 semaphone_index = 0;

    pen::thread* thread_create(PEN_THREAD_ROUTINE(thread_func), u32 stack_size, void* thread_params, thread_start_flags flags)
    {
        // allocate penthread handle
        pen::thread* new_thread = (pen::thread*)pen::memory_alloc(sizeof(pen::thread));

        // create the thread using posix
        pthread_attr_t attr;
        int            err;
        int            thread_err;

        err = pthread_attr_init(&attr);
        PEN_ASSERT(!err);

        err = pthread_attr_setdetachstate(&attr, flags);
        PEN_ASSERT(!err);

        thread_err = pthread_create(&new_thread->handle, &attr, thread_func, thread_params);

        err = pthread_attr_destroy(&attr);
        PEN_ASSERT(!err);

        PEN_ASSERT(!thread_err);

        return new_thread;
    }

    void thread_destroy(pen::thread* p_thread)
    {
        pthread_cancel(p_thread->handle);

        pen::memory_free(p_thread);
    }

    pen::mutex* thread_mutex_create()
    {
        pen::mutex* new_mutex = (pen::mutex*)pen::memory_alloc(sizeof(pen::mutex));

        int                 err;
        pthread_mutexattr_t mta;

        err = pthread_mutexattr_init(&mta);

        err = pthread_mutex_init(&new_mutex->handle, &mta);

        return new_mutex;
    }

    void thread_mutex_destroy(mutex* p_mutex)
    {
        pthread_mutex_destroy(&p_mutex->handle);

        pen::memory_free(p_mutex);
    }

    void thread_mutex_lock(mutex* p_mutex)
    {
        pthread_mutex_lock(&p_mutex->handle);
    }

    u32 thread_mutex_try_lock(mutex* p_mutex)
    {
        int err = pthread_mutex_trylock(&p_mutex->handle);

        return err == 0;
    }

    void thread_mutex_unlock(mutex* p_mutex)
    {
        pthread_mutex_unlock(&p_mutex->handle);
    }

    pen::semaphore* thread_semaphore_create(u32 initial_count, u32 max_count)
    {
        pen::semaphore* new_semaphore = (pen::semaphore*)pen::memory_alloc(sizeof(pen::semaphore));

        c8 name_buf[16];
        pen::string_format(&name_buf[0], 32, "sem%i", semaphone_index++);

        sem_unlink(name_buf);
        new_semaphore->handle = sem_open(name_buf, O_CREAT, 0, 0);

        assert(!(new_semaphore->handle == (void*)-1));

        return new_semaphore;
    }

    void thread_semaphore_destroy(semaphore* p_semaphore)
    {
        sem_close(p_semaphore->handle);
        pen::memory_free(p_semaphore);
    }

    bool thread_semaphore_wait(semaphore* p_semaphore)
    {
        sem_wait(p_semaphore->handle);

        return true;
    }

    bool thread_semaphore_try_wait(pen::semaphore* p_semaphore)
    {
        if (sem_trywait(p_semaphore->handle) == 0)
            return true;

        return false;
    }

    void thread_semaphore_signal(semaphore* p_semaphore, u32 count)
    {
        sem_post(p_semaphore->handle);
    }

    void thread_sleep_ms(u32 milliseconds)
    {
        usleep(milliseconds * 1000);
    }

    void thread_sleep_us(u32 microseconds)
    {
        usleep(microseconds);
    }
} // namespace pen
<|endoftext|>


<commit_before>/* ******************************************************************************
 *
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License, Version 2.0 which is available at
 * https://www.apache.org/licenses/LICENSE-2.0.
 *
 *  See the NOTICE file distributed with this work for additional
 *  information regarding copyright ownership.
 * 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.
 *
 * SPDX-License-Identifier: Apache-2.0
 ******************************************************************************/

//
// @author Yurii Shyrma (iuriish@yahoo.com), created on 04.06.2018
//

#include <ops/declarable/CustomOperations.h>
#include <ops/declarable/helpers/axis.h>
#include <ops/declarable/helpers/reductions.h>
#if NOT_EXCLUDED(OP_reduce_variance)
namespace sd    {
namespace ops     {

//////////////////////////////////////////////////////////////////////////
CUSTOM_OP_IMPL(reduce_variance, -1, 1, false, 0, 0) {
    auto input   = INPUT_VARIABLE(0);
    auto output  = OUTPUT_VARIABLE(0);

    bool keepDims      = false;//block.getTArguments()->size() > 0 ? (bool)T_ARG(0) : false;
    bool biasCorrected = false;//block.getTArguments()->size() > 1 ? (bool)T_ARG(1) : false;

    auto dimensions = *block.getIArguments();
    if (block.width() > 1) {
        auto axesVector = INPUT_VARIABLE(1);
        helpers::adjustAxis(input->rankOf(), axesVector, dimensions);
    }

    if (block.getBArguments()->size()) {
        keepDims = B_ARG(0);
        if (block.getBArguments()->size() > 1)
            biasCorrected = B_ARG(1);
    }
    else if (block.getTArguments()->size()) {
        keepDims = (bool)T_ARG(0);
        if (block.getTArguments()->size() > 1)
            biasCorrected = (bool)T_ARG(1);
    }

    REQUIRE_TRUE(dimensions.size() <= input->rankOf(), 0, "REDUCE_VARIANCE OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions)
        REQUIRE_TRUE(item >= -input->rankOf() && item < input->rankOf(), 0, "REDUCE_VARIANCE OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !" , input->rankOf(), input->rankOf(), item);

    sd::ops::helpers::variance(*input, *output, dimensions, biasCorrected);

    return Status::OK();
}

DECLARE_SHAPE_FN(reduce_variance) {

    bool keepDims      = false;//block.getTArguments()->size() > 0 ? (bool)T_ARG(0) : false;
    auto dimensions = *block.getIArguments();
    if (block.width() > 1) {
        auto axesVector = INPUT_VARIABLE(1);
        helpers::adjustAxis(INPUT_VARIABLE(0)->rankOf(), axesVector, dimensions);
    }

    if (block.getBArguments()->size()) {
        keepDims = B_ARG(0);
    }
    else if (block.getTArguments()->size()) {
        keepDims = (bool)T_ARG(0);
    }

    REQUIRE_TRUE(dimensions.size() <= INPUT_VARIABLE(0)->rankOf(), 0, "REDUCE_VARIANCE OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions)
        REQUIRE_TRUE(item >= -inputShape->at(0)[0] && item < inputShape->at(0)[0], 0, "REDUCE_VARIANCE OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !" , inputShape->at(0)[0], inputShape->at(0)[0], item);

    auto outShapeInfo = ShapeUtils::evalReduceShapeInfo(shape::order(inputShape->at(0)), dimensions, inputShape->at(0), keepDims, false, block.getWorkspace());

    return SHAPELIST(outShapeInfo);
}

DECLARE_TYPES(reduce_variance) {
    getOpDescriptor()
        ->setAllowedInputTypes(sd::DataType::ANY)
        ->setAllowedOutputTypes({ALL_FLOATS});
}

//////////////////////////////////////////////////////////////////////////
CUSTOM_OP_IMPL(reduce_variance_bp, -1, 1, false, 0, 0) {
    auto input  = INPUT_VARIABLE(0);
    auto gradO  = INPUT_VARIABLE(1);

    auto gradI  = OUTPUT_VARIABLE(0);

    bool keepDims      = false;//block.getTArguments()->size() > 0 ? (bool)T_ARG(0) : false;
    bool biasCorrected = false;//block.getTArguments()->size() > 1 ? (bool)T_ARG(1) : false;

    auto dimensions = *block.getIArguments();
    if (block.width() > 2) {
        auto axesVector = INPUT_VARIABLE(2);
        helpers::adjustAxis(input->rankOf(), axesVector, dimensions);
        nd4j_debug("Shape of axes vector for reduce_variance_bp %d\n",0);
        axesVector->printShapeInfo();
    }

    if (block.getBArguments()->size()) {
        keepDims = B_ARG(0);
        if (block.getBArguments()->size() > 1)
            biasCorrected = B_ARG(1);
    }
    else if (block.getTArguments()->size()) {
        keepDims = (bool)T_ARG(0);
        if (block.getTArguments()->size() > 1)
            biasCorrected = (bool)T_ARG(1);
    }

    REQUIRE_TRUE(dimensions.size() <= input->rankOf(), 0, "REDUCE_VARIANCE_BP OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions) {
        REQUIRE_TRUE(item >= -input->rankOf() && item < input->rankOf(), 0,
                     "REDUCE_VARIANCE_BP OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !",
                     input->rankOf(), input->rankOf(), item);
        nd4j_debug("Dimension item is %d\n",item);
    }

    const Nd4jLong N = input->lengthOf() / gradO->lengthOf();
    const Nd4jLong NminusOne = biasCorrected ? N - 1 : N;
    const double factor1 = 2.0 / NminusOne;
    const double factor2 = 2.0 / (N * NminusOne);
    nd4j_debug("Before mean in variance bp %d\n",0);
    auto mean = input->reduceAlongDimension(reduce::Mean, dimensions, true);
    nd4j_debug("After mean in variance bp %d\n",0);

    gradI->assign( (*input - mean) * (2.0f / NminusOne));                                    // automatic broadcasting happens here
    nd4j_debug("After assign in variance bp %d\n",0);

    if(!keepDims) {
        nd4j_debug("In not keep dims reduce variance bp %d\n",0);
        auto gradOShapeKeepDims = ShapeUtils::evalReduceShapeInfo(gradO->ordering(), dimensions, *input, true, false, block.getWorkspace());
        *gradI *= gradO->reshape(gradO->ordering(), ShapeUtils::pullShapeFromShapeInfo(gradOShapeKeepDims));  // for example could be something like [a,b] -> [1,a,1,b]
        nd4j_debug("After not keep dims reduce variance bp %d\n",0);

    } else
        *gradI *= *gradO;           // automatic broadcasting happens here

    return Status::OK();
}

DECLARE_SHAPE_FN(reduce_variance_bp) {
    auto in = inputShape->at(0);
    auto rank = shape::rank(in);
    auto dimensions = *block.getIArguments();
    if (block.width() > 2) {
        auto axesVector = INPUT_VARIABLE(2);
        helpers::adjustAxis(rank, axesVector, dimensions);
    }

    REQUIRE_TRUE(dimensions.size() <= rank, 0, "REDUCE_VARIANCE_BP OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions)
        REQUIRE_TRUE(item >= -inputShape->at(0)[0] && item < inputShape->at(0)[0], 0, "REDUCE_VARIANCE_BP OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !" , inputShape->at(0)[0], inputShape->at(0)[0], item);

    Nd4jLong* gradIshapeInfo(nullptr);
    COPY_SHAPE(in, gradIshapeInfo);

    return SHAPELIST(CONSTANT(gradIshapeInfo));
}

DECLARE_TYPES(reduce_variance_bp) {
    getOpDescriptor()
        ->setAllowedInputTypes(sd::DataType::ANY)
        ->setAllowedOutputTypes({ALL_FLOATS});
}

}
}
#endif
<commit_msg>Remove debug statements<commit_after>/* ******************************************************************************
 *
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License, Version 2.0 which is available at
 * https://www.apache.org/licenses/LICENSE-2.0.
 *
 *  See the NOTICE file distributed with this work for additional
 *  information regarding copyright ownership.
 * 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.
 *
 * SPDX-License-Identifier: Apache-2.0
 ******************************************************************************/

//
// @author Yurii Shyrma (iuriish@yahoo.com), created on 04.06.2018
//

#include <ops/declarable/CustomOperations.h>
#include <ops/declarable/helpers/axis.h>
#include <ops/declarable/helpers/reductions.h>
#if NOT_EXCLUDED(OP_reduce_variance)
namespace sd    {
namespace ops     {

//////////////////////////////////////////////////////////////////////////
CUSTOM_OP_IMPL(reduce_variance, -1, 1, false, 0, 0) {
    auto input   = INPUT_VARIABLE(0);
    auto output  = OUTPUT_VARIABLE(0);

    bool keepDims      = false;//block.getTArguments()->size() > 0 ? (bool)T_ARG(0) : false;
    bool biasCorrected = false;//block.getTArguments()->size() > 1 ? (bool)T_ARG(1) : false;

    auto dimensions = *block.getIArguments();
    if (block.width() > 1) {
        auto axesVector = INPUT_VARIABLE(1);
        helpers::adjustAxis(input->rankOf(), axesVector, dimensions);
    }

    if (block.getBArguments()->size()) {
        keepDims = B_ARG(0);
        if (block.getBArguments()->size() > 1)
            biasCorrected = B_ARG(1);
    }
    else if (block.getTArguments()->size()) {
        keepDims = (bool)T_ARG(0);
        if (block.getTArguments()->size() > 1)
            biasCorrected = (bool)T_ARG(1);
    }

    REQUIRE_TRUE(dimensions.size() <= input->rankOf(), 0, "REDUCE_VARIANCE OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions)
        REQUIRE_TRUE(item >= -input->rankOf() && item < input->rankOf(), 0, "REDUCE_VARIANCE OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !" , input->rankOf(), input->rankOf(), item);

    sd::ops::helpers::variance(*input, *output, dimensions, biasCorrected);

    return Status::OK();
}

DECLARE_SHAPE_FN(reduce_variance) {

    bool keepDims      = false;//block.getTArguments()->size() > 0 ? (bool)T_ARG(0) : false;
    auto dimensions = *block.getIArguments();
    if (block.width() > 1) {
        auto axesVector = INPUT_VARIABLE(1);
        helpers::adjustAxis(INPUT_VARIABLE(0)->rankOf(), axesVector, dimensions);
    }

    if (block.getBArguments()->size()) {
        keepDims = B_ARG(0);
    }
    else if (block.getTArguments()->size()) {
        keepDims = (bool)T_ARG(0);
    }

    REQUIRE_TRUE(dimensions.size() <= INPUT_VARIABLE(0)->rankOf(), 0, "REDUCE_VARIANCE OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions)
        REQUIRE_TRUE(item >= -inputShape->at(0)[0] && item < inputShape->at(0)[0], 0, "REDUCE_VARIANCE OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !" , inputShape->at(0)[0], inputShape->at(0)[0], item);

    auto outShapeInfo = ShapeUtils::evalReduceShapeInfo(shape::order(inputShape->at(0)), dimensions, inputShape->at(0), keepDims, false, block.getWorkspace());

    return SHAPELIST(outShapeInfo);
}

DECLARE_TYPES(reduce_variance) {
    getOpDescriptor()
        ->setAllowedInputTypes(sd::DataType::ANY)
        ->setAllowedOutputTypes({ALL_FLOATS});
}

//////////////////////////////////////////////////////////////////////////
CUSTOM_OP_IMPL(reduce_variance_bp, -1, 1, false, 0, 0) {
    auto input  = INPUT_VARIABLE(0);
    auto gradO  = INPUT_VARIABLE(1);

    auto gradI  = OUTPUT_VARIABLE(0);

    bool keepDims      = false;//block.getTArguments()->size() > 0 ? (bool)T_ARG(0) : false;
    bool biasCorrected = false;//block.getTArguments()->size() > 1 ? (bool)T_ARG(1) : false;

    auto dimensions = *block.getIArguments();
    if (block.width() > 2) {
        auto axesVector = INPUT_VARIABLE(2);
        helpers::adjustAxis(input->rankOf(), axesVector, dimensions);
        axesVector->printShapeInfo();
    }

    if (block.getBArguments()->size()) {
        keepDims = B_ARG(0);
        if (block.getBArguments()->size() > 1)
            biasCorrected = B_ARG(1);
    }
    else if (block.getTArguments()->size()) {
        keepDims = (bool)T_ARG(0);
        if (block.getTArguments()->size() > 1)
            biasCorrected = (bool)T_ARG(1);
    }

    REQUIRE_TRUE(dimensions.size() <= input->rankOf(), 0, "REDUCE_VARIANCE_BP OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions) {
        REQUIRE_TRUE(item >= -input->rankOf() && item < input->rankOf(), 0,
                     "REDUCE_VARIANCE_BP OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !",
                     input->rankOf(), input->rankOf(), item);
        nd4j_debug("Dimension item is %d\n",item);
    }

    const Nd4jLong N = input->lengthOf() / gradO->lengthOf();
    const Nd4jLong NminusOne = biasCorrected ? N - 1 : N;
    const double factor1 = 2.0 / NminusOne;
    const double factor2 = 2.0 / (N * NminusOne);
    auto mean = input->reduceAlongDimension(reduce::Mean, dimensions, true);

    gradI->assign( (*input - mean) * (2.0f / NminusOne));                                    // automatic broadcasting happens here

    if(!keepDims) {
        auto gradOShapeKeepDims = ShapeUtils::evalReduceShapeInfo(gradO->ordering(), dimensions, *input, true, false, block.getWorkspace());
        *gradI *= gradO->reshape(gradO->ordering(), ShapeUtils::pullShapeFromShapeInfo(gradOShapeKeepDims));  // for example could be something like [a,b] -> [1,a,1,b]

    } else
        *gradI *= *gradO;           // automatic broadcasting happens here

    return Status::OK();
}

DECLARE_SHAPE_FN(reduce_variance_bp) {
    auto in = inputShape->at(0);
    auto rank = shape::rank(in);
    auto dimensions = *block.getIArguments();
    if (block.width() > 2) {
        auto axesVector = INPUT_VARIABLE(2);
        helpers::adjustAxis(rank, axesVector, dimensions);
    }

    REQUIRE_TRUE(dimensions.size() <= rank, 0, "REDUCE_VARIANCE_BP OP: the number of dimensions to reduce along must be <= input array rank, but got %i instead" , dimensions.size());

    for(const auto& item : dimensions)
        REQUIRE_TRUE(item >= -inputShape->at(0)[0] && item < inputShape->at(0)[0], 0, "REDUCE_VARIANCE_BP OP: the input dimension to reduce along must be in range [-%i, %i), but got %i instead !" , inputShape->at(0)[0], inputShape->at(0)[0], item);

    Nd4jLong* gradIshapeInfo(nullptr);
    COPY_SHAPE(in, gradIshapeInfo);

    return SHAPELIST(CONSTANT(gradIshapeInfo));
}

DECLARE_TYPES(reduce_variance_bp) {
    getOpDescriptor()
        ->setAllowedInputTypes(sd::DataType::ANY)
        ->setAllowedOutputTypes({ALL_FLOATS});
}

}
}
#endif
<|endoftext|>


<commit_before>#ifndef ROADNET_H
#define ROADNET_H

#include <string>
#include <vector>
#include <iostream>
#include <cassert>

#include <Eigen/Dense>

/** Road network description

   This class serves a similar purpose to the class RoadNetwork in
   dubins_traffic.py of the fmrb Python package. However, this is considered the
   reference implementation.

   \ingroup dubins_traffic
 */
class RoadNetwork
{
public:
    /** Create RoadNetwork that is 4-connected grid of size (shape0, shape1). */
    RoadNetwork( double length_,
                 const Eigen::Vector3d &transform_,
                 int shape0, int shape1 );

    /** Create RoadNetwork from a description in a JSON container.

        segments is not yet implemented. Thus, until then, it is only possible
        to define a 4-connected grid using shape.
     */
    RoadNetwork( std::istream &rndjson );

    /** Output in RND format using JSON container to given stream. */
    friend std::ostream & operator<<( std::ostream &out, const RoadNetwork &rd );

private:
    void populate_4grid( int shape0, int shape1 );

private:
    int version;
    double length;
    Eigen::Vector3d transform;
    std::vector<Eigen::Vector4d> segments;
    std::vector<int> shape;
};

void RoadNetwork::populate_4grid( int shape0, int shape1 )
{
    assert( shape0 >= 1 && shape1 >= 1 );
    for (int x = 0; x < shape1-1; x++) {
        for (int y = 0; y < shape0-1; y++) {
            segments.push_back( Eigen::Vector4d( x, y, x+1, y ) );
            segments.push_back( Eigen::Vector4d( x, y, x, y+1 ) );
        }
    }
    for (int x = 0; x < shape1-1; x++)
        segments.push_back( Eigen::Vector4d( x, shape0-1, x+1, shape0-1 ) );
    for (int y = 0; y < shape0-1; y++)
        segments.push_back( Eigen::Vector4d( shape1-1, y, shape1-1, y+1 ) );
}

RoadNetwork::RoadNetwork( double length_,
                          const Eigen::Vector3d &transform_,
                          int shape0, int shape1 )
    : version(0), length(length_), transform(transform_),
      shape( {shape0, shape1} )
{
    assert( length > 0 );
    populate_4grid( shape0, shape1 );
}

RoadNetwork::RoadNetwork( std::istream &rndjson )
    : version(-1), length(1.0), transform(0.0, 0.0, 0.0),
      shape( {2, 2} )
{
    enum state {waiting, rd_version, rd_length, rd_transform, rd_segments, rd_shape};
    state parser = waiting;
    std::string buf;
    std::string rndjson_str;
    rndjson >> buf;
    while (!rndjson.eof()) {
        rndjson_str.append( buf );
        rndjson >> buf;
    }

    size_t pos = 0, nextpos;
    while (pos < rndjson_str.size()) {
        if (parser == waiting) {
            if ((nextpos = rndjson_str.find( "version", pos )) != std::string::npos) {
                parser = rd_version;
                pos = nextpos + 7;
            } else if ((nextpos = rndjson_str.find( "length", pos )) != std::string::npos) {
                parser = rd_length;
                pos = nextpos + 6;
            } else if ((nextpos = rndjson_str.find( "transform", pos )) != std::string::npos) {
                parser = rd_transform;
                pos = nextpos + 9;
            } else if ((nextpos = rndjson_str.find( "shape", pos )) != std::string::npos) {
                parser = rd_shape;
                pos = nextpos + 5;
            } else {
                break;
            }

        } else if (parser == rd_version || parser == rd_length) {
            if ((nextpos = rndjson_str.find( ":", pos )) != std::string::npos) {
                pos = nextpos + 1;
                try {
                    int parsed_int = std::stoi( rndjson_str.substr( pos ) );
                    switch (parser) {
                    case rd_version:
                        version = parsed_int;
                        break;
                    case rd_length:
                        length = parsed_int;
                        break;
                    }
                } catch (std::invalid_argument) {
                    std::cout << "stoi() conversion failed on \""
                              << rndjson_str.substr( pos ) << "\"" << std::endl;
                }
                parser = waiting;
            } else {
                break;
            }

        } else if (parser == rd_transform || parser == rd_shape) {
            std::vector<double> parsed_numbers;
            if ((nextpos = rndjson_str.find( "[", pos )) != std::string::npos) {
                pos = nextpos + 1;
                while (true) {
                    try {
                        parsed_numbers.push_back( std::stod( rndjson_str.substr( pos ) ) );
                    } catch (std::invalid_argument) {
                        std::cout << "stod() conversion failed on \""
                                  << rndjson_str.substr( pos ) << "\"" << std::endl;
                    }

                    size_t closingpos = rndjson_str.find( "]", pos );
                    nextpos = rndjson_str.find( ",", pos );
                    if (closingpos == std::string::npos) {
                        break;  // Missing ] implies malformed array.
                    } else if (nextpos != std::string::npos && nextpos < closingpos) {
                        pos = nextpos + 1;
                    } else {
                        pos = closingpos + 1;
                        break;  // Found closing ] implies well-formed array.
                    }
                }

                switch (parser) {
                case rd_transform:
                    assert( parsed_numbers.size() == 3 );
                    for (int idx = 0; idx < parsed_numbers.size(); idx++)
                        transform(idx) = parsed_numbers.at(idx);
                    break;
                case rd_shape:
                    assert( parsed_numbers.size() == 2 );
                    for (int idx = 0; idx < parsed_numbers.size(); idx++)
                        shape[idx] = parsed_numbers.at(idx);
                    break;
                }

                parser = waiting;
            } else {
                break;
            }

        } else {
            break;
        }
    }
}

std::ostream & operator<<( std::ostream &out, const RoadNetwork &rd )
{
    out << "{ \"version\": " << rd.version << ", ";
    out << "\"length\": " << rd.length << ", ";
    out << "\"transform\": ["
        << rd.transform(0) << ", " << rd.transform(1) << ", " << rd.transform(2)
        << "], ";
    out << "\"shape\": [" << rd.shape[0] << ", " << rd.shape[1] << "], ";
    out << "\"segments\": [";
    for (int segment_index = 0; segment_index < rd.segments.size(); segment_index++) {
        out << "[";
        for (int idx = 0; idx < 4; idx++) {
            out << rd.segments[segment_index](idx);
            if (idx < 3)
                out << ", ";
        }
        out << "]";
        if (segment_index < rd.segments.size()-1)
            out << ", ";
    }
    out << "] }";
}

#endif
<commit_msg>Populate segments as 4-grid in constructor using JSON str<commit_after>#ifndef ROADNET_H
#define ROADNET_H

#include <string>
#include <vector>
#include <iostream>
#include <cassert>

#include <Eigen/Dense>

/** Road network description

   This class serves a similar purpose to the class RoadNetwork in
   dubins_traffic.py of the fmrb Python package. However, this is considered the
   reference implementation.

   \ingroup dubins_traffic
 */
class RoadNetwork
{
public:
    /** Create RoadNetwork that is 4-connected grid of size (shape0, shape1). */
    RoadNetwork( double length_,
                 const Eigen::Vector3d &transform_,
                 int shape0, int shape1 );

    /** Create RoadNetwork from a description in a JSON container.

        segments is not yet implemented. Thus, until then, it is only possible
        to define a 4-connected grid using shape.
     */
    RoadNetwork( std::istream &rndjson );

    /** Output in RND format using JSON container to given stream. */
    friend std::ostream & operator<<( std::ostream &out, const RoadNetwork &rd );

private:
    void populate_4grid( int shape0, int shape1 );

private:
    int version;
    double length;
    Eigen::Vector3d transform;
    std::vector<Eigen::Vector4d> segments;
    std::vector<int> shape;
};

void RoadNetwork::populate_4grid( int shape0, int shape1 )
{
    assert( shape0 >= 1 && shape1 >= 1 );
    for (int x = 0; x < shape1-1; x++) {
        for (int y = 0; y < shape0-1; y++) {
            segments.push_back( Eigen::Vector4d( x, y, x+1, y ) );
            segments.push_back( Eigen::Vector4d( x, y, x, y+1 ) );
        }
    }
    for (int x = 0; x < shape1-1; x++)
        segments.push_back( Eigen::Vector4d( x, shape0-1, x+1, shape0-1 ) );
    for (int y = 0; y < shape0-1; y++)
        segments.push_back( Eigen::Vector4d( shape1-1, y, shape1-1, y+1 ) );
}

RoadNetwork::RoadNetwork( double length_,
                          const Eigen::Vector3d &transform_,
                          int shape0, int shape1 )
    : version(0), length(length_), transform(transform_),
      shape( {shape0, shape1} )
{
    assert( length > 0 );
    populate_4grid( shape0, shape1 );
}

RoadNetwork::RoadNetwork( std::istream &rndjson )
    : version(-1), length(1.0), transform(0.0, 0.0, 0.0),
      shape( {2, 2} )
{
    enum state {waiting, rd_version, rd_length, rd_transform, rd_segments, rd_shape};
    state parser = waiting;
    std::string buf;
    std::string rndjson_str;
    rndjson >> buf;
    while (!rndjson.eof()) {
        rndjson_str.append( buf );
        rndjson >> buf;
    }

    size_t pos = 0, nextpos;
    while (pos < rndjson_str.size()) {
        if (parser == waiting) {
            if ((nextpos = rndjson_str.find( "version", pos )) != std::string::npos) {
                parser = rd_version;
                pos = nextpos + 7;
            } else if ((nextpos = rndjson_str.find( "length", pos )) != std::string::npos) {
                parser = rd_length;
                pos = nextpos + 6;
            } else if ((nextpos = rndjson_str.find( "transform", pos )) != std::string::npos) {
                parser = rd_transform;
                pos = nextpos + 9;
            } else if ((nextpos = rndjson_str.find( "shape", pos )) != std::string::npos) {
                parser = rd_shape;
                pos = nextpos + 5;
            } else {
                break;
            }

        } else if (parser == rd_version || parser == rd_length) {
            if ((nextpos = rndjson_str.find( ":", pos )) != std::string::npos) {
                pos = nextpos + 1;
                try {
                    int parsed_int = std::stoi( rndjson_str.substr( pos ) );
                    switch (parser) {
                    case rd_version:
                        version = parsed_int;
                        break;
                    case rd_length:
                        length = parsed_int;
                        break;
                    }
                } catch (std::invalid_argument) {
                    std::cout << "stoi() conversion failed on \""
                              << rndjson_str.substr( pos ) << "\"" << std::endl;
                }
                parser = waiting;
            } else {
                break;
            }

        } else if (parser == rd_transform || parser == rd_shape) {
            std::vector<double> parsed_numbers;
            if ((nextpos = rndjson_str.find( "[", pos )) != std::string::npos) {
                pos = nextpos + 1;
                while (true) {
                    try {
                        parsed_numbers.push_back( std::stod( rndjson_str.substr( pos ) ) );
                    } catch (std::invalid_argument) {
                        std::cout << "stod() conversion failed on \""
                                  << rndjson_str.substr( pos ) << "\"" << std::endl;
                    }

                    size_t closingpos = rndjson_str.find( "]", pos );
                    nextpos = rndjson_str.find( ",", pos );
                    if (closingpos == std::string::npos) {
                        break;  // Missing ] implies malformed array.
                    } else if (nextpos != std::string::npos && nextpos < closingpos) {
                        pos = nextpos + 1;
                    } else {
                        pos = closingpos + 1;
                        break;  // Found closing ] implies well-formed array.
                    }
                }

                switch (parser) {
                case rd_transform:
                    assert( parsed_numbers.size() == 3 );
                    for (int idx = 0; idx < parsed_numbers.size(); idx++)
                        transform(idx) = parsed_numbers.at(idx);
                    break;
                case rd_shape:
                    assert( parsed_numbers.size() == 2 );
                    for (int idx = 0; idx < parsed_numbers.size(); idx++)
                        shape[idx] = parsed_numbers.at(idx);
                    break;
                }

                parser = waiting;
            } else {
                break;
            }

        } else {
            break;
        }
    }

    assert( length > 0 );
    populate_4grid( shape[0], shape[1] );
}

std::ostream & operator<<( std::ostream &out, const RoadNetwork &rd )
{
    out << "{ \"version\": " << rd.version << ", ";
    out << "\"length\": " << rd.length << ", ";
    out << "\"transform\": ["
        << rd.transform(0) << ", " << rd.transform(1) << ", " << rd.transform(2)
        << "], ";
    out << "\"shape\": [" << rd.shape[0] << ", " << rd.shape[1] << "], ";
    out << "\"segments\": [";
    for (int segment_index = 0; segment_index < rd.segments.size(); segment_index++) {
        out << "[";
        for (int idx = 0; idx < 4; idx++) {
            out << rd.segments[segment_index](idx);
            if (idx < 3)
                out << ", ";
        }
        out << "]";
        if (segment_index < rd.segments.size()-1)
            out << ", ";
    }
    out << "] }";
}

#endif
<|endoftext|>