<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief arango benchmark tool
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Basics/Common.h"

#include "ArangoShell/ArangoClient.h"
#include "Basics/Mutex.h"
#include "Basics/MutexLocker.h"
#include "Basics/ProgramOptions.h"
#include "Basics/ProgramOptionsDescription.h"
#include "Basics/StringUtils.h"
#include "Basics/init.h"
#include "Basics/logging.h"
#include "Basics/random.h"
#include "Basics/tri-strings.h"
#include "Basics/string-buffer.h"
#include "Basics/terminal-utils.h"
#include "Rest/Endpoint.h"
#include "Rest/HttpRequest.h"
#include "Rest/InitialiseRest.h"
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include "Benchmark/BenchmarkCounter.h"
#include "Benchmark/BenchmarkOperation.h"
#include "Benchmark/BenchmarkThread.h"

using namespace std;
using namespace triagens::basics;
using namespace triagens::httpclient;
using namespace triagens::rest;
using namespace triagens::arango;
using namespace triagens::arangob;

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief base class for clients
////////////////////////////////////////////////////////////////////////////////

ArangoClient BaseClient("arangob");

////////////////////////////////////////////////////////////////////////////////
/// @brief started counter
////////////////////////////////////////////////////////////////////////////////

static atomic<int> Started;

////////////////////////////////////////////////////////////////////////////////
/// @brief mutex for start counter
////////////////////////////////////////////////////////////////////////////////

Mutex StartMutex;

////////////////////////////////////////////////////////////////////////////////
/// @brief send asychronous requests
////////////////////////////////////////////////////////////////////////////////

static bool Async = false;

////////////////////////////////////////////////////////////////////////////////
/// @brief number of operations in one batch
////////////////////////////////////////////////////////////////////////////////

static int BatchSize = 0;

////////////////////////////////////////////////////////////////////////////////
/// @brief collection to use
////////////////////////////////////////////////////////////////////////////////

static string Collection = "ArangoBenchmark";

////////////////////////////////////////////////////////////////////////////////
/// @brief complexity parameter for tests
////////////////////////////////////////////////////////////////////////////////

static uint64_t Complexity = 1;

////////////////////////////////////////////////////////////////////////////////
/// @brief concurrency
////////////////////////////////////////////////////////////////////////////////

static int Concurrency = 1;

////////////////////////////////////////////////////////////////////////////////
/// @brief use a startup delay
////////////////////////////////////////////////////////////////////////////////

static bool Delay = false;

////////////////////////////////////////////////////////////////////////////////
/// @brief use HTTP keep-alive
////////////////////////////////////////////////////////////////////////////////

static bool KeepAlive = true;

////////////////////////////////////////////////////////////////////////////////
/// @brief number of operations to perform
////////////////////////////////////////////////////////////////////////////////

static int Operations = 1000;

////////////////////////////////////////////////////////////////////////////////
/// @brief display progress
////////////////////////////////////////////////////////////////////////////////

static bool Progress = true;

////////////////////////////////////////////////////////////////////////////////
/// @brief test case to use
////////////////////////////////////////////////////////////////////////////////

static string TestCase = "version";

////////////////////////////////////////////////////////////////////////////////
/// @brief print out replies on error
////////////////////////////////////////////////////////////////////////////////

static bool verbose = false;

////////////////////////////////////////////////////////////////////////////////
/// @brief includes all the test cases
////////////////////////////////////////////////////////////////////////////////

#include "Benchmark/test-cases.h"

// -----------------------------------------------------------------------------
// --SECTION--                                                 private functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief update the number of ready threads. this is a callback function
/// that is called by each thread after it is created
////////////////////////////////////////////////////////////////////////////////

static void UpdateStartCounter () {
  ++Started;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get the value of the number of started threads counter
////////////////////////////////////////////////////////////////////////////////

static int GetStartCounter () {
  return Started;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief print a status line (if ! quiet)
////////////////////////////////////////////////////////////////////////////////

static void Status (const string& value) {
  if (! BaseClient.quiet()) {
    cout << value << endl;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parses the program options
////////////////////////////////////////////////////////////////////////////////

static void ParseProgramOptions (int argc, char* argv[]) {
  ProgramOptionsDescription description("STANDARD options");

  description
    ("async", &Async, "send asychronous requests")
    ("concurrency", &Concurrency, "number of parallel connections")
    ("requests", &Operations, "total number of operations")
    ("batch-size", &BatchSize, "number of operations in one batch (0 disables batching)")
    ("keep-alive", &KeepAlive, "use HTTP keep-alive")
    ("collection", &Collection, "collection name to use in tests")
    ("test-case", &TestCase, "test case to use (possible values: version, document, collection, import-document, hash, skiplist, edge, shapes, shapes-append, random-shapes, crud, crud-append, crud-write-read, aqltrx, counttrx, multitrx, multi-collection, aqlinsert)")
    ("complexity", &Complexity, "complexity parameter for the test")
    ("delay", &Delay, "use a startup delay (necessary only when run in series)")
    ("progress", &Progress, "show progress")
    ("verbose", &verbose, "print out replies if the http-header indicates db-errors")
  ;

  BaseClient.setupGeneral(description);
  BaseClient.setupServer(description);

  vector<string> arguments;
  description.arguments(&arguments);

  ProgramOptions options;
  BaseClient.parse(options, description, "--concurrency <concurrency> --requests <request> --test-case <case> ...", argc, argv, "arangob.conf");
}

// -----------------------------------------------------------------------------
// --SECTION--                                                  public functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief startup and exit functions
////////////////////////////////////////////////////////////////////////////////

static void arangobEntryFunction ();
static void arangobExitFunction (int, void*);

#ifdef _WIN32

// .............................................................................
// Call this function to do various initialisations for windows only
// .............................................................................

void arangobEntryFunction () {
  int maxOpenFiles = 1024;
  int res = 0;

  // ...........................................................................
  // Uncomment this to call this for extended debug information.
  // If you familiar with valgrind ... then this is not like that, however
  // you do get some similar functionality.
  // ...........................................................................
  //res = initialiseWindows(TRI_WIN_INITIAL_SET_DEBUG_FLAG, 0);

  res = initialiseWindows(TRI_WIN_INITIAL_SET_INVALID_HANLE_HANDLER, 0);
  if (res != 0) {
    _exit(1);
  }

  res = initialiseWindows(TRI_WIN_INITIAL_SET_MAX_STD_IO,(const char*)(&maxOpenFiles));
  if (res != 0) {
    _exit(1);
  }

  res = initialiseWindows(TRI_WIN_INITIAL_WSASTARTUP_FUNCTION_CALL, 0);
  if (res != 0) {
    _exit(1);
  }

  TRI_Application_Exit_SetExit(arangobExitFunction);
}

static void arangobExitFunction (int exitCode, void* data) {
  int res = 0;
  // ...........................................................................
  // TODO: need a terminate function for windows to be called and cleanup
  // any windows specific stuff.
  // ...........................................................................

  res = finaliseWindows(TRI_WIN_FINAL_WSASTARTUP_FUNCTION_CALL, 0);

  if (res != 0) {
    exit(1);
  }

  exit(exitCode);
}
#else

static void arangobEntryFunction () {
}

static void arangobExitFunction (int exitCode, void* data) {
}

#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief main
////////////////////////////////////////////////////////////////////////////////

int main (int argc, char* argv[]) {
  int ret = EXIT_SUCCESS;

  arangobEntryFunction();

  TRIAGENS_C_INITIALISE(argc, argv);
  TRIAGENS_REST_INITIALISE(argc, argv);

  TRI_InitialiseLogging(false);

  BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

  // .............................................................................
  // parse the program options
  // .............................................................................

  ParseProgramOptions(argc, argv);

  // .............................................................................
  // set-up client connection
  // .............................................................................

  BaseClient.createEndpoint();

  if (BaseClient.endpointServer() == nullptr) {
    LOG_FATAL_AND_EXIT("invalid value for --server.endpoint ('%s')", BaseClient.endpointString().c_str());
  }

  BenchmarkOperation* testCase = GetTestCase(TestCase);

  if (testCase == nullptr) {
    LOG_FATAL_AND_EXIT("invalid test case name '%s'", TestCase.c_str());
    return EXIT_FAILURE; // will not be reached
  }

  Status("starting threads...");

  BenchmarkCounter<unsigned long> operationsCounter(0, (unsigned long) Operations);
  ConditionVariable startCondition;

  vector<Endpoint*> endpoints;
  vector<BenchmarkThread*> threads;

  const double stepSize = (double) Operations / (double) Concurrency;
  int64_t realStep = (int64_t) stepSize;
  if (stepSize - (double) ((int64_t) stepSize) > 0.0) {
    realStep++;
  }
  if (realStep % 1000 != 0) {
    realStep += 1000 - (realStep % 1000);
  }
  // add some more offset so we don't get into trouble with threads of different speed
  realStep += 10000;

  // start client threads
  for (int i = 0; i < Concurrency; ++i) {
    Endpoint* endpoint = Endpoint::clientFactory(BaseClient.endpointString());
    endpoints.push_back(endpoint);

    BenchmarkThread* thread = new BenchmarkThread(testCase,
        &startCondition,
        &UpdateStartCounter,
        i,
        (unsigned long) BatchSize,
        &operationsCounter,
        endpoint,
        BaseClient.databaseName(),
        BaseClient.username(),
        BaseClient.password(),
        BaseClient.requestTimeout(),
        BaseClient.connectTimeout(),
        BaseClient.sslProtocol(),
        KeepAlive,
        Async,
        verbose);

    threads.push_back(thread);
    thread->setOffset((size_t) (i * realStep));
    thread->start();
  }

  // give all threads a chance to start so they will not miss the broadcast
  while (GetStartCounter() < Concurrency) {
    usleep(5000);
  }

  if (Delay) {
    Status("sleeping (startup delay)...");
    sleep(10);
  }
  Status("executing tests...");

  double start = TRI_microtime();

  // broadcast the start signal to all threads
  {
    ConditionLocker guard(&startCondition);
    guard.broadcast();
  }

  const size_t stepValue = (Operations / 20);
  size_t nextReportValue = stepValue;

  if (nextReportValue < 100) {
    nextReportValue = 100;
  }

  while (1) {
    const size_t numOperations = operationsCounter.getDone();

    if (numOperations >= (size_t) Operations) {
      break;
    }

    if (Progress && numOperations >= nextReportValue) {
      LOG_INFO("number of operations: %d", (int) nextReportValue);
      nextReportValue += stepValue;
    }

    usleep(20000);
  }

  double time = TRI_microtime() - start;
  double requestTime = 0.0;

  for (int i = 0; i < Concurrency; ++i) {
    requestTime += threads[i]->getTime();
  }

  size_t failures = operationsCounter.failures();
  size_t incomplete = operationsCounter.incompleteFailures();

  cout << endl;
  cout << "Total number of operations: " << Operations <<
          ", keep alive: " << (KeepAlive ? "yes" : "no") <<
          ", async: " << (Async ? "yes" : "no")  <<
          ", batch size: " << BatchSize <<
          ", concurrency level (threads): " << Concurrency <<
          endl;

  cout << "Test case: " << TestCase <<
          ", complexity: " << Complexity <<
          ", database: '" << BaseClient.databaseName() <<
          "', collection: '" << Collection << "'" <<
          endl;

  cout << "Total request/response duration (sum of all threads): " << fixed << requestTime << " s" << endl;
  cout << "Request/response duration (per thread): " << fixed << (requestTime / (double) Concurrency) << " s" << endl;
  cout << "Time needed per operation: " << fixed << (time / Operations) << " s" << endl;
  cout << "Time needed per operation per thread: " << fixed << (time / (double) Operations * (double) Concurrency) << " s" << endl;
  cout << "Operations per second rate: " << fixed << ((double) Operations / time) << endl;
  cout << "Elapsed time since start: " << fixed << time << " s" << endl << endl;

  if (failures > 0) {
    cerr << "WARNING: " << failures << " arangob request(s) failed!!" << endl;
  }
  if (incomplete > 0) {
    cerr << "WARNING: " << incomplete << " arangob requests with incomplete results!!" << endl;
  }

  testCase->tearDown();

  for (int i = 0; i < Concurrency; ++i) {
    threads[i]->join();
    delete threads[i];
    delete endpoints[i];
  }

  delete testCase;

  TRIAGENS_REST_SHUTDOWN;

  if (failures > 0) {
    ret = EXIT_FAILURE;
  }

  arangobExitFunction(ret, nullptr);

  return ret;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>resolve conflict with namespace "Concurrency", introduced by MS on top-level...<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief arango benchmark tool
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Basics/Common.h"

#include "ArangoShell/ArangoClient.h"
#include "Basics/Mutex.h"
#include "Basics/MutexLocker.h"
#include "Basics/ProgramOptions.h"
#include "Basics/ProgramOptionsDescription.h"
#include "Basics/StringUtils.h"
#include "Basics/init.h"
#include "Basics/logging.h"
#include "Basics/random.h"
#include "Basics/tri-strings.h"
#include "Basics/string-buffer.h"
#include "Basics/terminal-utils.h"
#include "Rest/Endpoint.h"
#include "Rest/HttpRequest.h"
#include "Rest/InitialiseRest.h"
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include "Benchmark/BenchmarkCounter.h"
#include "Benchmark/BenchmarkOperation.h"
#include "Benchmark/BenchmarkThread.h"

using namespace std;
using namespace triagens::basics;
using namespace triagens::httpclient;
using namespace triagens::rest;
using namespace triagens::arango;
using namespace triagens::arangob;

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief base class for clients
////////////////////////////////////////////////////////////////////////////////

ArangoClient BaseClient("arangob");

////////////////////////////////////////////////////////////////////////////////
/// @brief started counter
////////////////////////////////////////////////////////////////////////////////

static atomic<int> Started;

////////////////////////////////////////////////////////////////////////////////
/// @brief mutex for start counter
////////////////////////////////////////////////////////////////////////////////

Mutex StartMutex;

////////////////////////////////////////////////////////////////////////////////
/// @brief send asychronous requests
////////////////////////////////////////////////////////////////////////////////

static bool Async = false;

////////////////////////////////////////////////////////////////////////////////
/// @brief number of operations in one batch
////////////////////////////////////////////////////////////////////////////////

static int BatchSize = 0;

////////////////////////////////////////////////////////////////////////////////
/// @brief collection to use
////////////////////////////////////////////////////////////////////////////////

static string Collection = "ArangoBenchmark";

////////////////////////////////////////////////////////////////////////////////
/// @brief complexity parameter for tests
////////////////////////////////////////////////////////////////////////////////

static uint64_t Complexity = 1;

////////////////////////////////////////////////////////////////////////////////
/// @brief concurrency
////////////////////////////////////////////////////////////////////////////////

static int ThreadConcurrency = 1;

////////////////////////////////////////////////////////////////////////////////
/// @brief use a startup delay
////////////////////////////////////////////////////////////////////////////////

static bool Delay = false;

////////////////////////////////////////////////////////////////////////////////
/// @brief use HTTP keep-alive
////////////////////////////////////////////////////////////////////////////////

static bool KeepAlive = true;

////////////////////////////////////////////////////////////////////////////////
/// @brief number of operations to perform
////////////////////////////////////////////////////////////////////////////////

static int Operations = 1000;

////////////////////////////////////////////////////////////////////////////////
/// @brief display progress
////////////////////////////////////////////////////////////////////////////////

static bool Progress = true;

////////////////////////////////////////////////////////////////////////////////
/// @brief test case to use
////////////////////////////////////////////////////////////////////////////////

static string TestCase = "version";

////////////////////////////////////////////////////////////////////////////////
/// @brief print out replies on error
////////////////////////////////////////////////////////////////////////////////

static bool verbose = false;

////////////////////////////////////////////////////////////////////////////////
/// @brief includes all the test cases
////////////////////////////////////////////////////////////////////////////////

#include "Benchmark/test-cases.h"

// -----------------------------------------------------------------------------
// --SECTION--                                                 private functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief update the number of ready threads. this is a callback function
/// that is called by each thread after it is created
////////////////////////////////////////////////////////////////////////////////

static void UpdateStartCounter () {
  ++Started;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get the value of the number of started threads counter
////////////////////////////////////////////////////////////////////////////////

static int GetStartCounter () {
  return Started;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief print a status line (if ! quiet)
////////////////////////////////////////////////////////////////////////////////

static void Status (const string& value) {
  if (! BaseClient.quiet()) {
    cout << value << endl;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parses the program options
////////////////////////////////////////////////////////////////////////////////

static void ParseProgramOptions (int argc, char* argv[]) {
  ProgramOptionsDescription description("STANDARD options");

  description
    ("async", &Async, "send asychronous requests")
    ("concurrency", &ThreadConcurrency, "number of parallel connections")
    ("requests", &Operations, "total number of operations")
    ("batch-size", &BatchSize, "number of operations in one batch (0 disables batching)")
    ("keep-alive", &KeepAlive, "use HTTP keep-alive")
    ("collection", &Collection, "collection name to use in tests")
    ("test-case", &TestCase, "test case to use (possible values: version, document, collection, import-document, hash, skiplist, edge, shapes, shapes-append, random-shapes, crud, crud-append, crud-write-read, aqltrx, counttrx, multitrx, multi-collection, aqlinsert)")
    ("complexity", &Complexity, "complexity parameter for the test")
    ("delay", &Delay, "use a startup delay (necessary only when run in series)")
    ("progress", &Progress, "show progress")
    ("verbose", &verbose, "print out replies if the http-header indicates db-errors")
  ;

  BaseClient.setupGeneral(description);
  BaseClient.setupServer(description);

  vector<string> arguments;
  description.arguments(&arguments);

  ProgramOptions options;
  BaseClient.parse(options, description, "--concurrency <concurrency> --requests <request> --test-case <case> ...", argc, argv, "arangob.conf");
}

// -----------------------------------------------------------------------------
// --SECTION--                                                  public functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief startup and exit functions
////////////////////////////////////////////////////////////////////////////////

static void arangobEntryFunction ();
static void arangobExitFunction (int, void*);

#ifdef _WIN32

// .............................................................................
// Call this function to do various initialisations for windows only
// .............................................................................

void arangobEntryFunction () {
  int maxOpenFiles = 1024;
  int res = 0;

  // ...........................................................................
  // Uncomment this to call this for extended debug information.
  // If you familiar with valgrind ... then this is not like that, however
  // you do get some similar functionality.
  // ...........................................................................
  //res = initialiseWindows(TRI_WIN_INITIAL_SET_DEBUG_FLAG, 0);

  res = initialiseWindows(TRI_WIN_INITIAL_SET_INVALID_HANLE_HANDLER, 0);
  if (res != 0) {
    _exit(1);
  }

  res = initialiseWindows(TRI_WIN_INITIAL_SET_MAX_STD_IO,(const char*)(&maxOpenFiles));
  if (res != 0) {
    _exit(1);
  }

  res = initialiseWindows(TRI_WIN_INITIAL_WSASTARTUP_FUNCTION_CALL, 0);
  if (res != 0) {
    _exit(1);
  }

  TRI_Application_Exit_SetExit(arangobExitFunction);
}

static void arangobExitFunction (int exitCode, void* data) {
  int res = 0;
  // ...........................................................................
  // TODO: need a terminate function for windows to be called and cleanup
  // any windows specific stuff.
  // ...........................................................................

  res = finaliseWindows(TRI_WIN_FINAL_WSASTARTUP_FUNCTION_CALL, 0);

  if (res != 0) {
    exit(1);
  }

  exit(exitCode);
}
#else

static void arangobEntryFunction () {
}

static void arangobExitFunction (int exitCode, void* data) {
}

#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief main
////////////////////////////////////////////////////////////////////////////////

int main (int argc, char* argv[]) {
  int ret = EXIT_SUCCESS;

  arangobEntryFunction();

  TRIAGENS_C_INITIALISE(argc, argv);
  TRIAGENS_REST_INITIALISE(argc, argv);

  TRI_InitialiseLogging(false);

  BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

  // .............................................................................
  // parse the program options
  // .............................................................................

  ParseProgramOptions(argc, argv);

  // .............................................................................
  // set-up client connection
  // .............................................................................

  BaseClient.createEndpoint();

  if (BaseClient.endpointServer() == nullptr) {
    LOG_FATAL_AND_EXIT("invalid value for --server.endpoint ('%s')", BaseClient.endpointString().c_str());
  }

  BenchmarkOperation* testCase = GetTestCase(TestCase);

  if (testCase == nullptr) {
    LOG_FATAL_AND_EXIT("invalid test case name '%s'", TestCase.c_str());
    return EXIT_FAILURE; // will not be reached
  }

  Status("starting threads...");

  BenchmarkCounter<unsigned long> operationsCounter(0, (unsigned long) Operations);
  ConditionVariable startCondition;

  vector<Endpoint*> endpoints;
  vector<BenchmarkThread*> threads;

  const double stepSize = (double) Operations / (double) ThreadConcurrency;
  int64_t realStep = (int64_t) stepSize;
  if (stepSize - (double) ((int64_t) stepSize) > 0.0) {
    realStep++;
  }
  if (realStep % 1000 != 0) {
    realStep += 1000 - (realStep % 1000);
  }
  // add some more offset so we don't get into trouble with threads of different speed
  realStep += 10000;

  // start client threads
  for (int i = 0; i < ThreadConcurrency; ++i) {
    Endpoint* endpoint = Endpoint::clientFactory(BaseClient.endpointString());
    endpoints.push_back(endpoint);

    BenchmarkThread* thread = new BenchmarkThread(testCase,
        &startCondition,
        &UpdateStartCounter,
        i,
        (unsigned long) BatchSize,
        &operationsCounter,
        endpoint,
        BaseClient.databaseName(),
        BaseClient.username(),
        BaseClient.password(),
        BaseClient.requestTimeout(),
        BaseClient.connectTimeout(),
        BaseClient.sslProtocol(),
        KeepAlive,
        Async,
        verbose);

    threads.push_back(thread);
    thread->setOffset((size_t) (i * realStep));
    thread->start();
  }

  // give all threads a chance to start so they will not miss the broadcast
  while (GetStartCounter() < ThreadConcurrency) {
    usleep(5000);
  }

  if (Delay) {
    Status("sleeping (startup delay)...");
    sleep(10);
  }
  Status("executing tests...");

  double start = TRI_microtime();

  // broadcast the start signal to all threads
  {
    ConditionLocker guard(&startCondition);
    guard.broadcast();
  }

  const size_t stepValue = (Operations / 20);
  size_t nextReportValue = stepValue;

  if (nextReportValue < 100) {
    nextReportValue = 100;
  }

  while (1) {
    const size_t numOperations = operationsCounter.getDone();

    if (numOperations >= (size_t) Operations) {
      break;
    }

    if (Progress && numOperations >= nextReportValue) {
      LOG_INFO("number of operations: %d", (int) nextReportValue);
      nextReportValue += stepValue;
    }

    usleep(20000);
  }

  double time = TRI_microtime() - start;
  double requestTime = 0.0;

  for (int i = 0; i < ThreadConcurrency; ++i) {
    requestTime += threads[i]->getTime();
  }

  size_t failures = operationsCounter.failures();
  size_t incomplete = operationsCounter.incompleteFailures();

  cout << endl;
  cout << "Total number of operations: " << Operations <<
          ", keep alive: " << (KeepAlive ? "yes" : "no") <<
          ", async: " << (Async ? "yes" : "no")  <<
          ", batch size: " << BatchSize <<
          ", concurrency level (threads): " << ThreadConcurrency <<
          endl;

  cout << "Test case: " << TestCase <<
          ", complexity: " << Complexity <<
          ", database: '" << BaseClient.databaseName() <<
          "', collection: '" << Collection << "'" <<
          endl;

  cout << "Total request/response duration (sum of all threads): " << fixed << requestTime << " s" << endl;
  cout << "Request/response duration (per thread): " << fixed << (requestTime / (double) ThreadConcurrency) << " s" << endl;
  cout << "Time needed per operation: " << fixed << (time / Operations) << " s" << endl;
  cout << "Time needed per operation per thread: " << fixed << (time / (double) Operations * (double) ThreadConcurrency) << " s" << endl;
  cout << "Operations per second rate: " << fixed << ((double) Operations / time) << endl;
  cout << "Elapsed time since start: " << fixed << time << " s" << endl << endl;

  if (failures > 0) {
    cerr << "WARNING: " << failures << " arangob request(s) failed!!" << endl;
  }
  if (incomplete > 0) {
    cerr << "WARNING: " << incomplete << " arangob requests with incomplete results!!" << endl;
  }

  testCase->tearDown();

  for (int i = 0; i < ThreadConcurrency; ++i) {
    threads[i]->join();
    delete threads[i];
    delete endpoints[i];
  }

  delete testCase;

  TRIAGENS_REST_SHUTDOWN;

  if (failures > 0) {
    ret = EXIT_FAILURE;
  }

  arangobExitFunction(ret, nullptr);

  return ret;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>/* Computes the gradient magnitude after convolving with a Gaussian kernel.
   It uses IIR filter for approximating the convolution  */

#include "vvITKFilterModule.h"

#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"

static int ProcessData(void *inf, vtkVVProcessDataStruct *pds)
{

  vtkVVPluginInfo *info = (vtkVVPluginInfo *)inf;

  const unsigned int Dimension = 3;

  try
  {
  switch( info->InputVolumeScalarType )
    {
    case VTK_UNSIGNED_CHAR:
      {
      typedef  unsigned char                        PixelType;
      typedef  itk::Image< PixelType, Dimension >   ImageType;
      typedef  itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType,  ImageType >   FilterType;
      VolView::PlugIn::FilterModule< FilterType > module;
      module.SetPlugInfo( info );
      module.SetUpdateMessage("Computing the gradient magnitude...");
      // Set the parameters on it
      module.GetFilter()->SetSigma(  atof( info->GUIItems[ 0 ].CurrentValue) );
      // Execute the filter
      module.ProcessData( pds  );
      break;
      }
    case VTK_UNSIGNED_SHORT:
      {
      typedef  unsigned short                       PixelType;
      typedef  itk::Image< PixelType, Dimension >   ImageType;
      typedef  itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType,  ImageType >   FilterType;
      VolView::PlugIn::FilterModule< FilterType > module;
      module.SetPlugInfo( info );
      module.SetUpdateMessage("Computing the gradient magnitude...");
      // Set the parameters on it
      module.GetFilter()->SetSigma(  atof( info->GUIItems[ 0 ].CurrentValue) );
      // Execute the filter
      module.ProcessData( pds );
      break;
      }
    }
  }
  catch( itk::ExceptionObject & except )
  {
    info->DisplayError( info, except.what() );
    return -1;
  }
  return 0;
}

static int UpdateGUI(void *inf)
{
  vtkVVPluginInfo *info = (vtkVVPluginInfo *)inf;

  info->GUIItems[0].Label = "Sigma";
  info->GUIItems[0].GUIType = VV_GUI_SCALE;
  info->GUIItems[0].Default = "1.0";
  info->GUIItems[0].Help = "Standard deviation of the Gaussian kernel used to smooth the image before computing the gradient";
  info->GUIItems[0].Hints = "0 20 0.1";

  info->RequiredZOverlap = 0;

  info->OutputVolumeScalarType = info->InputVolumeScalarType;
  info->OutputVolumeNumberOfComponents =
    info->InputVolumeNumberOfComponents;
  memcpy(info->OutputVolumeDimensions,info->InputVolumeDimensions,
         3*sizeof(int));
  memcpy(info->OutputVolumeSpacing,info->InputVolumeSpacing,
         3*sizeof(float));
  memcpy(info->OutputVolumeOrigin,info->InputVolumeOrigin,
         3*sizeof(float));

  return 1;
}

extern "C" {

void VV_PLUGIN_EXPORT vvITKGradientMagnitudeRecursiveGaussianInit(vtkVVPluginInfo *info)
{
  // setup information that never changes
  info->ProcessData = ProcessData;
  info->UpdateGUI = UpdateGUI;
  info->Name = "Gradient Magnitude IIR (ITK)";
  info->TerseDocumentation = "Gradient Magnitude Gaussian IIR";
  info->FullDocumentation =
    "This filter applies IIR filters to compute the equivalent of convolving the input image with the derivatives of a Gaussian kernel and then computing the magnitude of the resulting gradient.";
  info->SupportsInPlaceProcessing = 0;
  info->SupportsProcessingPieces = 0;
  info->RequiredZOverlap = 0;

  // Number of bytes required in intermediate memory per voxel
  info->PerVoxelMemoryRequired = 16;

  /* setup the GUI components */
  info->NumberOfGUIItems = 1;
  info->GUIItems = (vtkVVGUIItem *)malloc(info->NumberOfGUIItems*sizeof(vtkVVGUIItem));
}

}
<commit_msg>FIX: Normalization across scale added.<commit_after>/* Computes the gradient magnitude after convolving with a Gaussian kernel.
   It uses IIR filter for approximating the convolution  */

#include "vvITKFilterModule.h"

#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"

static int ProcessData(void *inf, vtkVVProcessDataStruct *pds)
{

  vtkVVPluginInfo *info = (vtkVVPluginInfo *)inf;

  const unsigned int Dimension = 3;

  try
  {
  switch( info->InputVolumeScalarType )
    {
    case VTK_UNSIGNED_CHAR:
      {
      typedef  unsigned char                        PixelType;
      typedef  itk::Image< PixelType, Dimension >   ImageType;
      typedef  itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType,  ImageType >   FilterType;
      VolView::PlugIn::FilterModule< FilterType > module;
      module.SetPlugInfo( info );
      module.SetUpdateMessage("Computing the gradient magnitude...");
      // Set the parameters on it
      module.GetFilter()->SetSigma(  atof( info->GUIItems[ 0 ].CurrentValue) );
      module.GetFilter()->SetNormalizeAcrossScale( true );
      // Execute the filter
      module.ProcessData( pds  );
      break;
      }
    case VTK_UNSIGNED_SHORT:
      {
      typedef  unsigned short                       PixelType;
      typedef  itk::Image< PixelType, Dimension >   ImageType;
      typedef  itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType,  ImageType >   FilterType;
      VolView::PlugIn::FilterModule< FilterType > module;
      module.SetPlugInfo( info );
      module.SetUpdateMessage("Computing the gradient magnitude...");
      // Set the parameters on it
      module.GetFilter()->SetSigma(  atof( info->GUIItems[ 0 ].CurrentValue) );
      module.GetFilter()->SetNormalizeAcrossScale( true );
      // Execute the filter
      module.ProcessData( pds );
      break;
      }
    }
  }
  catch( itk::ExceptionObject & except )
  {
    info->DisplayError( info, except.what() );
    return -1;
  }
  return 0;
}

static int UpdateGUI(void *inf)
{
  vtkVVPluginInfo *info = (vtkVVPluginInfo *)inf;

  info->GUIItems[0].Label = "Sigma";
  info->GUIItems[0].GUIType = VV_GUI_SCALE;
  info->GUIItems[0].Default = "1.0";
  info->GUIItems[0].Help = "Standard deviation of the Gaussian kernel used to smooth the image before computing the gradient";
  info->GUIItems[0].Hints = "0 20 0.1";

  info->RequiredZOverlap = 0;

  info->OutputVolumeScalarType = info->InputVolumeScalarType;
  info->OutputVolumeNumberOfComponents =
    info->InputVolumeNumberOfComponents;
  memcpy(info->OutputVolumeDimensions,info->InputVolumeDimensions,
         3*sizeof(int));
  memcpy(info->OutputVolumeSpacing,info->InputVolumeSpacing,
         3*sizeof(float));
  memcpy(info->OutputVolumeOrigin,info->InputVolumeOrigin,
         3*sizeof(float));

  return 1;
}

extern "C" {

void VV_PLUGIN_EXPORT vvITKGradientMagnitudeRecursiveGaussianInit(vtkVVPluginInfo *info)
{
  // setup information that never changes
  info->ProcessData = ProcessData;
  info->UpdateGUI = UpdateGUI;
  info->Name = "Gradient Magnitude IIR (ITK)";
  info->TerseDocumentation = "Gradient Magnitude Gaussian IIR";
  info->FullDocumentation =
    "This filter applies IIR filters to compute the equivalent of convolving the input image with the derivatives of a Gaussian kernel and then computing the magnitude of the resulting gradient.";
  info->SupportsInPlaceProcessing = 0;
  info->SupportsProcessingPieces = 0;
  info->RequiredZOverlap = 0;

  // Number of bytes required in intermediate memory per voxel
  info->PerVoxelMemoryRequired = 16;

  /* setup the GUI components */
  info->NumberOfGUIItems = 1;
  info->GUIItems = (vtkVVGUIItem *)malloc(info->NumberOfGUIItems*sizeof(vtkVVGUIItem));
}

}
<|endoftext|>


<commit_before>#pragma once

#include "base/status_or.hpp"
#include "geometry/named_quantities.hpp"
#include "physics/body.hpp"
#include "physics/discrete_trajectory.hpp"
#include "physics/massive_body.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/quantities.hpp"

namespace principia {
namespace astronomy {
namespace internal_orbital_elements {

using base::StatusOr;
using geometry::Instant;
using physics::Body;
using physics::DiscreteTrajectory;
using physics::MassiveBody;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Difference;
using quantities::Infinity;
using quantities::Length;
using quantities::Time;

class OrbitalElements {
 public:
  template<typename PrimaryCentred>
  static StatusOr<OrbitalElements> ForTrajectory(
      DiscreteTrajectory<PrimaryCentred> const& trajectory,
      MassiveBody const& primary,
      Body const& secondary);

  // The classical Keplerian elements (a, e, i, Ω, ω, M),
  // together with an epoch.
  struct ClassicalElements {
    Instant time;
    Length semimajor_axis;
    double eccentricity;
    Angle inclination;
    Angle longitude_of_ascending_node;
    Angle argument_of_periapsis;
    Angle mean_anomaly;
  };

  // Mean element time series.  These elements are free of short-period
  // variations, i.e., variations whose period is the orbital period.
  std::vector<ClassicalElements> const& mean_elements() const;

  // The period of the (osculating) mean longitude λ = Ω + ω + M.
  // Note that since our mean elements are filtered by integration over this
  // period, it does not make much sense to recompute it based on our mean
  // elements.
  Time sidereal_period() const;
  // The period of the (mean) mean argument of latitude u = ω + M.
  Time nodal_period() const;
  // The period of the (mean) mean anomaly M.
  Time anomalistic_period() const;

  // The rate of precession of Ω.
  AngularFrequency nodal_precession() const;

  // NOTE(egg): The argument of periapsis ω typically precesses as well.
  // However, long-period variations tend to be comparatively large, so that a
  // precession rate computed over a few orbits would be highly inaccurate.
  // More importantly, whereas the actual value of Ω′ is relevant to, e.g.,
  // orbit recurrence computation or sun-synchronicity, one typically cares
  // about ω′ only when requiring that ω′ be 0 (in a frozen orbit), in which
  // case the more relevant requirement is that ω stays close to some reference
  // value.

  // Of the mean classical elements (a, e, i, Ω, ω, M), under the influence of
  // gravitational forces,
  // — M always exhibits a fast secular variation (anomalistic mean motion);
  // — Ω often exhibits a secular variation (nodal precession); there are
  //   however rare cases where it is kept constant (so-called inertial orbits
  //   that achieve Ω′ = 0 by being polar, e.g., CoRoT or Gravity Probe B); in
  //   that case, the frozen value may occasionally be relevant: for CoRoT, it
  //   determines the region of the sky that may be observed.
  // — ω exhibits a secular variation, except for frozen orbits or orbits at the
  // critical inclination; For frozen
  //   orbits (type II frozen orbits in the terminology of Ulrich Walter), its
  //   constant value must be eithre 90° or 270°; for orbits at the critical
  //   inclination (type I frozen orbits), ω is arbitrary; in highly eccentric
  //   cases, it is often chosen to be 270° so that the apogee is at high
  //   latitudes (Молния, みちびき, etc.).
  // — a, e, i exhibit no secular variation.
  // However, the elements that exhibit no secular variation still have
  // long-period variations; instead of trying to characterize these complex
  // effects, we provide the range of values taken by these elements over the
  // trajectory being analysed.

  // Represents the interval [min, max].
  // TODO(egg): This makes sense for T = instant, but InfinitePast and
  // InfiniteFuture work differently from Infinity.
  template<typename T>
  struct Interval {
    T min = +Infinity<T>();
    T max = -Infinity<T>();

    Difference<T> measure() const;
    T midpoint() const;

    // Extends this interval so that it contains x.
    void Include(T const& x);
  };

  // REMOVE BEFORE FLIGHT: rename these to mean_meow_range.
  Interval<Length> mean_semimajor_axis_range() const;
  Interval<double> mean_eccentricity_range() const;
  Interval<Angle> mean_inclination_range() const;
  Interval<Angle> mean_longitude_of_ascending_node_range() const;
  Interval<Angle> mean_argument_of_periapsis_range() const;

  // The equinoctial elements, and in particular the osculating equinoctial
  // elements, are not directly interesting; anything that could be derived from
  // them should be directly computed by this class instead.  They are however
  // useful for experimentation in Mathematica, to see whether the
  // transformation from osculating to mean elements is well-behaved, whether
  // the mean elements are stable, and what useful quantities can be derived
  // from the mean elements.

  // The equinoctial elements, together with an epoch.
  // See Broucke and Cefola (1972), On the equinoctial orbit elements.
  struct EquinoctialElements {
    Instant t;
    Length a;
    double h;
    double k;
    Angle λ;
    double p;
    double q;
    // pʹ and qʹ use the cotangent of the half-inclination instead of its
    // tangent; they are better suited to retrograde orbits.
    double pʹ;
    double qʹ;
  };

  std::vector<EquinoctialElements> const& osculating_equinoctial_elements()
      const;
  std::vector<EquinoctialElements> const& mean_equinoctial_elements() const;

 private:
  OrbitalElements() = default;

  template<typename PrimaryCentred>
  static std::vector<EquinoctialElements> OsculatingEquinoctialElements(
      DiscreteTrajectory<PrimaryCentred> const& trajectory,
      MassiveBody const& primary,
      Body const& secondary);

  // |equinoctial_elements| must contain at least 2 elements.
  static Time SiderealPeriod(
      std::vector<EquinoctialElements> const& equinoctial_elements);

  // |osculating| must contain at least 2 elements.
  // The resulting elements are averaged over one period, centred on t.
  static std::vector<EquinoctialElements> MeanEquinoctialElements(
      std::vector<EquinoctialElements> const& osculating,
      Time const& period);

  static std::vector<ClassicalElements> ToClassicalElements(
      std::vector<EquinoctialElements> const& equinoctial_elements);

  // |mean_classical_elements_| must have been computed; sets
  // |anomalistic_period_|, |nodal_period_|, and |nodal_precession_|
  // accordingly. Note that this does not compute |sidereal_period_| (our mean
  // element computation is based on it, so it gets computed earlier).
  void ComputePeriodsAndPrecession();

  void ComputeMeanElementRanges();

  std::vector<EquinoctialElements> osculating_equinoctial_elements_;
  Time sidereal_period_;
  std::vector<EquinoctialElements> mean_equinoctial_elements_;
  std::vector<ClassicalElements> mean_classical_elements_;
  Time anomalistic_period_;
  Time nodal_period_;
  AngularFrequency nodal_precession_;

  Interval<Length> mean_semimajor_axis_range_;
  Interval<double> mean_eccentricity_range_;
  Interval<Angle> mean_inclination_range_;
  Interval<Angle> mean_longitude_of_ascending_node_range_;
  Interval<Angle> mean_argument_of_periapsis_range_;
};

}  // namespace internal_orbital_elements

using internal_orbital_elements::OrbitalElements;

}  // namespace astronomy
}  // namespace principia

#include "astronomy/orbital_elements_body.hpp"
<commit_msg>remove<commit_after>#pragma once

#include "base/status_or.hpp"
#include "geometry/named_quantities.hpp"
#include "physics/body.hpp"
#include "physics/discrete_trajectory.hpp"
#include "physics/massive_body.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/quantities.hpp"

namespace principia {
namespace astronomy {
namespace internal_orbital_elements {

using base::StatusOr;
using geometry::Instant;
using physics::Body;
using physics::DiscreteTrajectory;
using physics::MassiveBody;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Difference;
using quantities::Infinity;
using quantities::Length;
using quantities::Time;

class OrbitalElements {
 public:
  template<typename PrimaryCentred>
  static StatusOr<OrbitalElements> ForTrajectory(
      DiscreteTrajectory<PrimaryCentred> const& trajectory,
      MassiveBody const& primary,
      Body const& secondary);

  // The classical Keplerian elements (a, e, i, Ω, ω, M),
  // together with an epoch.
  struct ClassicalElements {
    Instant time;
    Length semimajor_axis;
    double eccentricity;
    Angle inclination;
    Angle longitude_of_ascending_node;
    Angle argument_of_periapsis;
    Angle mean_anomaly;
  };

  // Mean element time series.  These elements are free of short-period
  // variations, i.e., variations whose period is the orbital period.
  std::vector<ClassicalElements> const& mean_elements() const;

  // The period of the (osculating) mean longitude λ = Ω + ω + M.
  // Note that since our mean elements are filtered by integration over this
  // period, it does not make much sense to recompute it based on our mean
  // elements.
  Time sidereal_period() const;
  // The period of the (mean) mean argument of latitude u = ω + M.
  Time nodal_period() const;
  // The period of the (mean) mean anomaly M.
  Time anomalistic_period() const;

  // The rate of precession of Ω.
  AngularFrequency nodal_precession() const;

  // NOTE(egg): The argument of periapsis ω typically precesses as well.
  // However, long-period variations tend to be comparatively large, so that a
  // precession rate computed over a few orbits would be highly inaccurate.
  // More importantly, whereas the actual value of Ω′ is relevant to, e.g.,
  // orbit recurrence computation or sun-synchronicity, one typically cares
  // about ω′ only when requiring that ω′ be 0 (in a frozen orbit), in which
  // case the more relevant requirement is that ω stays close to some reference
  // value.

  // Of the mean classical elements (a, e, i, Ω, ω, M), under the influence of
  // gravitational forces,
  // — M always exhibits a fast secular variation (anomalistic mean motion);
  // — Ω often exhibits a secular variation (nodal precession); there are
  //   however rare cases where it is kept constant (so-called inertial orbits
  //   that achieve Ω′ = 0 by being polar, e.g., CoRoT or Gravity Probe B); in
  //   that case, the frozen value may occasionally be relevant: for CoRoT, it
  //   determines the region of the sky that may be observed.
  // — ω exhibits a secular variation, except for frozen orbits or orbits at the
  // critical inclination; For frozen
  //   orbits (type II frozen orbits in the terminology of Ulrich Walter), its
  //   constant value must be eithre 90° or 270°; for orbits at the critical
  //   inclination (type I frozen orbits), ω is arbitrary; in highly eccentric
  //   cases, it is often chosen to be 270° so that the apogee is at high
  //   latitudes (Молния, みちびき, etc.).
  // — a, e, i exhibit no secular variation.
  // However, the elements that exhibit no secular variation still have
  // long-period variations; instead of trying to characterize these complex
  // effects, we provide the range of values taken by these elements over the
  // trajectory being analysed.

  // Represents the interval [min, max].
  // TODO(egg): This makes sense for T = instant, but InfinitePast and
  // InfiniteFuture work differently from Infinity.
  template<typename T>
  struct Interval {
    T min = +Infinity<T>();
    T max = -Infinity<T>();

    Difference<T> measure() const;
    T midpoint() const;

    // Extends this interval so that it contains x.
    void Include(T const& x);
  };

  Interval<Length> mean_semimajor_axis_range() const;
  Interval<double> mean_eccentricity_range() const;
  Interval<Angle> mean_inclination_range() const;
  Interval<Angle> mean_longitude_of_ascending_node_range() const;
  Interval<Angle> mean_argument_of_periapsis_range() const;

  // The equinoctial elements, and in particular the osculating equinoctial
  // elements, are not directly interesting; anything that could be derived from
  // them should be directly computed by this class instead.  They are however
  // useful for experimentation in Mathematica, to see whether the
  // transformation from osculating to mean elements is well-behaved, whether
  // the mean elements are stable, and what useful quantities can be derived
  // from the mean elements.

  // The equinoctial elements, together with an epoch.
  // See Broucke and Cefola (1972), On the equinoctial orbit elements.
  struct EquinoctialElements {
    Instant t;
    Length a;
    double h;
    double k;
    Angle λ;
    double p;
    double q;
    // pʹ and qʹ use the cotangent of the half-inclination instead of its
    // tangent; they are better suited to retrograde orbits.
    double pʹ;
    double qʹ;
  };

  std::vector<EquinoctialElements> const& osculating_equinoctial_elements()
      const;
  std::vector<EquinoctialElements> const& mean_equinoctial_elements() const;

 private:
  OrbitalElements() = default;

  template<typename PrimaryCentred>
  static std::vector<EquinoctialElements> OsculatingEquinoctialElements(
      DiscreteTrajectory<PrimaryCentred> const& trajectory,
      MassiveBody const& primary,
      Body const& secondary);

  // |equinoctial_elements| must contain at least 2 elements.
  static Time SiderealPeriod(
      std::vector<EquinoctialElements> const& equinoctial_elements);

  // |osculating| must contain at least 2 elements.
  // The resulting elements are averaged over one period, centred on t.
  static std::vector<EquinoctialElements> MeanEquinoctialElements(
      std::vector<EquinoctialElements> const& osculating,
      Time const& period);

  static std::vector<ClassicalElements> ToClassicalElements(
      std::vector<EquinoctialElements> const& equinoctial_elements);

  // |mean_classical_elements_| must have been computed; sets
  // |anomalistic_period_|, |nodal_period_|, and |nodal_precession_|
  // accordingly. Note that this does not compute |sidereal_period_| (our mean
  // element computation is based on it, so it gets computed earlier).
  void ComputePeriodsAndPrecession();

  void ComputeMeanElementRanges();

  std::vector<EquinoctialElements> osculating_equinoctial_elements_;
  Time sidereal_period_;
  std::vector<EquinoctialElements> mean_equinoctial_elements_;
  std::vector<ClassicalElements> mean_classical_elements_;
  Time anomalistic_period_;
  Time nodal_period_;
  AngularFrequency nodal_precession_;

  Interval<Length> mean_semimajor_axis_range_;
  Interval<double> mean_eccentricity_range_;
  Interval<Angle> mean_inclination_range_;
  Interval<Angle> mean_longitude_of_ascending_node_range_;
  Interval<Angle> mean_argument_of_periapsis_range_;
};

}  // namespace internal_orbital_elements

using internal_orbital_elements::OrbitalElements;

}  // namespace astronomy
}  // namespace principia

#include "astronomy/orbital_elements_body.hpp"
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/app/atom_main_delegate.h"

#include <string>

#include "atom/browser/atom_browser_client.h"
#include "atom/renderer/atom_renderer_client.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"

namespace atom {

AtomMainDelegate::AtomMainDelegate() {
}

AtomMainDelegate::~AtomMainDelegate() {
}

void AtomMainDelegate::AddDataPackFromPath(
    ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {
#if defined(OS_WIN)
  bundle->AddDataPackFromPath(
      pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")),
      ui::SCALE_FACTOR_200P);
  bundle->AddDataPackFromPath(
      pak_dir.Append(FILE_PATH_LITERAL("webkit_resources_200_percent.pak")),
      ui::SCALE_FACTOR_200P);
#endif
}

bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
  // Disable logging out to debug.log on Windows
#if defined(OS_WIN)
  logging::LoggingSettings settings;
#if defined(DEBUG)
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = L"debug.log";
  settings.lock_log = logging::LOCK_LOG_FILE;
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif
  logging::InitLogging(settings);
#endif  // defined(OS_WIN)

  // Logging with pid and timestamp.
  logging::SetLogItems(true, false, true, false);

  // Enable convient stack printing.
#if defined(DEBUG) && defined(OS_LINUX)
  base::debug::EnableInProcessStackDumping();
#endif

  return brightray::MainDelegate::BasicStartupComplete(exit_code);
}

void AtomMainDelegate::PreSandboxStartup() {
  brightray::MainDelegate::PreSandboxStartup();

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  std::string process_type = command_line->GetSwitchValueASCII(
      switches::kProcessType);

  // Only append arguments for browser process.
  if (!process_type.empty())
    return;

  // Add a flag to mark the start of switches added by atom-shell.
  command_line->AppendSwitch("atom-shell-switches-start");

  // Disable renderer sandbox for most of node's functions.
  command_line->AppendSwitch(switches::kNoSandbox);

  // Add a flag to mark the end of switches added by atom-shell.
  command_line->AppendSwitch("atom-shell-switches-end");
}

content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new AtomBrowserClient);
  return browser_client_.get();
}

content::ContentRendererClient*
    AtomMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new AtomRendererClient);
  return renderer_client_.get();
}

}  // namespace atom
<commit_msg>win: Disable the LegacyRenderWidgetHostHWND, fixes #506.<commit_after>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/app/atom_main_delegate.h"

#include <string>

#include "atom/browser/atom_browser_client.h"
#include "atom/renderer/atom_renderer_client.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"

namespace atom {

AtomMainDelegate::AtomMainDelegate() {
}

AtomMainDelegate::~AtomMainDelegate() {
}

void AtomMainDelegate::AddDataPackFromPath(
    ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {
#if defined(OS_WIN)
  bundle->AddDataPackFromPath(
      pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")),
      ui::SCALE_FACTOR_200P);
  bundle->AddDataPackFromPath(
      pak_dir.Append(FILE_PATH_LITERAL("webkit_resources_200_percent.pak")),
      ui::SCALE_FACTOR_200P);
#endif
}

bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
  // Disable logging out to debug.log on Windows
#if defined(OS_WIN)
  logging::LoggingSettings settings;
#if defined(DEBUG)
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = L"debug.log";
  settings.lock_log = logging::LOCK_LOG_FILE;
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif
  logging::InitLogging(settings);
#endif  // defined(OS_WIN)

  // Logging with pid and timestamp.
  logging::SetLogItems(true, false, true, false);

  // Enable convient stack printing.
#if defined(DEBUG) && defined(OS_LINUX)
  base::debug::EnableInProcessStackDumping();
#endif

  return brightray::MainDelegate::BasicStartupComplete(exit_code);
}

void AtomMainDelegate::PreSandboxStartup() {
  brightray::MainDelegate::PreSandboxStartup();

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  std::string process_type = command_line->GetSwitchValueASCII(
      switches::kProcessType);

  // Only append arguments for browser process.
  if (!process_type.empty())
    return;

  // Add a flag to mark the start of switches added by atom-shell.
  command_line->AppendSwitch("atom-shell-switches-start");

#if defined(OS_WIN)
  // Disable the LegacyRenderWidgetHostHWND, it made frameless windows unable
  // to move and resize. We may consider enabling it again after upgraded to
  // Chrome 38, which should have fixed the problem.
  command_line->AppendSwitch(switches::kDisableLegacyIntermediateWindow);
#endif

  // Disable renderer sandbox for most of node's functions.
  command_line->AppendSwitch(switches::kNoSandbox);

  // Add a flag to mark the end of switches added by atom-shell.
  command_line->AppendSwitch("atom-shell-switches-end");
}

content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new AtomBrowserClient);
  return browser_client_.get();
}

content::ContentRendererClient*
    AtomMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new AtomRendererClient);
  return renderer_client_.get();
}

}  // namespace atom
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: i_type.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-15 13:26:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef ARY_IDL_I_TYPE_HXX
#define ARY_IDL_I_TYPE_HXX

// USED SERVICES
    // BASE CLASSES
    // COMPONENTS
#include <ary/re.hxx>
    // PARAMETERS
#include <ary/idl/i_language.hxx>

namespace ary
{
namespace idl
{

class Gate;

/** Abstract base for all secondary productions of types
*/
class Type_2s
{
  public:
    virtual             ~Type_2s() {}

    static DYN Type_2s *
                        Create_(
                            RCid                i_nCeId );
};

/** @resp Base of all IDL types.

    @->Type represents the occurence of a type as base,
    parameter, return type or element type in UNO IDL code.
    Some of them relate to a @->CodeEntity, but
    the @->Type "MyInterface" is something different than
    the @->CodeEntity "MyInterface".

    This is a storage base class, where more special
    classes are derived from.
*/
class Type : public n22::RepositoryEntity
{
  public:
    typedef Type_2s secondary_productions;

    // LIFECYCLE
    virtual             ~Type() {}

    // INQUIRY
    Type_id             TypeId() const          { return Type_id(Id()); }

    /// @descr Does NOT clear the output-parameters.
    void                Get_Text(
                            StringVector &      o_module,
                            String &            o_name,
                            Ce_id &             o_nRelatedCe,
                            int &               o_nSequenceCount,
                            const Gate &        i_rGate ) const;
    Type_id             TemplateParameterType() const;

  private:
    virtual void        inq_Get_Text(
                            StringVector &      o_module,
                            String &            o_name,
                            Ce_id &             o_nRelatedCe,
                            int &               o_nSequemceCount,
                            const Gate &        i_rGate ) const = 0;
    virtual Type_id     inq_TemplateParameterType() const;
};

inline void
Type::Get_Text( StringVector &      o_module,
                String &            o_name,
                Ce_id &             o_nRelatedCe,
                int &               o_nSequenceCount,
                const Gate &        i_rGate ) const
{
    inq_Get_Text(o_module,o_name,o_nRelatedCe,o_nSequenceCount,i_rGate);
}

inline Type_id
Type::TemplateParameterType() const
{
    return inq_TemplateParameterType();
}

}   // namespace idl
}   // namespace ary

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.18); FILE MERGED 2005/09/05 13:09:22 rt 1.3.18.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: i_type.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:12:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef ARY_IDL_I_TYPE_HXX
#define ARY_IDL_I_TYPE_HXX

// USED SERVICES
    // BASE CLASSES
    // COMPONENTS
#include <ary/re.hxx>
    // PARAMETERS
#include <ary/idl/i_language.hxx>

namespace ary
{
namespace idl
{

class Gate;

/** Abstract base for all secondary productions of types
*/
class Type_2s
{
  public:
    virtual             ~Type_2s() {}

    static DYN Type_2s *
                        Create_(
                            RCid                i_nCeId );
};

/** @resp Base of all IDL types.

    @->Type represents the occurence of a type as base,
    parameter, return type or element type in UNO IDL code.
    Some of them relate to a @->CodeEntity, but
    the @->Type "MyInterface" is something different than
    the @->CodeEntity "MyInterface".

    This is a storage base class, where more special
    classes are derived from.
*/
class Type : public n22::RepositoryEntity
{
  public:
    typedef Type_2s secondary_productions;

    // LIFECYCLE
    virtual             ~Type() {}

    // INQUIRY
    Type_id             TypeId() const          { return Type_id(Id()); }

    /// @descr Does NOT clear the output-parameters.
    void                Get_Text(
                            StringVector &      o_module,
                            String &            o_name,
                            Ce_id &             o_nRelatedCe,
                            int &               o_nSequenceCount,
                            const Gate &        i_rGate ) const;
    Type_id             TemplateParameterType() const;

  private:
    virtual void        inq_Get_Text(
                            StringVector &      o_module,
                            String &            o_name,
                            Ce_id &             o_nRelatedCe,
                            int &               o_nSequemceCount,
                            const Gate &        i_rGate ) const = 0;
    virtual Type_id     inq_TemplateParameterType() const;
};

inline void
Type::Get_Text( StringVector &      o_module,
                String &            o_name,
                Ce_id &             o_nRelatedCe,
                int &               o_nSequenceCount,
                const Gate &        i_rGate ) const
{
    inq_Get_Text(o_module,o_name,o_nRelatedCe,o_nSequenceCount,i_rGate);
}

inline Type_id
Type::TemplateParameterType() const
{
    return inq_TemplateParameterType();
}

}   // namespace idl
}   // namespace ary

#endif
<|endoftext|>


<commit_before>/*
 *  CompoundAgent.cpp
 *  openc2e
 *
 *  Created by Alyssa Milburn on Tue May 25 2004.
 *  Copyright (c) 2004 Alyssa Milburn. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#include "CompoundPart.h"
#include "openc2e.h"
#include "c16Image.h"
#include "SDLBackend.h"

void CompoundPart::render(SDLBackend *renderer, int xoffset, int yoffset) {
	renderer->render(getSprite(), getCurrentSprite(), xoffset + x, yoffset + y, is_transparent, transparency);
}

CompoundPart::CompoundPart(unsigned int _id, std::string spritefile, unsigned int fimg,
						unsigned int _x, unsigned int _y, unsigned int _z) {
	id = _id;
	firstimg = fimg;
	x = _x;
	y = _y;
	zorder = _z;
	sprite = gallery.getImage(spritefile);
	caos_assert(sprite);
	pose = 0;
	base = 0;
	is_transparent = false;
	framerate = 1;
	framedelay = 0;
}

DullPart::DullPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
			 unsigned int _z) : CompoundPart(_id, spritefile, fimg, _x, _y, _z) {
}

ButtonPart::ButtonPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
	unsigned int _z, const bytestring &animhover, int msgid, int option) : CompoundPart(_id, spritefile, fimg, _x, _y, _z) {
	messageid = msgid;
	hitopaquepixelsonly = (option == 1);
	hoveranimation = animhover;
}

FixedTextPart::FixedTextPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
		                                  unsigned int _z, std::string fontsprite) : TextPart(_id, spritefile, fimg, _x, _y, _z) {
	// TODO: load fontsprite
}

TextEntryPart::TextEntryPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
		                                  unsigned int _z, unsigned int msgid, std::string fontsprite) : TextPart(_id, spritefile, fimg, _x, _y, _z) {
	// TODO: load fontsprite, msgid
}

void CompoundPart::tick() {
	if (!animation.empty()) {
                if (framerate > 1) {
			framedelay++;
			if (framedelay == framerate + 1)
				framedelay = 0;
		}

		if (framedelay == 0) {
			unsigned int f = frameno + 1;
			if (f == animation.size()) return;
			if (animation[f] == 255) {
				if (f == (animation.size() - 1)) f = 0;
				else f = animation[f + 1];
			}
			setFrameNo(f);
		}
	}
}

/* vim: set noet: */
<commit_msg>Test * commitbot<commit_after>/*
 *  CompoundAgent.cpp
 *  openc2e
 *
 *  Created by Alyssa Milburn on Tue May 25 2004.
 *  Copyright (c) 2004 Alyssa Milburn. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#include "CompoundPart.h"
#include "openc2e.h"
#include "c16Image.h"
#include "SDLBackend.h"

void CompoundPart::render(SDLBackend *renderer, int xoffset, int yoffset) {
	renderer->render(getSprite(), getCurrentSprite(), xoffset + x, yoffset + y, is_transparent, transparency);
}

CompoundPart::CompoundPart(unsigned int _id, std::string spritefile, unsigned int fimg,
						unsigned int _x, unsigned int _y, unsigned int _z) {
	id = _id;
	firstimg = fimg;
	x = _x;
	y = _y;
	zorder = _z;
	sprite = gallery.getImage(spritefile);
	caos_assert(sprite);
	pose = 0;
	base = 0;
	is_transparent = false;
	framerate = 1;
	framedelay = 0;
}

DullPart::DullPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
			 unsigned int _z) : CompoundPart(_id, spritefile, fimg, _x, _y, _z) {
}

ButtonPart::ButtonPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
	unsigned int _z, const bytestring &animhover, int msgid, int option) : CompoundPart(_id, spritefile, fimg, _x, _y, _z) {
	messageid = msgid;
	hitopaquepixelsonly = (option == 1);
	hoveranimation = animhover;
}

FixedTextPart::FixedTextPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
		                                  unsigned int _z, std::string fontsprite) : TextPart(_id, spritefile, fimg, _x, _y, _z) {
	// TODO: load fontsprite
}

TextEntryPart::TextEntryPart(unsigned int _id, std::string spritefile, unsigned int fimg, unsigned int _x, unsigned int _y,
		                                  unsigned int _z, unsigned int msgid, std::string fontsprite) : TextPart(_id, spritefile, fimg, _x, _y, _z) {
	// TODO: load fontsprite, msgid
}

void CompoundPart::tick() {
	if (!animation.empty()) {
                if (framerate > 1) {
			framedelay++;
			if (framedelay == framerate + 1)
				framedelay = 0;
		}

		if (framedelay == 0) {
			unsigned int f = frameno + 1;
			if (f == animation.size()) return;
			if (animation[f] == 255) {
				if (f == (animation.size() - 1)) f = 0;
				else f = animation[f + 1];
			}
			setFrameNo(f);
		}
	}
}

/* vim: set noet: */

<|endoftext|>


<commit_before>#include "ComputeUtils.h"
#include "LuaUtils.h"
#include <pthread.h>

#ifdef _WIN32
	#include <Windows.h>
#else
	#include <dlfcn.h>
#endif

//
struct ComputeDevices {
#ifdef WANT_CUDA
//	COMPUTE_LIB mCUDA;	//
#endif

#ifdef WANT_METAL
//    MTLDevice mMetalDevice;
#endif
};

//
static bool Exists (const char * name)
{
#ifdef _WIN32
	HMODULE lib = LoadLibraryA(name);
#else
	void * lib = dlopen(name, RTLD_NOW);
#endif

	if (lib != NULL)
	{
#ifdef _WIN32
		FreeLibrary(lib);
#else
		dlclose(lib);
#endif
	}

	return lib != NULL;
}

// Global device info
static ComputeDevices * sDevices;

// Avoid conflicts while launching device queries
static pthread_mutex_t s_DevicesInit = PTHREAD_MUTEX_INITIALIZER;

#ifdef WANT_CUDA

#include <cuda.h>
#include <cuda_runtime_api.h>

static bool CheckCUDA (ComputeCaps & caps)
{
	if (!Exists(
#ifdef _WIN32
		"nvcuda.dll"
#else
		"libcuda.so"
#endif
	)) return false;

	int count;

    if (CUDA_SUCCESS != cuInit(0)) return false;
    if (CUDA_SUCCESS != cuDeviceGetCount(&count)) return false;

	caps.mDevicesCUDA.resize(size_t(count));

    for (int i = 0; i < count; i++)
    {
        ComputeCaps::DeviceInfoCUDA & dev = caps.mDevicesCUDA[i];
/*
struct cudaDeviceProp deviceProp;
if(cudaGetDeviceProperties(&deviceProp,i) == CUDA_SUCCESS)

  {
	  int m,n;
	 cuDeviceComputeCapability(&m, &n, i);

	 unsigned long memory = (unsigned long)deviceProp.totalGlobalMem;

	 memory = memory / 1024;

	 memory = memory / 1024;

	 printf("Device Name: %s", deviceProp.name);

	 printf("Device Computer Capability: %d.%d", m, n);

	 printf("\nMem Size: %lu \n", memory);

	 printf("Max Threads: %d\n", deviceProp.maxThreadsPerBlock);

	 printf("Max Threads Dim[x?]: %d\n", deviceProp.maxThreadsDim[0]);

	 printf("Max Threads Dim[y?]: %d\n", deviceProp.maxThreadsDim[1]);

	 printf("Max Threads Dim[z?]: %d\n", deviceProp.maxThreadsDim[2]);

	 printf("Max Grid Size[x?]: %d\n", deviceProp.maxGridSize[0]);

	 printf("Max Grid Size[y?]: %d\n", deviceProp.maxGridSize[1]);

	 printf("Max Grid Size[z?]: %d\n", deviceProp.maxGridSize[2]);

  }
  */
        if (CUDA_SUCCESS != cuDeviceComputeCapability(&dev.mMajor, &dev.mMinor, i)) return false;
printf("%i, %i, %i!\n", i, dev.mMajor, dev.mMinor);
		// ^^ TODO: Detect minimum acceptable version... (test on better device!)
    }

	return true;
}

#endif
//#include <iostream>
bool CheckComputeSupport (lua_State * L, ComputeCaps & caps)
{
	if (!IsMainState(L)) return false;

	caps.mFlags = 0;

	ComputeDevices * cd = (ComputeDevices *)lua_newuserdata(L, sizeof(ComputeDevices));	// ..., devices

	// TODO: Check C++ AMP support? (DirectX11 caps? otherwise have to include that .exe...)
	// vs. https://github.com/debdattabasu/amp-radix-sort/blob/master/amp_sort/main.cpp#L14
	#ifdef WANT_AMP
		caps.mAccelerators = concurrency::accelerator::get_all();
/*
http://stackoverflow.com/a/7533864
TODO: investigate some more, suss out most useful fields
    std::for_each(begin(caps.mAccelerators), end(caps.mAccelerators),[=](concurrency::accelerator acc){
        std::wcout << "New accelerator: " << acc.description << std::endl;
        std::wcout << "is_debug = " << acc.is_debug << std::endl;
        std::wcout << "is_emulated = " << acc.is_emulated <<std::endl;
        std::wcout << "dedicated_memory = " << acc.dedicated_memory << std::endl;
        std::wcout << "device_path = " << acc.device_path << std::endl;
        std::wcout << "has_display = " << acc.has_display << std::endl;
        std::wcout << "version = " << (acc.version >> 16) << '.' << (acc.version & 0xFFFF) << std::endl;
    });
*/
		if (!caps.mAccelerators.empty()) caps.mFlags |= ComputeCaps::eAMP; // Probably too liberal (e.g. emulated stuff unlikely to be much good)
	#endif

	#ifdef WANT_CUDA
		if (CheckCUDA(caps)) caps.mFlags |= ComputeCaps::eCUDA;
	#endif

	#ifdef WANT_METAL
    /*
		cd->mMetalDevice = MTLCreateSystemDefaultDevice();

		if (cd->mMetalDevice) caps.mFlags |= ComputeCaps::eMetal;
    */
	#endif

	AttachGC(L, "compute_devices", [](lua_State * L)
	{
		ShutDownBackend(ComputeCaps::eCUDA);
		ShutDownBackend(ComputeCaps::eMetal);
		ShutDownBackend(ComputeCaps::eOpenCL);
		ShutDownBackend(ComputeCaps::eRenderScript);

		return 0;
	});

	pthread_mutex_lock(&s_DevicesInit);

	sDevices = cd;

	pthread_mutex_unlock(&s_DevicesInit);

	return true;
}

void ShutDownBackend (ComputeCaps::Flag flag)
{
	pthread_mutex_lock(&s_DevicesInit);	// wait for any initialization
	pthread_mutex_unlock(&s_DevicesInit);

	if (!sDevices) return;

	switch (flag)
	{
	case ComputeCaps::eAMP:
	#ifdef WANT_AMP
		// TODO!
	#endif
		break;
	case ComputeCaps::eCUDA:
	#ifdef WANT_CUDA
		// TODO!
	#endif
		break;
	case ComputeCaps::eMetal:
	#ifdef WANT_METAL
	/*	if (mMetalDevice) ;

		mMetalDevice = NULL;*/
	#endif
		break;
	case ComputeCaps::eOpenCL:
	#ifdef WANT_OPENCL
		// TODO!
		// http://arrayfire.com/getting-started-with-opencl-on-android/
		// http://arrayfire.com/opencl-on-mobile-devices/
		// https://stackoverflow.com/questions/26795921/does-android-support-opencl
		// https://streamcomputing.eu/blog/2014-06-30/opencl-support-recent-android-smartphones/
	#endif
		break;
	case ComputeCaps::eRenderScript:
	#ifdef WANT_RENDERSCRIPT
		// TODO!
		// https://possiblemobile.com/2013/10/renderscript-for-all/
	#endif
		break;
	}
}

#undef COMPUTE_LIB
#undef COMPUTE_PROC
#undef _CUDA_API_<commit_msg>Commented out header (no good on Mac yet)<commit_after>#include "ComputeUtils.h"
#include "LuaUtils.h"
#include <pthread.h>

#ifdef _WIN32
	#include <Windows.h>
#else
	#include <dlfcn.h>
#endif

//
struct ComputeDevices {
#ifdef WANT_CUDA
//	COMPUTE_LIB mCUDA;	//
#endif

#ifdef WANT_METAL
//    MTLDevice mMetalDevice;
#endif
};

//
static bool Exists (const char * name)
{
#ifdef _WIN32
	HMODULE lib = LoadLibraryA(name);
#else
	void * lib = dlopen(name, RTLD_NOW);
#endif

	if (lib != NULL)
	{
#ifdef _WIN32
		FreeLibrary(lib);
#else
		dlclose(lib);
#endif
	}

	return lib != NULL;
}

// Global device info
static ComputeDevices * sDevices;

// Avoid conflicts while launching device queries
static pthread_mutex_t s_DevicesInit = PTHREAD_MUTEX_INITIALIZER;

#ifdef WANT_CUDA

#include <cuda.h>
//#include <cuda_runtime_api.h>

static bool CheckCUDA (ComputeCaps & caps)
{
	if (!Exists(
#ifdef _WIN32
		"nvcuda.dll"
#else
		"libcuda.so"
#endif
	)) return false;

	int count;

    if (CUDA_SUCCESS != cuInit(0)) return false;
    if (CUDA_SUCCESS != cuDeviceGetCount(&count)) return false;

	caps.mDevicesCUDA.resize(size_t(count));

    for (int i = 0; i < count; i++)
    {
        ComputeCaps::DeviceInfoCUDA & dev = caps.mDevicesCUDA[i];
/*
struct cudaDeviceProp deviceProp;
if(cudaGetDeviceProperties(&deviceProp,i) == CUDA_SUCCESS)

  {
	  int m,n;
	 cuDeviceComputeCapability(&m, &n, i);

	 unsigned long memory = (unsigned long)deviceProp.totalGlobalMem;

	 memory = memory / 1024;

	 memory = memory / 1024;

	 printf("Device Name: %s", deviceProp.name);

	 printf("Device Computer Capability: %d.%d", m, n);

	 printf("\nMem Size: %lu \n", memory);

	 printf("Max Threads: %d\n", deviceProp.maxThreadsPerBlock);

	 printf("Max Threads Dim[x?]: %d\n", deviceProp.maxThreadsDim[0]);

	 printf("Max Threads Dim[y?]: %d\n", deviceProp.maxThreadsDim[1]);

	 printf("Max Threads Dim[z?]: %d\n", deviceProp.maxThreadsDim[2]);

	 printf("Max Grid Size[x?]: %d\n", deviceProp.maxGridSize[0]);

	 printf("Max Grid Size[y?]: %d\n", deviceProp.maxGridSize[1]);

	 printf("Max Grid Size[z?]: %d\n", deviceProp.maxGridSize[2]);

  }
  */
        if (CUDA_SUCCESS != cuDeviceComputeCapability(&dev.mMajor, &dev.mMinor, i)) return false;
printf("%i, %i, %i!\n", i, dev.mMajor, dev.mMinor);
		// ^^ TODO: Detect minimum acceptable version... (test on better device!)
    }

	return true;
}

#endif
//#include <iostream>
bool CheckComputeSupport (lua_State * L, ComputeCaps & caps)
{
	if (!IsMainState(L)) return false;

	caps.mFlags = 0;

	ComputeDevices * cd = (ComputeDevices *)lua_newuserdata(L, sizeof(ComputeDevices));	// ..., devices

	// TODO: Check C++ AMP support? (DirectX11 caps? otherwise have to include that .exe...)
	// vs. https://github.com/debdattabasu/amp-radix-sort/blob/master/amp_sort/main.cpp#L14
	#ifdef WANT_AMP
		caps.mAccelerators = concurrency::accelerator::get_all();
/*
http://stackoverflow.com/a/7533864
TODO: investigate some more, suss out most useful fields
    std::for_each(begin(caps.mAccelerators), end(caps.mAccelerators),[=](concurrency::accelerator acc){
        std::wcout << "New accelerator: " << acc.description << std::endl;
        std::wcout << "is_debug = " << acc.is_debug << std::endl;
        std::wcout << "is_emulated = " << acc.is_emulated <<std::endl;
        std::wcout << "dedicated_memory = " << acc.dedicated_memory << std::endl;
        std::wcout << "device_path = " << acc.device_path << std::endl;
        std::wcout << "has_display = " << acc.has_display << std::endl;
        std::wcout << "version = " << (acc.version >> 16) << '.' << (acc.version & 0xFFFF) << std::endl;
    });
*/
		if (!caps.mAccelerators.empty()) caps.mFlags |= ComputeCaps::eAMP; // Probably too liberal (e.g. emulated stuff unlikely to be much good)
	#endif

	#ifdef WANT_CUDA
		if (CheckCUDA(caps)) caps.mFlags |= ComputeCaps::eCUDA;
	#endif

	#ifdef WANT_METAL
    /*
		cd->mMetalDevice = MTLCreateSystemDefaultDevice();

		if (cd->mMetalDevice) caps.mFlags |= ComputeCaps::eMetal;
    */
	#endif

	AttachGC(L, "compute_devices", [](lua_State * L)
	{
		ShutDownBackend(ComputeCaps::eCUDA);
		ShutDownBackend(ComputeCaps::eMetal);
		ShutDownBackend(ComputeCaps::eOpenCL);
		ShutDownBackend(ComputeCaps::eRenderScript);

		return 0;
	});

	pthread_mutex_lock(&s_DevicesInit);

	sDevices = cd;

	pthread_mutex_unlock(&s_DevicesInit);

	return true;
}

void ShutDownBackend (ComputeCaps::Flag flag)
{
	pthread_mutex_lock(&s_DevicesInit);	// wait for any initialization
	pthread_mutex_unlock(&s_DevicesInit);

	if (!sDevices) return;

	switch (flag)
	{
	case ComputeCaps::eAMP:
	#ifdef WANT_AMP
		// TODO!
	#endif
		break;
	case ComputeCaps::eCUDA:
	#ifdef WANT_CUDA
		// TODO!
	#endif
		break;
	case ComputeCaps::eMetal:
	#ifdef WANT_METAL
	/*	if (mMetalDevice) ;

		mMetalDevice = NULL;*/
	#endif
		break;
	case ComputeCaps::eOpenCL:
	#ifdef WANT_OPENCL
		// TODO!
		// http://arrayfire.com/getting-started-with-opencl-on-android/
		// http://arrayfire.com/opencl-on-mobile-devices/
		// https://stackoverflow.com/questions/26795921/does-android-support-opencl
		// https://streamcomputing.eu/blog/2014-06-30/opencl-support-recent-android-smartphones/
	#endif
		break;
	case ComputeCaps::eRenderScript:
	#ifdef WANT_RENDERSCRIPT
		// TODO!
		// https://possiblemobile.com/2013/10/renderscript-for-all/
	#endif
		break;
	}
}

#undef COMPUTE_LIB
#undef COMPUTE_PROC
#undef _CUDA_API_<|endoftext|>


<commit_before>#include "ofApp.h"

//------------------------------------------------------------------------------
void ofApp::setup()
{
    ofSetFrameRate(30);
    ofEnableAlphaBlending();
}

//------------------------------------------------------------------------------
void ofApp::draw()
{
    ofBackground(0);

    // get the current time
    unsigned long long now = ofGetElapsedTimeMillis();

    // cycle through the rectangles
    for(int i = 0; i < numRectangles; i++)
    {
        // if now is past the next scheduled blink time
        if(now > nextRectangleBlinkTime[i])
        {
            // schedule the next blink time
            nextRectangleBlinkTime[i] = now + rectangleDelays[i];
            // toggle the rectangle state
            rectangleState[i] = !rectangleState[i];
        }

        // draw the rectangles
        if(rectangleState[i])
        {
            // draw an unfilled rectangle if the state is "true"
            ofNoFill();
        }
        else
        {
            // draw a filled rectangle if the state is "false"
            ofFill();
        }

        ofSetColor(ofColor::yellow);
        ofRect(rectangles[i]);

        // Uncomment the following to draw based on the amount of time left
        // before the next blink happens.

//        unsigned long long timeUntilNextBlink = nextRectangleBlinkTime[i] - now;
//
//        float percent = ofNormalize(timeUntilNextBlink,0,rectangleDelays[i]);
//
//        ofFill();
//        ofSetColor(255,0,0);
//        ofRect(rectangles[i].x,
//               rectangles[i].y + rectangles[i].height,
//               10,
//               -rectangles[i].height * percent);

    }
}
<commit_msg>Cleanup.<commit_after>#include "ofApp.h"

//------------------------------------------------------------------------------
void ofApp::setup()
{
    ofSetFrameRate(30);
    ofEnableAlphaBlending();
}

//------------------------------------------------------------------------------
void ofApp::draw()
{

    ofBackground(0);

    // get the current time
    unsigned long long now = ofGetElapsedTimeMillis();

    // cycle through the rectangles
    for(int i = 0; i < numRectangles; i++)
    {
        // if now is past the next scheduled blink time
        if(now > nextRectangleBlinkTime[i])
        {
            // schedule the next blink time
            nextRectangleBlinkTime[i] = now + rectangleDelays[i];
            // toggle the rectangle state
            rectangleState[i] = !rectangleState[i];
        }

        // draw the rectangles
        if(rectangleState[i])
        {
            // draw an unfilled rectangle if the state is "true"
            ofNoFill();
        }
        else
        {
            // draw a filled rectangle if the state is "false"
            ofFill();
        }

        ofSetColor(ofColor::yellow);
        ofRect(rectangles[i]);

        // Uncomment the following to draw based on the amount of time left
        // before the next blink happens.

//        unsigned long long timeUntilNextBlink = nextRectangleBlinkTime[i] - now;
//
//        float percent = ofNormalize(timeUntilNextBlink,0,rectangleDelays[i]);
//
//        ofFill();
//        ofSetColor(255,0,0);
//        ofRect(rectangles[i].x,
//               rectangles[i].y + rectangles[i].height,
//               10,
//               -rectangles[i].height * percent);

    }
}
<|endoftext|>


<commit_before>//@author A0097630B
#include "stdafx.h"
#include "query_executor.h"
#include "../exceptions/context_index_out_of_range_exception.h"
#include "../result.h"
#include "query_executor_builder_visitor.h"

namespace You {
namespace Controller {
namespace Internal {

using You::NLP::QUERY;
using You::NLP::ADD_QUERY;
using You::NLP::EDIT_QUERY;
using You::NLP::DELETE_QUERY;

QueryExecutorBuilderVisitor::QueryExecutorBuilderVisitor(
	const Controller::Context& context)
	: context(context) {
}

std::unique_ptr<QueryExecutor>
QueryExecutorBuilderVisitor::build(const ADD_QUERY& query) {
	class AddTaskQueryExecutor : public QueryExecutor {
	public:
		explicit AddTaskQueryExecutor(
			std::unique_ptr<QueryEngine::Query>&& query)
			: QueryExecutor(std::move(query)) {
		}

		virtual ~AddTaskQueryExecutor() = default;

	protected:
		Result processResponse(
			const You::QueryEngine::Response& response) override {
			return ADD_RESULT {
				boost::get<Task>(response)
			};
		}
	};

	return std::unique_ptr<QueryExecutor>(
		new AddTaskQueryExecutor(
			QueryEngine::AddTask(
				query.description,
				query.deadline ? query.deadline.get() : Task::DEFAULT_DEADLINE,
				query.priority == You::NLP::TaskPriority::HIGH ?
					Task::Priority::IMPORTANT : Task::Priority::NORMAL,
				Task::Dependencies()
			)
		)
	);
}

std::unique_ptr<QueryExecutor>
QueryExecutorBuilderVisitor::build(const EDIT_QUERY& query) const {
	class EditTaskQueryExecutor : public QueryExecutor {
	public:
		explicit EditTaskQueryExecutor(
			std::unique_ptr<QueryEngine::Query>&& query)
			: QueryExecutor(std::move(query)) {
		}

		virtual ~EditTaskQueryExecutor() = default;

	protected:
		Result processResponse(
			const You::QueryEngine::Response& response) override {
			return EDIT_RESULT {
				boost::get<Task>(response)
			};
		}
	};

	try {
		const Task& task = context.at(query.taskID);
		std::wstring description = query.description ?
			query.description.get() :
			Task::DEFAULT_DESCRIPTION;
		boost::posix_time::ptime deadline = query.deadline ?
			query.deadline.get() :
			Task::DEFAULT_DEADLINE;
		Task::Priority priority = query.priority ?
			(query.priority == You::NLP::TaskPriority::HIGH ?
				Task::Priority::IMPORTANT : Task::Priority::NORMAL) :
			Task::DEFAULT_PRIORITY;

		return std::unique_ptr<QueryExecutor>(
			new EditTaskQueryExecutor(
				QueryEngine::UpdateTask(
					task.getID(),
					description,
					deadline,
					Task::DEFAULT_PRIORITY,
					Task::Dependencies()
				)
			)
		);
	} catch (std::out_of_range& e) {
		throw ContextIndexOutOfRangeException(e);
	}
}

std::unique_ptr<QueryExecutor>
QueryExecutorBuilderVisitor::build(const DELETE_QUERY& query) const {
	class DeleteTaskQueryExecutor : public QueryExecutor {
	public:
		explicit DeleteTaskQueryExecutor(
			std::unique_ptr<QueryEngine::Query>&& query)
			: QueryExecutor(std::move(query)) {
		}

		virtual ~DeleteTaskQueryExecutor() = default;

	protected:
		Result processResponse(
			const You::QueryEngine::Response& response) override {
			return DELETE_RESULT {
				boost::get<Task::ID>(response)
			};
		}
	};

	try {
		const Task& task = context.at(query.taskID);

		return std::unique_ptr<QueryExecutor>(
			new DeleteTaskQueryExecutor(
				QueryEngine::DeleteTask(
					task.getID()
				)
			)
		);
	} catch (std::out_of_range& e) {
		throw ContextIndexOutOfRangeException(e);
	}
}

}  // namespace Internal
}  // namespace Controller
}  // namespace You
<commit_msg>Fix lints.<commit_after>//@author A0097630B
#include "stdafx.h"
#include "query_executor.h"
#include "../exceptions/context_index_out_of_range_exception.h"
#include "../result.h"
#include "query_executor_builder_visitor.h"

namespace You {
namespace Controller {
namespace Internal {

using You::NLP::QUERY;
using You::NLP::ADD_QUERY;
using You::NLP::EDIT_QUERY;
using You::NLP::DELETE_QUERY;

QueryExecutorBuilderVisitor::QueryExecutorBuilderVisitor(
	const Controller::Context& context)
	: context(context) {
}

std::unique_ptr<QueryExecutor>
QueryExecutorBuilderVisitor::build(const ADD_QUERY& query) {
	class AddTaskQueryExecutor : public QueryExecutor {
	public:
		explicit AddTaskQueryExecutor(
			std::unique_ptr<QueryEngine::Query>&& query)
			: QueryExecutor(std::move(query)) {
		}

		virtual ~AddTaskQueryExecutor() = default;

	protected:
		Result processResponse(
			const You::QueryEngine::Response& response) override {
			return ADD_RESULT {
				boost::get<Task>(response)
			};
		}
	};

	return std::unique_ptr<QueryExecutor>(
		new AddTaskQueryExecutor(
			QueryEngine::AddTask(
				query.description,
				query.deadline ? query.deadline.get() : Task::DEFAULT_DEADLINE,
				query.priority == You::NLP::TaskPriority::HIGH ?
					Task::Priority::IMPORTANT : Task::Priority::NORMAL,
				Task::Dependencies()
			)
		)
	);
}

std::unique_ptr<QueryExecutor>
QueryExecutorBuilderVisitor::build(const EDIT_QUERY& query) const {
	class EditTaskQueryExecutor : public QueryExecutor {
	public:
		explicit EditTaskQueryExecutor(
			std::unique_ptr<QueryEngine::Query>&& query)
			: QueryExecutor(std::move(query)) {
		}

		virtual ~EditTaskQueryExecutor() = default;

	protected:
		Result processResponse(
			const You::QueryEngine::Response& response) override {
			return EDIT_RESULT {
				boost::get<Task>(response)
			};
		}
	};

	try {
		const Task& task = context.at(query.taskID);
		std::wstring description = query.description ?
			query.description.get() :
			Task::DEFAULT_DESCRIPTION;
		boost::posix_time::ptime deadline = query.deadline ?
			query.deadline.get() :
			Task::DEFAULT_DEADLINE;
		Task::Priority priority = query.priority ?
			(query.priority == You::NLP::TaskPriority::HIGH ?
				Task::Priority::IMPORTANT : Task::Priority::NORMAL) :
			Task::DEFAULT_PRIORITY;

		return std::unique_ptr<QueryExecutor>(
			new EditTaskQueryExecutor(
				QueryEngine::UpdateTask(
					task.getID(),
					description,
					deadline,
					Task::DEFAULT_PRIORITY,
					Task::Dependencies())));
	} catch (std::out_of_range& e) {
		throw ContextIndexOutOfRangeException(e);
	}
}

std::unique_ptr<QueryExecutor>
QueryExecutorBuilderVisitor::build(const DELETE_QUERY& query) const {
	class DeleteTaskQueryExecutor : public QueryExecutor {
	public:
		explicit DeleteTaskQueryExecutor(
			std::unique_ptr<QueryEngine::Query>&& query)
			: QueryExecutor(std::move(query)) {
		}

		virtual ~DeleteTaskQueryExecutor() = default;

	protected:
		Result processResponse(
			const You::QueryEngine::Response& response) override {
			return DELETE_RESULT {
				boost::get<Task::ID>(response)
			};
		}
	};

	try {
		const Task& task = context.at(query.taskID);

		return std::unique_ptr<QueryExecutor>(
			new DeleteTaskQueryExecutor(
				QueryEngine::DeleteTask(
					task.getID())));
	} catch (std::out_of_range& e) {
		throw ContextIndexOutOfRangeException(e);
	}
}

}  // namespace Internal
}  // namespace Controller
}  // namespace You
<|endoftext|>