<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetManager.cpp
 */

#include "./JPetManager.h"

#include <cassert>
#include <string>
#include <exception>

#include "../JPetLoggerInclude.h"
#include "../JPetCommonTools/JPetCommonTools.h"
#include "../DBHandler/HeaderFiles/DBHandler.h"
#include "../JPetCmdParser/JPetCmdParser.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetUnzipAndUnpackTask/JPetUnzipAndUnpackTask.h"
#include "../JPetOptionsGenerator/JPetOptionsGenerator.h"

#include <TThread.h>

using namespace jpet_options_tools;

JPetManager::JPetManager()
{
  fTaskGeneratorChain = new TaskGeneratorChain;
}

JPetManager& JPetManager::getManager()
{
  static JPetManager instance;
  return instance;
}

bool JPetManager::areThreadsEnabled() const
{
  return fThreadsEnabled;
}

void JPetManager::setThreadsEnabled(bool enable)
{
  fThreadsEnabled = enable;
}

bool JPetManager::run(int argc, const char** argv)
{
  if (!parseCmdLine(argc, argv)) {
    ERROR("While parsing command line arguments");
    return false;
  }
  INFO( "======== Starting processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  std::vector<JPetTaskChainExecutor*> executors;
  std::vector<TThread*> threads;
  auto inputDataSeq = 0;
  /// For every input option, new TaskChainExecutor is created, which creates the chain of previously
  /// registered tasks. The inputDataSeq is the identifier of given chain.
  for (auto opt : fOptions) {
    JPetTaskChainExecutor* executor = new JPetTaskChainExecutor(fTaskGeneratorChain, inputDataSeq, opt.second);
    executors.push_back(executor);
    if (areThreadsEnabled()) {
      auto thr = executor->run();
      if (thr) {
        threads.push_back(thr);
      } else {
        ERROR("thread pointer is null");
      }
    } else {
      if (!executor->process()) {
        ERROR("While running process");
        return false;
      }
    }
    inputDataSeq++;
  }
  if (areThreadsEnabled()) {
    for (auto thread : threads) {
      assert(thread);
      thread->Join();
    }
  }
  for (auto& executor : executors) {
    if (executor) {
      delete executor;
      executor = 0;
    }
  }
  INFO( "======== Finished processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  return true;
}

bool JPetManager::parseCmdLine(int argc, const char** argv)
{
  auto addDefaultTasksFromOptions = [&](const std::map<std::string, boost::any>& options) {
    auto fileType = FileTypeChecker::getInputFileType(options);
    if (fileType == FileTypeChecker::kScope) {
      auto task2 = []() {
        return new JPetScopeLoader(std::unique_ptr<JPetScopeTask>(new JPetScopeTask("JPetScopeReader")));
      };
      fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task2);
    }
    /// add task to unzip or unpack if needed
    auto task = []() {
      return new JPetUnzipAndUnpackTask("UnpackerAndUnzipper");
    };
    fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task);
  };

  try {
    JPetOptionsGenerator optionsGenerator;
    JPetCmdParser parser;
    auto optionsFromCmdLine = parser.parseCmdLineArgs(argc, argv);
    /// One  common map of all options
    auto allValidatedOptions = optionsGenerator.generateAndValidateOptions(optionsFromCmdLine);
    addDefaultTasksFromOptions(allValidatedOptions);

    int numberOfRegisteredTasks = 1;
    if (fTaskGeneratorChain) {
      numberOfRegisteredTasks = fTaskGeneratorChain->size();
    }
    fOptions  = optionsGenerator.generateOptionsForTasks(allValidatedOptions, numberOfRegisteredTasks);
  } catch (std::exception& e) {
    ERROR(e.what());
    return false;
  }
  return true;
}

//
JPetManager::~JPetManager()
{
  /// delete shared caches for paramBanks
  /// @todo I think that should be changed
  JPetDBParamGetter::clearParamCache();
}

void JPetManager::useTask(const char* name, const char* inputFileType, const char* outputFileType){
  assert(fTaskGeneratorChain);
  if( fTasksDictionary.count(name) > 0 ){
    TaskGenerator userTaskGen = fTasksDictionary.at(name);
    // wrap the JPetUserTask-based task in a JPetTaskIO
    fTaskGeneratorChain->push_back( [name, inputFileType, outputFileType, userTaskGen]() {
	JPetTaskIO * task = new JPetTaskIO(name, inputFileType, outputFileType);
	task->setSubTask(std::unique_ptr<JPetTaskInterface>(userTaskGen()));
	return task;
      });
  }else{
    ERROR(Form("The requested task %s is unknown", name));
    exit(1);
  }
}

JPetManager::Options JPetManager::getOptions() const
{
  return fOptions;
}

/**
 * @brief Initialize connection to database if such connection is necessary
 *
 * @param configFilePath path to the config file with database connection details
 *
 * @return true if database connection was required and initialization was called,
 * false if database connection was not required and its initialization was skipped
 *
 * Database connection is only initialized if the user provided the run number
 * ("-i" option) and did not provide local database ("-l") at the same time.
 */
bool JPetManager::initDBConnection(const char* configFilePath)
{
  bool isDBrequired = false;

  if (fOptions.size() > 0) { // If at least one input file to process.
    auto optsVect = fOptions.begin()->second;
    if (optsVect.size() > 0) {
      auto opt = optsVect.front();
      if (getRunNumber(opt) >= 0) { // if run number is not default -1
        if (!isLocalDB(opt)) { // unless local DB file was provided
          isDBrequired = true;
        }
      }
    }
  }
  if (isDBrequired) {
    INFO("Attempting to set up connection to the database.");
    DB::SERVICES::DBHandler::createDBConnection(configFilePath);
  } else {
    INFO("Setting connection to database skipped.");
  }
  return isDBrequired;
}
<commit_msg>Adapt adding task in JPetManager to multiple subtasks version<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetManager.cpp
 */

#include "./JPetManager.h"

#include <cassert>
#include <string>
#include <exception>

#include "../JPetLoggerInclude.h"
#include "../JPetCommonTools/JPetCommonTools.h"
#include "../DBHandler/HeaderFiles/DBHandler.h"
#include "../JPetCmdParser/JPetCmdParser.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetUnzipAndUnpackTask/JPetUnzipAndUnpackTask.h"
#include "../JPetOptionsGenerator/JPetOptionsGenerator.h"

#include <TThread.h>

using namespace jpet_options_tools;

JPetManager::JPetManager()
{
  fTaskGeneratorChain = new TaskGeneratorChain;
}

JPetManager& JPetManager::getManager()
{
  static JPetManager instance;
  return instance;
}

bool JPetManager::areThreadsEnabled() const
{
  return fThreadsEnabled;
}

void JPetManager::setThreadsEnabled(bool enable)
{
  fThreadsEnabled = enable;
}

bool JPetManager::run(int argc, const char** argv)
{
  if (!parseCmdLine(argc, argv)) {
    ERROR("While parsing command line arguments");
    return false;
  }
  INFO( "======== Starting processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  std::vector<JPetTaskChainExecutor*> executors;
  std::vector<TThread*> threads;
  auto inputDataSeq = 0;
  /// For every input option, new TaskChainExecutor is created, which creates the chain of previously
  /// registered tasks. The inputDataSeq is the identifier of given chain.
  for (auto opt : fOptions) {
    JPetTaskChainExecutor* executor = new JPetTaskChainExecutor(fTaskGeneratorChain, inputDataSeq, opt.second);
    executors.push_back(executor);
    if (areThreadsEnabled()) {
      auto thr = executor->run();
      if (thr) {
        threads.push_back(thr);
      } else {
        ERROR("thread pointer is null");
      }
    } else {
      if (!executor->process()) {
        ERROR("While running process");
        return false;
      }
    }
    inputDataSeq++;
  }
  if (areThreadsEnabled()) {
    for (auto thread : threads) {
      assert(thread);
      thread->Join();
    }
  }
  for (auto& executor : executors) {
    if (executor) {
      delete executor;
      executor = 0;
    }
  }
  INFO( "======== Finished processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  return true;
}

bool JPetManager::parseCmdLine(int argc, const char** argv)
{
  auto addDefaultTasksFromOptions = [&](const std::map<std::string, boost::any>& options) {
    auto fileType = FileTypeChecker::getInputFileType(options);
    if (fileType == FileTypeChecker::kScope) {
      auto task2 = []() {
        return new JPetScopeLoader(std::unique_ptr<JPetScopeTask>(new JPetScopeTask("JPetScopeReader")));
      };
      fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task2);
    }
    /// add task to unzip or unpack if needed
    auto task = []() {
      return new JPetUnzipAndUnpackTask("UnpackerAndUnzipper");
    };
    fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task);
  };

  try {
    JPetOptionsGenerator optionsGenerator;
    JPetCmdParser parser;
    auto optionsFromCmdLine = parser.parseCmdLineArgs(argc, argv);
    /// One  common map of all options
    auto allValidatedOptions = optionsGenerator.generateAndValidateOptions(optionsFromCmdLine);
    addDefaultTasksFromOptions(allValidatedOptions);

    int numberOfRegisteredTasks = 1;
    if (fTaskGeneratorChain) {
      numberOfRegisteredTasks = fTaskGeneratorChain->size();
    }
    fOptions  = optionsGenerator.generateOptionsForTasks(allValidatedOptions, numberOfRegisteredTasks);
  } catch (std::exception& e) {
    ERROR(e.what());
    return false;
  }
  return true;
}

//
JPetManager::~JPetManager()
{
  /// delete shared caches for paramBanks
  /// @todo I think that should be changed
  JPetDBParamGetter::clearParamCache();
}

void JPetManager::useTask(const char* name, const char* inputFileType, const char* outputFileType){
  assert(fTaskGeneratorChain);
  if( fTasksDictionary.count(name) > 0 ){
    TaskGenerator userTaskGen = fTasksDictionary.at(name);
    // wrap the JPetUserTask-based task in a JPetTaskIO
    fTaskGeneratorChain->push_back( [name, inputFileType, outputFileType, userTaskGen]() {
	JPetTaskIO * task = new JPetTaskIO(name, inputFileType, outputFileType);
	task->addSubTask(std::unique_ptr<JPetTaskInterface>(userTaskGen()));
	return task;
      });
  }else{
    ERROR(Form("The requested task %s is unknown", name));
    exit(1);
  }
}

JPetManager::Options JPetManager::getOptions() const
{
  return fOptions;
}

/**
 * @brief Initialize connection to database if such connection is necessary
 *
 * @param configFilePath path to the config file with database connection details
 *
 * @return true if database connection was required and initialization was called,
 * false if database connection was not required and its initialization was skipped
 *
 * Database connection is only initialized if the user provided the run number
 * ("-i" option) and did not provide local database ("-l") at the same time.
 */
bool JPetManager::initDBConnection(const char* configFilePath)
{
  bool isDBrequired = false;

  if (fOptions.size() > 0) { // If at least one input file to process.
    auto optsVect = fOptions.begin()->second;
    if (optsVect.size() > 0) {
      auto opt = optsVect.front();
      if (getRunNumber(opt) >= 0) { // if run number is not default -1
        if (!isLocalDB(opt)) { // unless local DB file was provided
          isDBrequired = true;
        }
      }
    }
  }
  if (isDBrequired) {
    INFO("Attempting to set up connection to the database.");
    DB::SERVICES::DBHandler::createDBConnection(configFilePath);
  } else {
    INFO("Setting connection to database skipped.");
  }
  return isDBrequired;
}
<|endoftext|>


<commit_before>#include "source/common/quic/client_connection_factory_impl.h"
#include "source/common/quic/quic_transport_socket_factory.h"

#include "test/common/upstream/utility.h"
#include "test/mocks/common.h"
#include "test/mocks/event/mocks.h"
#include "test/mocks/server/transport_socket_factory_context.h"
#include "test/mocks/ssl/mocks.h"
#include "test/mocks/upstream/cluster_info.h"
#include "test/mocks/upstream/host.h"
#include "test/test_common/environment.h"
#include "test/test_common/network_utility.h"
#include "test/test_common/simulated_time_system.h"

using testing::Return;

namespace Envoy {
namespace Quic {

class QuicNetworkConnectionTest : public Event::TestUsingSimulatedTime, public testing::Test {
protected:
  void initialize() {
    test_address_ = Network::Utility::resolveUrl(absl::StrCat(
        "tcp://",
        Network::Test::getLoopbackAddressString(TestEnvironment::getIpVersionsForTest()[0]),
        ":30"));
    Ssl::ClientContextSharedPtr context{new Ssl::MockClientContext()};
    EXPECT_CALL(context_.context_manager_, createSslClientContext(_, _, _))
        .WillOnce(Return(context));
    factory_ = std::make_unique<Quic::QuicClientTransportSocketFactory>(
        std::unique_ptr<Envoy::Ssl::ClientContextConfig>(
            new NiceMock<Ssl::MockClientContextConfig>),
        context_);
  }

  uint32_t highWatermark(EnvoyQuicClientSession* session) {
    return session->write_buffer_watermark_simulation_.highWatermark();
  }

  NiceMock<Event::MockDispatcher> dispatcher_;
  std::shared_ptr<Upstream::MockClusterInfo> cluster_{new NiceMock<Upstream::MockClusterInfo>()};
  Upstream::HostSharedPtr host_{new NiceMock<Upstream::MockHost>};
  NiceMock<Random::MockRandomGenerator> random_;
  Upstream::ClusterConnectivityState state_;
  Network::Address::InstanceConstSharedPtr test_address_;
  NiceMock<Server::Configuration::MockTransportSocketFactoryContext> context_;
  std::unique_ptr<Quic::QuicClientTransportSocketFactory> factory_;
  Stats::IsolatedStoreImpl store_;
  QuicStatNames quic_stat_names_{store_.symbolTable()};
};

TEST_F(QuicNetworkConnectionTest, BufferLimits) {
  initialize();

  quic::QuicConfig config;
  PersistentQuicInfoImpl info{dispatcher_, *factory_, simTime(), test_address_, config, 45};

  std::unique_ptr<Network::ClientConnection> client_connection = createQuicNetworkConnection(
      info, dispatcher_, test_address_, test_address_, quic_stat_names_, store_);
  EnvoyQuicClientSession* session = static_cast<EnvoyQuicClientSession*>(client_connection.get());
  session->Initialize();
  client_connection->connect();
  EXPECT_TRUE(client_connection->connecting());
  ASSERT(session != nullptr);
  EXPECT_EQ(highWatermark(session), 45);
  EXPECT_EQ(absl::nullopt, session->unixSocketPeerCredentials());
  EXPECT_EQ(absl::nullopt, session->lastRoundTripTime());
  client_connection->close(Network::ConnectionCloseType::NoFlush);
}

} // namespace Quic
} // namespace Envoy
<commit_msg>test: fixing test for v6 only environments (#18593)<commit_after>#include "source/common/quic/client_connection_factory_impl.h"
#include "source/common/quic/quic_transport_socket_factory.h"

#include "test/common/upstream/utility.h"
#include "test/mocks/common.h"
#include "test/mocks/event/mocks.h"
#include "test/mocks/server/transport_socket_factory_context.h"
#include "test/mocks/ssl/mocks.h"
#include "test/mocks/upstream/cluster_info.h"
#include "test/mocks/upstream/host.h"
#include "test/test_common/environment.h"
#include "test/test_common/network_utility.h"
#include "test/test_common/simulated_time_system.h"

using testing::Return;

namespace Envoy {
namespace Quic {

class QuicNetworkConnectionTest : public Event::TestUsingSimulatedTime,
                                  public testing::TestWithParam<Network::Address::IpVersion> {
protected:
  void initialize() {
    test_address_ = Network::Utility::resolveUrl(
        absl::StrCat("tcp://", Network::Test::getLoopbackAddressUrlString(GetParam()), ":30"));
    Ssl::ClientContextSharedPtr context{new Ssl::MockClientContext()};
    EXPECT_CALL(context_.context_manager_, createSslClientContext(_, _, _))
        .WillOnce(Return(context));
    factory_ = std::make_unique<Quic::QuicClientTransportSocketFactory>(
        std::unique_ptr<Envoy::Ssl::ClientContextConfig>(
            new NiceMock<Ssl::MockClientContextConfig>),
        context_);
  }

  uint32_t highWatermark(EnvoyQuicClientSession* session) {
    return session->write_buffer_watermark_simulation_.highWatermark();
  }

  NiceMock<Event::MockDispatcher> dispatcher_;
  std::shared_ptr<Upstream::MockClusterInfo> cluster_{new NiceMock<Upstream::MockClusterInfo>()};
  Upstream::HostSharedPtr host_{new NiceMock<Upstream::MockHost>};
  NiceMock<Random::MockRandomGenerator> random_;
  Upstream::ClusterConnectivityState state_;
  Network::Address::InstanceConstSharedPtr test_address_;
  NiceMock<Server::Configuration::MockTransportSocketFactoryContext> context_;
  std::unique_ptr<Quic::QuicClientTransportSocketFactory> factory_;
  Stats::IsolatedStoreImpl store_;
  QuicStatNames quic_stat_names_{store_.symbolTable()};
};

TEST_P(QuicNetworkConnectionTest, BufferLimits) {
  initialize();

  quic::QuicConfig config;
  PersistentQuicInfoImpl info{dispatcher_, *factory_, simTime(), test_address_, config, 45};

  std::unique_ptr<Network::ClientConnection> client_connection = createQuicNetworkConnection(
      info, dispatcher_, test_address_, test_address_, quic_stat_names_, store_);
  EnvoyQuicClientSession* session = static_cast<EnvoyQuicClientSession*>(client_connection.get());
  session->Initialize();
  client_connection->connect();
  EXPECT_TRUE(client_connection->connecting());
  ASSERT(session != nullptr);
  EXPECT_EQ(highWatermark(session), 45);
  EXPECT_EQ(absl::nullopt, session->unixSocketPeerCredentials());
  EXPECT_EQ(absl::nullopt, session->lastRoundTripTime());
  client_connection->close(Network::ConnectionCloseType::NoFlush);
}

INSTANTIATE_TEST_SUITE_P(IpVersions, QuicNetworkConnectionTest,
                         testing::ValuesIn(TestEnvironment::getIpVersionsForTest()));
} // namespace Quic
} // namespace Envoy
<|endoftext|>


<commit_before>// -*- C++ -*-

// The MIT License (MIT)
//
// Copyright (c) 2021 Alexander Samoilov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "ChebyshevDifferentiate.hpp"

///
/// as \f$T_n(\cos\theta)=\cos n\theta\f$, then
///
/// \f[
/// 	\frac{T'_{n+1}(x)}{n+1}-\frac{T'_{n-1}(x)}{n-1}=\frac2{c_n}T_n(x)
/// 	\quad(n>=0)
/// \f]
///
/// where \f$c_0=2,\,c_n=1\,(n\le1)\f$ and \f$T'_0=T'_{-1}=0\f$, implies if
///
/// \f[
/// 	\frac d{dx}\sum^N_{n=0}a_nT_n(x)=\sum^N_{n=0}b_nT_n(x)
/// \f]
///
/// then
///
/// \f{align*}{
/// 	\sum^N_{n=0}a_nT'_n(x)
/// 		&=\sum^N_{n=0}c_nb_n\left[T_n(x)
/// 		\frac{T'_{n+1}(x)}{n+1}-\frac{T'_{n-1}(x)}{n-1}\right]\\
/// 		&=\sum^{N+1}_{n=0}[c_{n-1}b_{n-1}-b_{n+1}]T'_n(x)/n
/// \f}
///
/// equating \f$T'_n(x)\f$ for \f$n=1,\dots,N+1\f$
/// we derive recurrent equations for Chebyshev polynomials derivatives
///
/// \f{alignat*}{{2}
///        c_{n-1}b_{n-1}-b_{n+1} &= 2na_n &&\quad(1\le n\le N)\\
///                           b_n &=0      &&\quad(n\ge N)
/// \f}
///
/// if approximate solution is at each collocation point \f$(x_j)\f$
///
/// \f[
///     u(x,t) = \sum_{k=1}^{N+1}a_{k}T_{k-1}(x)
/// \f]
///
/// then, in particular, spatial derivatives can be defined directly in terms
/// of undifferentiated Chebyshev polynomials, i.e.
///
/// \f[
///     \frac{\partial{u}}{\partial{x}} = \sum_{k=1}^{N}a_{k}^{(1)}T_{k-1}(x)
/// \f]
///
/// and
///
/// \f[
///     \frac{\partial^2{u}}{\partial{x^2}} = \sum_{k=1}^{N-1}a_{k}^{(2)}T_{k-1}(x)
/// \f]
///
/// Specifically, the following recurrence relations permit all
/// the \f$a_k^{(1)}, a_k^{(2)}\f$ coefficients to be obtained in \f$O(N)\f$ operations
///
/// \f{alignat*}{{2}
///     a_k^{(1)} &= a_{k+2}^{(1)} + 2k a_{k+1}       &&\quad(2\le k\le N)\\
///     a_k^{(2)} &= a_{k+2}^{(2)} + 2k a_{k+1}^{(1)} &&\quad(2\le k\le N-1)\\
/// \f}
///
/// and \f$\qquad a_1^{(1)} = 0.5 a_3^{(1)} + 2k a_2, \quad a_1^{(2)} = 0.5 a_3^{(2)} + 2k a_2^{(1)}\f$
///
/// and \f$\qquad a_{N+1}^{(1)} = a_{N+2}^{(1)} = 0, \quad a_{N}^{(2)} = a_{N+1}^{(2)} = 0\f$

void spectral_differentiate(size_t n,
                            Eigen::Ref<RowVectorXd> data,
                            Eigen::Ref<RowVectorXd> rslt,
                            double span)
{
    double temp1 = data[n-1],
           temp2 = data[n-2];

    rslt[n-1] = 2.0*n*span*data[n];
    rslt[n-2] = 2.0*(n-1)*span*temp1;
    for (size_t j = n-3; j>0; j--) {
        temp1   = data[j];
        rslt[j] = rslt[j+2]+2.0*(j+1)*span*temp2;
        temp2   = temp1;
    }
    rslt[0] = 0.5*rslt[2]+span*temp2;
    rslt[n] = 0.0;
}

<commit_msg>cosmetic: rename vars and reformat.<commit_after>// -*- C++ -*-

// The MIT License (MIT)
//
// Copyright (c) 2021 Alexander Samoilov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "ChebyshevDifferentiate.hpp"

///
/// as \f$T_n(\cos\theta)=\cos n\theta\f$, then
///
/// \f[
/// 	\frac{T'_{n+1}(x)}{n+1}-\frac{T'_{n-1}(x)}{n-1}=\frac2{c_n}T_n(x)
/// 	\quad(n>=0)
/// \f]
///
/// where \f$c_0=2,\,c_n=1\,(n\le1)\f$ and \f$T'_0=T'_{-1}=0\f$, implies if
///
/// \f[
/// 	\frac d{dx}\sum^N_{n=0}a_nT_n(x)=\sum^N_{n=0}b_nT_n(x)
/// \f]
///
/// then
///
/// \f{align*}{
/// 	\sum^N_{n=0}a_nT'_n(x)
/// 		&=\sum^N_{n=0}c_nb_n\left[T_n(x)
/// 		\frac{T'_{n+1}(x)}{n+1}-\frac{T'_{n-1}(x)}{n-1}\right]\\
/// 		&=\sum^{N+1}_{n=0}[c_{n-1}b_{n-1}-b_{n+1}]T'_n(x)/n
/// \f}
///
/// equating \f$T'_n(x)\f$ for \f$n=1,\dots,N+1\f$
/// we derive recurrent equations for Chebyshev polynomials derivatives
///
/// \f{alignat*}{{2}
///        c_{n-1}b_{n-1}-b_{n+1} &= 2na_n &&\quad(1\le n\le N)\\
///                           b_n &=0      &&\quad(n\ge N)
/// \f}
///
/// if approximate solution is at each collocation point \f$(x_j)\f$
///
/// \f[
///     u(x,t) = \sum_{k=1}^{N+1}a_{k}T_{k-1}(x)
/// \f]
///
/// then, in particular, spatial derivatives can be defined directly in terms
/// of undifferentiated Chebyshev polynomials, i.e.
///
/// \f[
///     \frac{\partial{u}}{\partial{x}} = \sum_{k=1}^{N}a_{k}^{(1)}T_{k-1}(x)
/// \f]
///
/// and
///
/// \f[
///     \frac{\partial^2{u}}{\partial{x^2}} = \sum_{k=1}^{N-1}a_{k}^{(2)}T_{k-1}(x)
/// \f]
///
/// Specifically, the following recurrence relations permit all
/// the \f$a_k^{(1)}, a_k^{(2)}\f$ coefficients to be obtained in \f$O(N)\f$ operations
///
/// \f{alignat*}{{2}
///     a_k^{(1)} &= a_{k+2}^{(1)} + 2k a_{k+1}       &&\quad(2\le k\le N)\\
///     a_k^{(2)} &= a_{k+2}^{(2)} + 2k a_{k+1}^{(1)} &&\quad(2\le k\le N-1)\\
/// \f}
///
/// and \f$\qquad a_1^{(1)} = 0.5 a_3^{(1)} + 2k a_2, \quad a_1^{(2)} = 0.5 a_3^{(2)} + 2k a_2^{(1)}\f$
///
/// and \f$\qquad a_{N+1}^{(1)} = a_{N+2}^{(1)} = 0, \quad a_{N}^{(2)} = a_{N+1}^{(2)} = 0\f$

void spectral_differentiate(size_t n,
                            Eigen::Ref<RowVectorXd> in,
                            Eigen::Ref<RowVectorXd> out,
                            double span)
{
    double temp1 = in[n-1],
           temp2 = in[n-2];

    out[n-1] = 2.0 *  n    * in[n] * span;
    out[n-2] = 2.0 * (n-1) * temp1 * span;
    for (size_t j = n-3; j>0; j--) {
        temp1  = in[j];
        out[j] = out[j+2] + 2.0 * (j+1) * temp2 * span;
        temp2  = temp1;
    }
    out[0] = 0.5 * out[2] + temp2 * span;
    out[n] = 0.0;
}

<|endoftext|>


<commit_before>/**
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   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.
 **/

#ifndef QUICKSTEP_TRANSACTION_TRANSACTION_HPP_
#define QUICKSTEP_TRANSACTION_TRANSACTION_HPP_

#include <cstddef>
#include <cstdint>
#include <functional>

namespace quickstep {

namespace transaction {

/** \addtogroup Transaction
 *  @{
 */

/**
 * @brief Type that represents id of a transaction.
 **/
using transaction_id = std::uint64_t;

/**
 * @brief Enum class for transaction internal status.
 **/
enum class TransactionStatus {
  kRUNNING = 0,
  kABORTED,
  kCOMMITTED
};

/**
 * @brief Transaction
 **/
class Transaction {
 public:
  /**
   * @brief Constructor for Transaction.
   *
   * @param tid Id of this transaction.
   **/
  explicit Transaction(transaction_id tid)
    : tid_(tid) {
  }

  /**
   * @brief Getter for transaction id.
   *
   * @return Transaction id of this.
   **/
  inline transaction_id getTransactionId() const {
    return tid_;
  }

  /**
   * @brief Setter for the transaction status.
   *
   * @param status New status of the transaction.
   **/
  inline void setStatus(TransactionStatus status) {
    status_ = status_;
  }

  /**
   * @brief Getter for the transaction status.
   *
   * @return Status of the transaction.
   **/
  inline TransactionStatus getStatus() const {
    return status_;
  }

  /**
   * @brief Equality operator for Transaction class.
   *
   * @param other Other transaction to be compared with.
   * @return True if other tid and this tid are equal, false otherwise.
   **/
  inline bool operator==(const Transaction &other) const {
    return tid_ == other.tid_;
  }

  /**
   * @brief Helper hasher class for transaction.
   **/
  struct TransactionHasher {
    std::size_t operator()(const Transaction &transaction) const {
      return std::hash<transaction_id>()(transaction.tid_);
    }
  };

 private:
  // Unique id for the transaction.
  transaction_id tid_;

  // Transaction's running status.
  TransactionStatus status_;
};

/** @} */

}  // namespace transaction

}  // namespace quickstep

#endif  // QUICKSTEP_TRANSACTION_TRANSACTION_HPP_
<commit_msg>Fixed enum class style, changed using to typedef keyword.<commit_after>/**
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   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.
 **/

#ifndef QUICKSTEP_TRANSACTION_TRANSACTION_HPP_
#define QUICKSTEP_TRANSACTION_TRANSACTION_HPP_

#include <cstddef>
#include <cstdint>
#include <functional>

namespace quickstep {

namespace transaction {

/** \addtogroup Transaction
 *  @{
 */

/**
 * @brief Type that represents id of a transaction.
 **/
typedef std::uint64_t transaction_id;

/**
 * @brief Enum class for transaction internal status.
 **/
enum class TransactionStatus {
  kRunning = 0,
  kAborted,
  kCommitted
};

/**
 * @brief Transaction
 **/
class Transaction {
 public:
  /**
   * @brief Constructor for Transaction.
   *
   * @param tid Id of this transaction.
   **/
  explicit Transaction(transaction_id tid)
    : tid_(tid) {
  }

  /**
   * @brief Getter for transaction id.
   *
   * @return Transaction id of this.
   **/
  inline transaction_id getTransactionId() const {
    return tid_;
  }

  /**
   * @brief Setter for the transaction status.
   *
   * @param status New status of the transaction.
   **/
  inline void setStatus(TransactionStatus status) {
    status_ = status_;
  }

  /**
   * @brief Getter for the transaction status.
   *
   * @return Status of the transaction.
   **/
  inline TransactionStatus getStatus() const {
    return status_;
  }

  /**
   * @brief Equality operator for Transaction class.
   *
   * @param other Other transaction to be compared with.
   * @return True if other tid and this tid are equal, false otherwise.
   **/
  inline bool operator==(const Transaction &other) const {
    return tid_ == other.tid_;
  }

  /**
   * @brief Helper hasher class for transaction.
   **/
  struct TransactionHasher {
    std::size_t operator()(const Transaction &transaction) const {
      return std::hash<transaction_id>()(transaction.tid_);
    }
  };

 private:
  // Unique id for the transaction.
  transaction_id tid_;

  // Transaction's running status.
  TransactionStatus status_;
};

/** @} */

}  // namespace transaction

}  // namespace quickstep

#endif  // QUICKSTEP_TRANSACTION_TRANSACTION_HPP_
<|endoftext|>


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

#include "chrome/browser/speech/speech_input_bubble_controller.h"

#include "chrome/browser/browser_thread.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "gfx/rect.h"

namespace speech_input {

SpeechInputBubbleController::SpeechInputBubbleController(Delegate* delegate)
    : delegate_(delegate),
      current_bubble_caller_id_(0),
      registrar_(new NotificationRegistrar) {
}

SpeechInputBubbleController::~SpeechInputBubbleController() {
  DCHECK(bubbles_.size() == 0);
}

void SpeechInputBubbleController::CreateBubble(int caller_id,
                                               int render_process_id,
                                               int render_view_id,
                                               const gfx::Rect& element_rect) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this, &SpeechInputBubbleController::CreateBubble,
                          caller_id, render_process_id, render_view_id,
                          element_rect));
    return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TabContents* tab_contents = tab_util::GetTabContentsByID(render_process_id,
                                                           render_view_id);

  DCHECK_EQ(0u, bubbles_.count(caller_id));
  SpeechInputBubble* bubble = SpeechInputBubble::Create(tab_contents, this,
                                                        element_rect);
  if (!bubble)  // could be null if tab or display rect were invalid.
    return;

  bubbles_[caller_id] = bubble;

  UpdateTabContentsSubscription(caller_id, BUBBLE_ADDED);
}

void SpeechInputBubbleController::CloseBubble(int caller_id) {
  ProcessRequestInUiThread(caller_id, REQUEST_CLOSE, string16(), 0);
}

void SpeechInputBubbleController::SetBubbleRecordingMode(int caller_id) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_RECORDING_MODE,
                           string16(), 0);
}

void SpeechInputBubbleController::SetBubbleRecognizingMode(int caller_id) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_RECOGNIZING_MODE,
                           string16(), 0);
}

void SpeechInputBubbleController::SetBubbleInputVolume(int caller_id,
                                                       float volume) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_INPUT_VOLUME, string16(),
                           volume);
}

void SpeechInputBubbleController::SetBubbleMessage(int caller_id,
                                                   const string16& text) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_MESSAGE, text, 0);
}

void SpeechInputBubbleController::UpdateTabContentsSubscription(
    int caller_id, ManageSubscriptionAction action) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // If there are any other bubbles existing for the same TabContents, we would
  // have subscribed to tab close notifications on their behalf and we need to
  // stay registered. So we don't change the subscription in such cases.
  TabContents* tab_contents = bubbles_[caller_id]->tab_contents();
  for (BubbleCallerIdMap::iterator iter = bubbles_.begin();
       iter != bubbles_.end(); ++iter) {
    if (iter->second->tab_contents() == tab_contents &&
        iter->first != caller_id) {
      // At least one other bubble exists for the same TabContents. So don't
      // make any change to the subscription.
      return;
    }
  }

  if (action == BUBBLE_ADDED) {
    registrar_->Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab_contents));
  } else {
    registrar_->Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab_contents));
  }
}

void SpeechInputBubbleController::Observe(NotificationType type,
                                          const NotificationSource& source,
                                          const NotificationDetails& details) {
  if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
    // Cancel all bubbles and active recognition sessions for this tab.
    TabContents* tab_contents = Source<TabContents>(source).ptr();
    BubbleCallerIdMap::iterator iter = bubbles_.begin();
    while (iter != bubbles_.end()) {
      if (iter->second->tab_contents() == tab_contents) {
        BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
            NewRunnableMethod(
                this,
                &SpeechInputBubbleController::InvokeDelegateButtonClicked,
                iter->first, SpeechInputBubble::BUTTON_CANCEL));
        CloseBubble(iter->first);
        // We expect to have a very small number of items in this map so
        // redo-ing from start is ok.
        iter = bubbles_.begin();
      } else {
        ++iter;
      }
    }
  } else {
    NOTREACHED() << "Unknown notification";
  }
}

void SpeechInputBubbleController::ProcessRequestInUiThread(
    int caller_id, RequestType type, const string16& text, float volume) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
        this, &SpeechInputBubbleController::ProcessRequestInUiThread,
        caller_id, type, text, volume));
    return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // The bubble may have been closed before we got a chance to process this
  // request. So check before proceeding.
  if (!bubbles_.count(caller_id))
    return;

  bool change_active_bubble = (type == REQUEST_SET_RECORDING_MODE ||
                               type == REQUEST_SET_MESSAGE);
  if (change_active_bubble) {
    if (current_bubble_caller_id_ && current_bubble_caller_id_ != caller_id)
      bubbles_[current_bubble_caller_id_]->Hide();
    current_bubble_caller_id_ = caller_id;
  }

  SpeechInputBubble* bubble = bubbles_[caller_id];
  switch (type) {
    case REQUEST_SET_RECORDING_MODE:
      bubble->SetRecordingMode();
      break;
    case REQUEST_SET_RECOGNIZING_MODE:
      bubble->SetRecognizingMode();
      break;
    case REQUEST_SET_MESSAGE:
      bubble->SetMessage(text);
      break;
    case REQUEST_SET_INPUT_VOLUME:
      bubble->SetInputVolume(volume);
      break;
    case REQUEST_CLOSE:
      if (current_bubble_caller_id_ == caller_id)
        current_bubble_caller_id_ = 0;
      UpdateTabContentsSubscription(caller_id, BUBBLE_REMOVED);
      delete bubble;
      bubbles_.erase(caller_id);
      break;
    default:
      NOTREACHED();
      break;
  }

  if (change_active_bubble)
    bubble->Show();
}

void SpeechInputBubbleController::InfoBubbleButtonClicked(
    SpeechInputBubble::Button button) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(current_bubble_caller_id_);

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      NewRunnableMethod(
          this,
          &SpeechInputBubbleController::InvokeDelegateButtonClicked,
          current_bubble_caller_id_, button));
}

void SpeechInputBubbleController::InfoBubbleFocusChanged() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(current_bubble_caller_id_);

  int old_bubble_caller_id = current_bubble_caller_id_;
  current_bubble_caller_id_ = 0;
  bubbles_[old_bubble_caller_id]->Hide();

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      NewRunnableMethod(
          this,
          &SpeechInputBubbleController::InvokeDelegateFocusChanged,
          old_bubble_caller_id));
}

void SpeechInputBubbleController::InvokeDelegateButtonClicked(
    int caller_id, SpeechInputBubble::Button button) {
  delegate_->InfoBubbleButtonClicked(caller_id, button);
}

void SpeechInputBubbleController::InvokeDelegateFocusChanged(int caller_id) {
  delegate_->InfoBubbleFocusChanged(caller_id);
}

}  // namespace speech_input
<commit_msg>Avoid closing speech input UI bubble twice.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/speech/speech_input_bubble_controller.h"

#include "chrome/browser/browser_thread.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "gfx/rect.h"

namespace speech_input {

SpeechInputBubbleController::SpeechInputBubbleController(Delegate* delegate)
    : delegate_(delegate),
      current_bubble_caller_id_(0),
      registrar_(new NotificationRegistrar) {
}

SpeechInputBubbleController::~SpeechInputBubbleController() {
  DCHECK(bubbles_.size() == 0);
}

void SpeechInputBubbleController::CreateBubble(int caller_id,
                                               int render_process_id,
                                               int render_view_id,
                                               const gfx::Rect& element_rect) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this, &SpeechInputBubbleController::CreateBubble,
                          caller_id, render_process_id, render_view_id,
                          element_rect));
    return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TabContents* tab_contents = tab_util::GetTabContentsByID(render_process_id,
                                                           render_view_id);

  DCHECK_EQ(0u, bubbles_.count(caller_id));
  SpeechInputBubble* bubble = SpeechInputBubble::Create(tab_contents, this,
                                                        element_rect);
  if (!bubble)  // could be null if tab or display rect were invalid.
    return;

  bubbles_[caller_id] = bubble;

  UpdateTabContentsSubscription(caller_id, BUBBLE_ADDED);
}

void SpeechInputBubbleController::CloseBubble(int caller_id) {
  ProcessRequestInUiThread(caller_id, REQUEST_CLOSE, string16(), 0);
}

void SpeechInputBubbleController::SetBubbleRecordingMode(int caller_id) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_RECORDING_MODE,
                           string16(), 0);
}

void SpeechInputBubbleController::SetBubbleRecognizingMode(int caller_id) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_RECOGNIZING_MODE,
                           string16(), 0);
}

void SpeechInputBubbleController::SetBubbleInputVolume(int caller_id,
                                                       float volume) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_INPUT_VOLUME, string16(),
                           volume);
}

void SpeechInputBubbleController::SetBubbleMessage(int caller_id,
                                                   const string16& text) {
  ProcessRequestInUiThread(caller_id, REQUEST_SET_MESSAGE, text, 0);
}

void SpeechInputBubbleController::UpdateTabContentsSubscription(
    int caller_id, ManageSubscriptionAction action) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // If there are any other bubbles existing for the same TabContents, we would
  // have subscribed to tab close notifications on their behalf and we need to
  // stay registered. So we don't change the subscription in such cases.
  TabContents* tab_contents = bubbles_[caller_id]->tab_contents();
  for (BubbleCallerIdMap::iterator iter = bubbles_.begin();
       iter != bubbles_.end(); ++iter) {
    if (iter->second->tab_contents() == tab_contents &&
        iter->first != caller_id) {
      // At least one other bubble exists for the same TabContents. So don't
      // make any change to the subscription.
      return;
    }
  }

  if (action == BUBBLE_ADDED) {
    registrar_->Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab_contents));
  } else {
    registrar_->Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab_contents));
  }
}

void SpeechInputBubbleController::Observe(NotificationType type,
                                          const NotificationSource& source,
                                          const NotificationDetails& details) {
  if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
    // Cancel all bubbles and active recognition sessions for this tab.
    TabContents* tab_contents = Source<TabContents>(source).ptr();
    BubbleCallerIdMap::iterator iter = bubbles_.begin();
    while (iter != bubbles_.end()) {
      if (iter->second->tab_contents() == tab_contents) {
        BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
            NewRunnableMethod(
                this,
                &SpeechInputBubbleController::InvokeDelegateButtonClicked,
                iter->first, SpeechInputBubble::BUTTON_CANCEL));
        CloseBubble(iter->first);
        // We expect to have a very small number of items in this map so
        // redo-ing from start is ok.
        iter = bubbles_.begin();
      } else {
        ++iter;
      }
    }
  } else {
    NOTREACHED() << "Unknown notification";
  }
}

void SpeechInputBubbleController::ProcessRequestInUiThread(
    int caller_id, RequestType type, const string16& text, float volume) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
        this, &SpeechInputBubbleController::ProcessRequestInUiThread,
        caller_id, type, text, volume));
    return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // The bubble may have been closed before we got a chance to process this
  // request. So check before proceeding.
  if (!bubbles_.count(caller_id))
    return;

  bool change_active_bubble = (type == REQUEST_SET_RECORDING_MODE ||
                               type == REQUEST_SET_MESSAGE);
  if (change_active_bubble) {
    if (current_bubble_caller_id_ && current_bubble_caller_id_ != caller_id)
      bubbles_[current_bubble_caller_id_]->Hide();
    current_bubble_caller_id_ = caller_id;
  }

  SpeechInputBubble* bubble = bubbles_[caller_id];
  switch (type) {
    case REQUEST_SET_RECORDING_MODE:
      bubble->SetRecordingMode();
      break;
    case REQUEST_SET_RECOGNIZING_MODE:
      bubble->SetRecognizingMode();
      break;
    case REQUEST_SET_MESSAGE:
      bubble->SetMessage(text);
      break;
    case REQUEST_SET_INPUT_VOLUME:
      bubble->SetInputVolume(volume);
      break;
    case REQUEST_CLOSE:
      if (current_bubble_caller_id_ == caller_id)
        current_bubble_caller_id_ = 0;
      UpdateTabContentsSubscription(caller_id, BUBBLE_REMOVED);
      delete bubble;
      bubbles_.erase(caller_id);
      break;
    default:
      NOTREACHED();
      break;
  }

  if (change_active_bubble)
    bubble->Show();
}

void SpeechInputBubbleController::InfoBubbleButtonClicked(
    SpeechInputBubble::Button button) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(current_bubble_caller_id_);

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      NewRunnableMethod(
          this,
          &SpeechInputBubbleController::InvokeDelegateButtonClicked,
          current_bubble_caller_id_, button));
}

void SpeechInputBubbleController::InfoBubbleFocusChanged() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(current_bubble_caller_id_);

  int old_bubble_caller_id = current_bubble_caller_id_;
  current_bubble_caller_id_ = 0;

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      NewRunnableMethod(
          this,
          &SpeechInputBubbleController::InvokeDelegateFocusChanged,
          old_bubble_caller_id));
}

void SpeechInputBubbleController::InvokeDelegateButtonClicked(
    int caller_id, SpeechInputBubble::Button button) {
  delegate_->InfoBubbleButtonClicked(caller_id, button);
}

void SpeechInputBubbleController::InvokeDelegateFocusChanged(int caller_id) {
  delegate_->InfoBubbleFocusChanged(caller_id);
}

}  // namespace speech_input
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#include	"../StroikaPreComp.h"

#include	<algorithm>
#include	<cstdlib>
#include	<sstream>

#include	"../../Foundation/Characters/Format.h"
#include	"../../Foundation/Containers/Common.h"
#include	"../../Foundation/DataExchangeFormat/BadFormatException.h"
#include	"../../Foundation/Debug/Assertions.h"
#include	"../../Foundation/Execution/Exceptions.h"
#include	"../../Foundation/IO/Network/HTTP/Headers.h"
#include	"../../Foundation/Memory/SmallStackBuffer.h"

#include	"HTTPResponse.h"

using	namespace	Stroika::Foundation;
using	namespace	Stroika::Foundation::Containers;
using	namespace	Stroika::Foundation::Memory;

using	namespace	Stroika::Frameworks;
using	namespace	Stroika::Frameworks::WebServer;

/*
 ********************************************************************************
 ************************ WebServer::HTTPResponse *******************************
 ********************************************************************************
 */
namespace	{
	// Based on looking at a handlful of typical file sizes...5k to 80k, but ave around
	// 25 and median abit above 32k. Small, not very representative sampling. And the more we use
	// subscripts (script src=x) this number could shrink.
	//
	// MAY want to switch to using SmallStackBuffer<Byte> - but before doing so, do some cleanups of its bugs and make sure
	// its optimized about how much it copies etc. Its really only tuned for POD-types (OK here but not necessarily good about reallocs).
	//
	//		-- LGP 2011-07-06
	const	size_t	kMinResponseBufferReserve_				=	32 * 1024;
	const	size_t	kResponseBufferReallocChunkSizeReserve_	=	16 * 1024;
}

HTTPResponse::HTTPResponse (const IO::Network::Socket& s,  Streams::BinaryOutputStream& outStream, const InternetMediaType& ct)
	: fSocket_ (s)
	, fOutStream_ (outStream)
	, fState_ (eInProgress)
	, fStatus_ (StatusCodes::kOK)
	, fHeaders_ ()
	, fContentType_ (ct)
	, fBytes_ ()
	, fContentSizePolicy_ (eAutoCompute_CSP)
	, fContentSize_ (0)
{
	AddHeader (L"Server", L"Stroka-Based-Web-Server");
}

void	HTTPResponse::SetContentSizePolicy (ContentSizePolicy csp)
{
	Require (csp == eAutoCompute_CSP or csp == eNone_CSP);
	fContentSizePolicy_ = csp;
}

void	HTTPResponse::SetContentSizePolicy (ContentSizePolicy csp, uint64_t size)
{
	Require (fState_ == eExact_CSP);
	Require (fState_ == eInProgress);
	fContentSizePolicy_ = csp;
	fContentSize_ = size;
}

void	HTTPResponse::SetContentType (const InternetMediaType& contentType)
{
	Require (fState_ == eInProgress);
	fContentType_ = contentType;
}

void	HTTPResponse::SetStatus (Status newStatus)
{
	Require (fState_ == eInProgress);
	fStatus_ = newStatus;
}

void	HTTPResponse::AddHeader (String headerName, String value)
{
	Require (fState_ == eInProgress);
	ClearHeader (headerName);
	fHeaders_.insert (map<String,String>::value_type (headerName, value));
}

void	HTTPResponse::ClearHeader ()
{
	Require (fState_ == eInProgress);
	fHeaders_.clear ();
}

void	HTTPResponse::ClearHeader (String headerName)
{
	Require (fState_ == eInProgress);
	map<String,String>::iterator i = fHeaders_.find (headerName);
	if (i != fHeaders_.end ()) {
		fHeaders_.erase (i);
	}
}

map<String,String>	HTTPResponse::GetSpecialHeaders () const
{
	return fHeaders_;
}

map<String,String>	HTTPResponse::GetEffectiveHeaders () const
{
	map<String,String>	tmp	=	GetSpecialHeaders ();
	switch (GetContentSizePolicy ()) {
		case	eAutoCompute_CSP:
		case	eExact_CSP: {
			wostringstream	buf;
			buf << fContentSize_;
			tmp.insert (map<String,String>::value_type (IO::Network::HTTP::HeaderName::kContentLength, buf.str ()));
		}
		break;
	}
	return tmp;
}

void	HTTPResponse::Flush ()
{
	if (fState_ == eInProgress) {
		{
			wstring	statusMsg;
			switch (fStatus_) {
				case StatusCodes::kOK:					statusMsg = L"OK"; break;
				case StatusCodes::kMovedPermanently:	statusMsg = L"Moved Permanently"; break;
			}
			wstring	version	=	L"1.1";
			wstring	tmp	=	Characters::Format (L"HTTP/%s %d %s\r\n", version.c_str (), fStatus_, statusMsg.c_str ());
			string	utf8	=	String (tmp).AsUTF8 ();
			fOutStream_.Write (reinterpret_cast<const Byte*> (Containers::Start (utf8)), reinterpret_cast<const Byte*> (Containers::End (utf8)));
		}

		{
			map<String,String>	headers2Write	=	GetEffectiveHeaders ();
			for (map<String,String>::const_iterator i = headers2Write.begin (); i != headers2Write.end (); ++i) {
				wstring	tmp	=	Characters::Format (L"%s: %s\r\n", i->first.As<wstring> ().c_str (), i->second.As<wstring> ().c_str ());
				string	utf8	=	String (tmp).AsUTF8 ();
				fOutStream_.Write (reinterpret_cast<const Byte*> (Containers::Start (utf8)), reinterpret_cast<const Byte*> (Containers::End (utf8)));
			}
		}

		const char	kCRLF[]	=	"\r\n";
		fOutStream_.Write (reinterpret_cast<const Byte*> (kCRLF), reinterpret_cast<const Byte*> (kCRLF + 2));
		fState_ = eInProgressHeaderSentState;
	}
	// write BYTES to fOutStream
	if (not fBytes_.empty ()) {
		Assert (fState_ != eCompleted);	// We PREVENT any writes when completed
		fOutStream_.Write (Containers::Start (fBytes_), Containers::End (fBytes_));
		fBytes_.clear ();
	}
}

void	HTTPResponse::End ()
{
	Require ((fState_ == eInProgress) or (fState_ == eInProgressHeaderSentState));
	Flush ();
	fState_ = eCompleted;
}

void	HTTPResponse::Kill ()
{
	if (fState_ != eCompleted) {
		fState_ = eCompleted;
		fSocket_.Close ();
	}
}

void	HTTPResponse::Redirect (const wstring& url)
{
	Require (fState_ == eInProgress);
	fBytes_.clear ();

	// PERHAPS should clear some header values???
	AddHeader (L"Connection", L"close");	// needed for redirect
	AddHeader (L"Location", url);			// needed for redirect
	SetStatus (StatusCodes::kMovedPermanently);
	Flush ();
	fState_ = eCompleted;
}

void	HTTPResponse::write (const Byte* s, const Byte* e)
{
	Require ((fState_ == eInProgress) or (fState_ == eInProgressHeaderSentState));
	Require ((fState_ == eInProgress) or (GetContentSizePolicy () != eAutoCompute_CSP));
	Require (s <= e);
	if (s < e) {
		Containers::ReserveSpeedTweekAddN (fBytes_, (e - s), kResponseBufferReallocChunkSizeReserve_);
		fBytes_.insert (fBytes_.end (), s, e);
		if (GetContentSizePolicy () == eAutoCompute_CSP) {
			// Because for autocompute - illegal to call flush and then write
			fContentSize_ = fBytes_.size ();
		}
	}
}

void	HTTPResponse::write (const wchar_t* s, const wchar_t* e)
{
	Require ((fState_ == eInProgress) or (fState_ == eInProgressHeaderSentState));
	Require ((fState_ == eInProgress) or (GetContentSizePolicy () != eAutoCompute_CSP));
	Require (s <= e);
	if (s < e) {
		wstring tmp = wstring (s,e);
		string utf8 = String (tmp).AsUTF8 ();
		if (not utf8.empty ()) {
			fBytes_.insert (fBytes_.end (), reinterpret_cast<const Byte*> (utf8.c_str ()), reinterpret_cast<const Byte*> (utf8.c_str () + utf8.length ()));
			if (GetContentSizePolicy () == eAutoCompute_CSP) {
				// Because for autocompute - illegal to call flush and then write
				fContentSize_ = fBytes_.size ();
			}
		}
	}
}
<commit_msg>Added first draft of ContentSizePolicy support to HTTPResponse<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#include	"../StroikaPreComp.h"

#include	<algorithm>
#include	<cstdlib>
#include	<sstream>

#include	"../../Foundation/Characters/Format.h"
#include	"../../Foundation/Containers/Common.h"
#include	"../../Foundation/DataExchangeFormat/BadFormatException.h"
#include	"../../Foundation/Debug/Assertions.h"
#include	"../../Foundation/Execution/Exceptions.h"
#include	"../../Foundation/IO/Network/HTTP/Headers.h"
#include	"../../Foundation/Memory/SmallStackBuffer.h"

#include	"HTTPResponse.h"

using	namespace	Stroika::Foundation;
using	namespace	Stroika::Foundation::Containers;
using	namespace	Stroika::Foundation::Memory;

using	namespace	Stroika::Frameworks;
using	namespace	Stroika::Frameworks::WebServer;

/*
 ********************************************************************************
 ************************ WebServer::HTTPResponse *******************************
 ********************************************************************************
 */
namespace	{
	// Based on looking at a handlful of typical file sizes...5k to 80k, but ave around
	// 25 and median abit above 32k. Small, not very representative sampling. And the more we use
	// subscripts (script src=x) this number could shrink.
	//
	// MAY want to switch to using SmallStackBuffer<Byte> - but before doing so, do some cleanups of its bugs and make sure
	// its optimized about how much it copies etc. Its really only tuned for POD-types (OK here but not necessarily good about reallocs).
	//
	//		-- LGP 2011-07-06
	const	size_t	kMinResponseBufferReserve_				=	32 * 1024;
	const	size_t	kResponseBufferReallocChunkSizeReserve_	=	16 * 1024;
}

HTTPResponse::HTTPResponse (const IO::Network::Socket& s,  Streams::BinaryOutputStream& outStream, const InternetMediaType& ct)
	: fSocket_ (s)
	, fOutStream_ (outStream)
	, fState_ (eInProgress)
	, fStatus_ (StatusCodes::kOK)
	, fHeaders_ ()
	, fContentType_ (ct)
	, fBytes_ ()
	, fContentSizePolicy_ (eAutoCompute_CSP)
	, fContentSize_ (0)
{
	AddHeader (L"Server", L"Stroka-Based-Web-Server");
}

void	HTTPResponse::SetContentSizePolicy (ContentSizePolicy csp)
{
	Require (csp == eAutoCompute_CSP or csp == eNone_CSP);
	fContentSizePolicy_ = csp;
}

void	HTTPResponse::SetContentSizePolicy (ContentSizePolicy csp, uint64_t size)
{
	Require (csp == eExact_CSP);
	Require (fState_ == eInProgress);
	fContentSizePolicy_ = csp;
	fContentSize_ = size;
}

void	HTTPResponse::SetContentType (const InternetMediaType& contentType)
{
	Require (fState_ == eInProgress);
	fContentType_ = contentType;
}

void	HTTPResponse::SetStatus (Status newStatus)
{
	Require (fState_ == eInProgress);
	fStatus_ = newStatus;
}

void	HTTPResponse::AddHeader (String headerName, String value)
{
	Require (fState_ == eInProgress);
	ClearHeader (headerName);
	fHeaders_.insert (map<String,String>::value_type (headerName, value));
}

void	HTTPResponse::ClearHeader ()
{
	Require (fState_ == eInProgress);
	fHeaders_.clear ();
}

void	HTTPResponse::ClearHeader (String headerName)
{
	Require (fState_ == eInProgress);
	map<String,String>::iterator i = fHeaders_.find (headerName);
	if (i != fHeaders_.end ()) {
		fHeaders_.erase (i);
	}
}

map<String,String>	HTTPResponse::GetSpecialHeaders () const
{
	return fHeaders_;
}

map<String,String>	HTTPResponse::GetEffectiveHeaders () const
{
	map<String,String>	tmp	=	GetSpecialHeaders ();
	switch (GetContentSizePolicy ()) {
		case	eAutoCompute_CSP:
		case	eExact_CSP: {
			wostringstream	buf;
			buf << fContentSize_;
			tmp.insert (map<String,String>::value_type (IO::Network::HTTP::HeaderName::kContentLength, buf.str ()));
		}
		break;
	}
	return tmp;
}

void	HTTPResponse::Flush ()
{
	if (fState_ == eInProgress) {
		{
			wstring	statusMsg;
			switch (fStatus_) {
				case StatusCodes::kOK:					statusMsg = L"OK"; break;
				case StatusCodes::kMovedPermanently:	statusMsg = L"Moved Permanently"; break;
			}
			wstring	version	=	L"1.1";
			wstring	tmp	=	Characters::Format (L"HTTP/%s %d %s\r\n", version.c_str (), fStatus_, statusMsg.c_str ());
			string	utf8	=	String (tmp).AsUTF8 ();
			fOutStream_.Write (reinterpret_cast<const Byte*> (Containers::Start (utf8)), reinterpret_cast<const Byte*> (Containers::End (utf8)));
		}

		{
			map<String,String>	headers2Write	=	GetEffectiveHeaders ();
			for (map<String,String>::const_iterator i = headers2Write.begin (); i != headers2Write.end (); ++i) {
				wstring	tmp	=	Characters::Format (L"%s: %s\r\n", i->first.As<wstring> ().c_str (), i->second.As<wstring> ().c_str ());
				string	utf8	=	String (tmp).AsUTF8 ();
				fOutStream_.Write (reinterpret_cast<const Byte*> (Containers::Start (utf8)), reinterpret_cast<const Byte*> (Containers::End (utf8)));
			}
		}

		const char	kCRLF[]	=	"\r\n";
		fOutStream_.Write (reinterpret_cast<const Byte*> (kCRLF), reinterpret_cast<const Byte*> (kCRLF + 2));
		fState_ = eInProgressHeaderSentState;
	}
	// write BYTES to fOutStream
	if (not fBytes_.empty ()) {
		Assert (fState_ != eCompleted);	// We PREVENT any writes when completed
		fOutStream_.Write (Containers::Start (fBytes_), Containers::End (fBytes_));
		fBytes_.clear ();
	}
}

void	HTTPResponse::End ()
{
	Require ((fState_ == eInProgress) or (fState_ == eInProgressHeaderSentState));
	Flush ();
	fState_ = eCompleted;
}

void	HTTPResponse::Kill ()
{
	if (fState_ != eCompleted) {
		fState_ = eCompleted;
		fSocket_.Close ();
	}
}

void	HTTPResponse::Redirect (const wstring& url)
{
	Require (fState_ == eInProgress);
	fBytes_.clear ();

	// PERHAPS should clear some header values???
	AddHeader (L"Connection", L"close");	// needed for redirect
	AddHeader (L"Location", url);			// needed for redirect
	SetStatus (StatusCodes::kMovedPermanently);
	Flush ();
	fState_ = eCompleted;
}

void	HTTPResponse::write (const Byte* s, const Byte* e)
{
	Require ((fState_ == eInProgress) or (fState_ == eInProgressHeaderSentState));
	Require ((fState_ == eInProgress) or (GetContentSizePolicy () != eAutoCompute_CSP));
	Require (s <= e);
	if (s < e) {
		Containers::ReserveSpeedTweekAddN (fBytes_, (e - s), kResponseBufferReallocChunkSizeReserve_);
		fBytes_.insert (fBytes_.end (), s, e);
		if (GetContentSizePolicy () == eAutoCompute_CSP) {
			// Because for autocompute - illegal to call flush and then write
			fContentSize_ = fBytes_.size ();
		}
	}
}

void	HTTPResponse::write (const wchar_t* s, const wchar_t* e)
{
	Require ((fState_ == eInProgress) or (fState_ == eInProgressHeaderSentState));
	Require ((fState_ == eInProgress) or (GetContentSizePolicy () != eAutoCompute_CSP));
	Require (s <= e);
	if (s < e) {
		wstring tmp = wstring (s,e);
		string utf8 = String (tmp).AsUTF8 ();
		if (not utf8.empty ()) {
			fBytes_.insert (fBytes_.end (), reinterpret_cast<const Byte*> (utf8.c_str ()), reinterpret_cast<const Byte*> (utf8.c_str () + utf8.length ()));
			if (GetContentSizePolicy () == eAutoCompute_CSP) {
				// Because for autocompute - illegal to call flush and then write
				fContentSize_ = fBytes_.size ();
			}
		}
	}
}
<|endoftext|>


<commit_before>#include <stan/math/rev/mat.hpp>
#include <gtest/gtest.h>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <chrono>

using stan::math::var;
using Eigen::Dynamic;
using Eigen::Matrix;

typedef std::chrono::high_resolution_clock::time_point TimeVar;
#define duration(a) std::chrono::duration_cast<std::chrono::microseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

//  We check that the values of the new regression match those of one built
//  from existing primitives.
TEST(ProbDistributionsNormalIdGLM, glm_matches_normal_id_doubles)
{
  Matrix<int, Dynamic, 1> n(3, 1);
  n << 51, 32, 12;
  Matrix<double, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<double, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  double alpha = 0.3;
  Matrix<double, Dynamic, 1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<double, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;
  Matrix<double, Dynamic, 1> sigma(3, 1);
  sigma << 10, 4, 6;

  EXPECT_FLOAT_EQ((stan::math::normal_lpdf(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf(n, x, beta, alpha,
                    sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<true>(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<true>(n, x, beta, alpha,
                  sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<false>(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<false>(n, x, beta, alpha,
                  sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<true, Matrix<int, Dynamic, 1>>(n,
                  theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<true, Matrix<int, Dynamic, 1>>(n, x, beta, alpha, sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<false, Matrix<int, Dynamic, 1>>(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<false, Matrix<int, Dynamic, 1>>(n, x, beta, alpha, sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<Matrix<int, Dynamic, 1>>(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<Matrix<int, Dynamic, 1>>(n, x, beta, alpha, sigma)));
}

//  We check that the gradients of the new regression match those of one built
//  from existing primitives.
TEST(ProbDistributionsNormalIdGLM, glm_matches_normal_id_vars)
{

  Matrix<int, Dynamic, 1> n(3, 1);
  n << 14, 32, 21;
  Matrix<var, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  var alpha = 0.3;
  Matrix<var, Dynamic, 1> sigma(3, 1);
  sigma << 10, 4, 6;
  Matrix<var, Dynamic,1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<var, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;

  var lp = stan::math::normal_lpdf(n, theta, sigma);
  lp.grad();

  stan::math::recover_memory();

  Matrix<int, Dynamic, 1> n2(3, 1);
  n2 << 14, 32, 21;
  Matrix<var, Dynamic, Dynamic> x2(3, 2);
  x2 << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta2(2, 1);
  beta2 << 0.3, 2;
  var alpha2 = 0.3;
  Matrix<var, Dynamic, 1> sigma2(3, 1);
  sigma2 << 10, 4, 6;

  var lp2 = stan::math::normal_id_glm_lpdf(n2, x2, beta2, alpha2, sigma2);
  lp2.grad();

  EXPECT_FLOAT_EQ(lp.val(),
                  lp2.val());
  for (size_t i = 0; i < 2; i++)
  {
    EXPECT_FLOAT_EQ(beta[i].adj(), beta2[i].adj());
  }
  EXPECT_FLOAT_EQ(alpha.adj(), alpha2.adj());
  for (size_t j = 0; j < 3; j++)
  {
    EXPECT_FLOAT_EQ(sigma[j].adj(), sigma2[j].adj());
    for (size_t i = 0; i < 2; i++)
    {
      EXPECT_FLOAT_EQ(x(j, i).adj(), x2(j, i).adj());
    }
  }
}

//  Here, we compare the speed of the new regression to that of one built from
//  existing primitives.

/*
TEST(ProbDistributionsNormalIdGLM, glm_matches_normal_id_speed) {
  const int R = 30000;
  const int C = 1000;

  Matrix<int,Dynamic,1> n(R, 1);
  for (size_t i = 0; i < R; i++) {
    n[i] = rand()%2000;
  }

  int T1 = 0;
  int T2 = 0;

  for (size_t testnumber = 0; testnumber < 30; testnumber++){
    Matrix<double, Dynamic, Dynamic> xreal = Matrix<double, Dynamic, Dynamic>::Random(R, C);
    Matrix<double, Dynamic, 1> betareal = Matrix<double, Dynamic, Dynamic>::Random(C, 1);
    Matrix<double, Dynamic, 1> sigmareal = Matrix<double, Dynamic, Dynamic>::Random(R, 1)
      + Matrix<double, R, 1>::Ones();  // Random Matrix has entries between -1 and 1. We add 1 to it to get positive entries.
    Matrix<double, 1, 1> alphareal = Matrix<double, 1, 1>::Random(1, 1);
    Matrix<double, Dynamic, 1> alpharealvec = Matrix<double, R, 1>::Ones() * alphareal;

    Matrix<var, Dynamic, 1> beta = betareal;
    Matrix<var, Dynamic, 1> sigma = sigmareal;
    Matrix<var, Dynamic, 1> theta(R, 1);

    TimeVar t1 = timeNow();
    theta = (xreal * beta) + alpharealvec;
    var lp = stan::math::normal_lpdf(n, theta, sigma);

    lp.grad();
    TimeVar t2 = timeNow();

    stan::math::recover_memory();

    Matrix<var, Dynamic, 1> beta2 = betareal;
    Matrix<var, Dynamic, 1> sigma2 = sigmareal;

    TimeVar t3 = timeNow();
    var lp2 = stan::math::normal_id_glm_lpdf(n, xreal, beta2, alphareal[0],
      sigma2);
    lp2.grad();
    TimeVar t4 = timeNow();
    stan::math::recover_memory();
    T1 += duration(t2 - t1);
    T2 += duration(t4 - t3);

  }

  std::cout << "Existing Primitives:" << std::endl << T1 << std::endl  << "New Primitives:" << std::endl << T2 << std::endl;
}
*/<commit_msg>satisfied cpplint for test<commit_after>#include <stan/math/rev/mat.hpp>
#include <gtest/gtest.h>
#include <stan/math/prim/scal/fun/value_of.hpp>

using stan::math::var;
using Eigen::Dynamic;
using Eigen::Matrix;

//  We check that the values of the new regression match those of one built
//  from existing primitives.
TEST(ProbDistributionsNormalIdGLM, glm_matches_normal_id_doubles) {
  Matrix<int, Dynamic, 1> n(3, 1);
  n << 51, 32, 12;
  Matrix<double, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<double, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  double alpha = 0.3;
  Matrix<double, Dynamic, 1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<double, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;
  Matrix<double, Dynamic, 1> sigma(3, 1);
  sigma << 10, 4, 6;

  EXPECT_FLOAT_EQ((stan::math::normal_lpdf(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf(n, x, beta, alpha,
                    sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<true>(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<true>(n, x, beta, alpha,
                  sigma)));
  EXPECT_FLOAT_EQ((stan::math::normal_lpdf<false>(n, theta, sigma)),
                  (stan::math::normal_id_glm_lpdf<false>(n, x, beta, alpha,
                  sigma)));
  EXPECT_FLOAT_EQ(
    (stan::math::normal_lpdf
      <true, Matrix<int, Dynamic, 1>>(n, theta, sigma)),
    (stan::math::normal_id_glm_lpdf
      <true, Matrix<int, Dynamic, 1>>(n, x, beta, alpha, sigma)));
  EXPECT_FLOAT_EQ(
    (stan::math::normal_lpdf
      <false, Matrix<int, Dynamic, 1>>(n, theta, sigma)),
    (stan::math::normal_id_glm_lpdf
      <false, Matrix<int, Dynamic, 1>>(n, x, beta, alpha, sigma)));
  EXPECT_FLOAT_EQ(
    (stan::math::normal_lpdf<Matrix<int, Dynamic, 1>>(n, theta, sigma)),
    (stan::math::normal_id_glm_lpdf
      <Matrix<int, Dynamic, 1>>(n, x, beta, alpha, sigma)));
}

//  We check that the gradients of the new regression match those of one built
//  from existing primitives.
TEST(ProbDistributionsNormalIdGLM, glm_matches_normal_id_vars) {
  Matrix<int, Dynamic, 1> n(3, 1);
  n << 14, 32, 21;
  Matrix<var, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  var alpha = 0.3;
  Matrix<var, Dynamic, 1> sigma(3, 1);
  sigma << 10, 4, 6;
  Matrix<var, Dynamic, 1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<var, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;

  var lp = stan::math::normal_lpdf(n, theta, sigma);
  lp.grad();

  stan::math::recover_memory();

  Matrix<int, Dynamic, 1> n2(3, 1);
  n2 << 14, 32, 21;
  Matrix<var, Dynamic, Dynamic> x2(3, 2);
  x2 << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta2(2, 1);
  beta2 << 0.3, 2;
  var alpha2 = 0.3;
  Matrix<var, Dynamic, 1> sigma2(3, 1);
  sigma2 << 10, 4, 6;

  var lp2 = stan::math::normal_id_glm_lpdf(n2, x2, beta2, alpha2, sigma2);
  lp2.grad();

  EXPECT_FLOAT_EQ(lp.val(),
                  lp2.val());
  for (size_t i = 0; i < 2; i++) {
    EXPECT_FLOAT_EQ(beta[i].adj(), beta2[i].adj());
  }
  EXPECT_FLOAT_EQ(alpha.adj(), alpha2.adj());
  for (size_t j = 0; j < 3; j++) {
    EXPECT_FLOAT_EQ(sigma[j].adj(), sigma2[j].adj());
    for (size_t i = 0; i < 2; i++) {
      EXPECT_FLOAT_EQ(x(j, i).adj(), x2(j, i).adj());
    }
  }
}

//  Here, we compare the speed of the new regression to that of one built from
//  existing primitives.

/*

#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimeVar;
#define duration(a) \
  std::chrono::duration_cast<std::chrono::microseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

TEST(ProbDistributionsNormalIdGLM, glm_matches_normal_id_speed) {
  const int R = 30000;
  const int C = 1000;

  Matrix<int,Dynamic,1> n(R, 1);
  for (size_t i = 0; i < R; i++) {
    n[i] = rand()%2000;
  }

  int T1 = 0;
  int T2 = 0;

  for (size_t testnumber = 0; testnumber < 30; testnumber++){
    Matrix<double, Dynamic, Dynamic> xreal = Matrix<double, Dynamic, Dynamic>::Random(R, C);
    Matrix<double, Dynamic, 1> betareal = Matrix<double, Dynamic, Dynamic>::Random(C, 1);
    Matrix<double, Dynamic, 1> sigmareal = Matrix<double, Dynamic, Dynamic>::Random(R, 1)
      + Matrix<double, R, 1>::Ones();  // Random Matrix has entries between -1 and 1. We add 1 to it to get positive entries.
    Matrix<double, 1, 1> alphareal = Matrix<double, 1, 1>::Random(1, 1);
    Matrix<double, Dynamic, 1> alpharealvec = Matrix<double, R, 1>::Ones() * alphareal;

    Matrix<var, Dynamic, 1> beta = betareal;
    Matrix<var, Dynamic, 1> sigma = sigmareal;
    Matrix<var, Dynamic, 1> theta(R, 1);

    TimeVar t1 = timeNow();
    theta = (xreal * beta) + alpharealvec;
    var lp = stan::math::normal_lpdf(n, theta, sigma);

    lp.grad();
    TimeVar t2 = timeNow();

    stan::math::recover_memory();

    Matrix<var, Dynamic, 1> beta2 = betareal;
    Matrix<var, Dynamic, 1> sigma2 = sigmareal;

    TimeVar t3 = timeNow();
    var lp2 = stan::math::normal_id_glm_lpdf(n, xreal, beta2, alphareal[0],
      sigma2);
    lp2.grad();
    TimeVar t4 = timeNow();
    stan::math::recover_memory();
    T1 += duration(t2 - t1);
    T2 += duration(t4 - t3);

  }

  std::cout << "Existing Primitives:" << std::endl << T1 << std::endl  << "New Primitives:" << std::endl << T2 << std::endl;
}
*/
<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include <set>
#include <regex>
#include <iostream>

#include "retrace.hpp"
#include "metric_backend.hpp"
#include "metric_writer.hpp"
#include "metric_backend_amd_perfmon.hpp"
#include "metric_backend_intel_perfquery.hpp"

namespace glretrace {

bool metricBackendsSetup = false;
bool profilingBoundaries[QUERY_BOUNDARY_LIST_END] = {false};
unsigned profilingBoundariesIndex[QUERY_BOUNDARY_LIST_END] = {0};
std::vector<MetricBackend*> metricBackends; // to be populated in initContext()
MetricBackend* curMetricBackend = nullptr; // backend active in the current pass
MetricWriter profiler(metricBackends);

MetricBackend* getBackend(std::string backendName) {
    // to be populated with backends
    Context *currentContext = getCurrentContext();
    if (backendName == "GL_AMD_performance_monitor") return &MetricBackend_AMD_perfmon::getInstance(currentContext);
    else if (backendName == "GL_INTEL_performance_query") return &MetricBackend_INTEL_perfquery::getInstance(currentContext);
    else return nullptr;
}

bool
isLastPass() {
    return ( retrace::curPass + 1 >= retrace::numPasses );
}

/* Callbacks for listing metrics with --list-metrics */
void listMetrics_metricCallback(Metric* c, int error, void* userData) {
    static const std::string metricType[] = {"CNT_TYPE_GENERIC", "CNT_TYPE_NUM",
                                "CNT_TYPE_DURATION", "CNT_TYPE_PERCENT",
                                "CNT_TYPE_TIMESTAMP", "CNT_TYPE_OTHER"};
    static const std::string metricNumType[] = {"CNT_NUM_UINT", "CNT_NUM_FLOAT",
                                   "CNT_NUM_UINT64", "CNT_NUM_DOUBLE",
                                   "CNT_NUM_BOOL", "CNT_NUM_INT64"};

    std::cout << "    Metric #" << c->id() << ": " << c->name()
              << " (type: " << metricType[c->type()] << ", num. type: "
              << metricNumType[c->numType()] << ").\n";
    std::cout << "           Description: " << c->description() << "\n";
}

void listMetrics_groupCallback(unsigned g, int error, void* userData) {
    MetricBackend* b = reinterpret_cast<MetricBackend*>(userData);
    std::cout << "\n  Group #" << g << ": " << b->getGroupName(g) << ".\n";
    b->enumMetrics(g, listMetrics_metricCallback, userData);
}

void listMetricsCLI() {
    // backends is to be populated with backend names
    std::string backends[] = {"GL_AMD_performance_monitor",
                              "GL_INTEL_performance_query"};
    std::cout << "Available metrics: \n";
    for (auto s : backends) {
        auto b = getBackend(s);
        if (!b->isSupported()) {
            continue;
        }
        std::cout << "\nBackend " << s << ":\n";
        b->enumGroups(listMetrics_groupCallback, b);
        std::cout << std::endl;
    }
}

void enableMetricsFromCLI(const char* metrics, QueryBoundary pollingRule) {
    const std::regex rOuter("\\s*([^:]+):\\s*([^;]*);?"); // backend: (...)
    const std::regex rInner("\\s*\\[\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\]\\s*,?"
                            "|\\s*([^;,]+),?"); // [g, i] | metricName
    std::unique_ptr<Metric> p;
    std::string metricName;

    auto rOuter_it = std::cregex_token_iterator(metrics,
                                                metrics+std::strlen(metrics),
                                                rOuter, {1,2});
    auto rOuter_end = std::cregex_token_iterator();
    while (rOuter_it != rOuter_end) {
        static std::set<MetricBackend*> backendsHash; // for not allowing duplicates
        std::string backendName = (rOuter_it++)->str();
        MetricBackend* backend = getBackend(backendName);
        if (!backend) {
            std::cerr << "Warning: No backend \"" << backendName << "\"."
                      << std::endl;
            rOuter_it++;
            continue;
        }
        if (!backend->isSupported()) {
            std::cerr << "Warning: Backend \"" << backendName
                      << "\" is not supported." << std::endl;
            rOuter_it++;
            continue;
        }
        /**
         * order in metricBackends is important for output
         * also there should be no duplicates
         */
        if (backendsHash.find(backend) == backendsHash.end()) {
            metricBackends.push_back(backend);
            backendsHash.insert(backend);
        }

        auto rInner_it = std::cregex_token_iterator(rOuter_it->first, rOuter_it->second,
                                                    rInner, {1,2,3});
        auto rInner_end = std::cregex_token_iterator();
        while (rInner_it != rInner_end) {
            if (rInner_it->matched) {
                std::string groupId = (rInner_it++)->str();
                std::string metricId = (rInner_it++)->str();
                rInner_it++;
                p = backend->getMetricById(std::stoi(groupId), std::stoi(metricId));
                metricName = "[" + groupId + ", " + metricId + "]";
            } else {
                rInner_it++;
                rInner_it++;
                metricName = (rInner_it++)->str();
                p = backend->getMetricByName(metricName);
            }

            if (!p) {
                std::cerr << "Warning: No metric \"" << metricName
                    << "\"." << std::endl;
                continue;
            }
            int error = backend->enableMetric(p.get(), pollingRule);
            if (error) {
                std::cerr << "Warning: Metric " << metricName << " not enabled"
                             " (error " << error << ")." << std::endl;
            } else {
                profilingBoundaries[pollingRule] = true;
            }
        }
        rOuter_it++;
    }
}

} /* namespace glretrace */
<commit_msg>glretrace: Plug "opengl" backend to the collection.<commit_after>#include <string>
#include <vector>
#include <set>
#include <regex>
#include <iostream>

#include "retrace.hpp"
#include "metric_backend.hpp"
#include "metric_writer.hpp"
#include "metric_backend_amd_perfmon.hpp"
#include "metric_backend_intel_perfquery.hpp"
#include "metric_backend_opengl.hpp"

namespace glretrace {

bool metricBackendsSetup = false;
bool profilingBoundaries[QUERY_BOUNDARY_LIST_END] = {false};
unsigned profilingBoundariesIndex[QUERY_BOUNDARY_LIST_END] = {0};
std::vector<MetricBackend*> metricBackends; // to be populated in initContext()
MetricBackend* curMetricBackend = nullptr; // backend active in the current pass
MetricWriter profiler(metricBackends);

MetricBackend* getBackend(std::string backendName) {
    // to be populated with backends
    Context *currentContext = getCurrentContext();
    if (backendName == "GL_AMD_performance_monitor") return &MetricBackend_AMD_perfmon::getInstance(currentContext);
    else if (backendName == "GL_INTEL_performance_query") return &MetricBackend_INTEL_perfquery::getInstance(currentContext);
    else if (backendName == "opengl") return &MetricBackend_opengl::getInstance(currentContext);
    else return nullptr;
}

bool
isLastPass() {
    return ( retrace::curPass + 1 >= retrace::numPasses );
}

/* Callbacks for listing metrics with --list-metrics */
void listMetrics_metricCallback(Metric* c, int error, void* userData) {
    static const std::string metricType[] = {"CNT_TYPE_GENERIC", "CNT_TYPE_NUM",
                                "CNT_TYPE_DURATION", "CNT_TYPE_PERCENT",
                                "CNT_TYPE_TIMESTAMP", "CNT_TYPE_OTHER"};
    static const std::string metricNumType[] = {"CNT_NUM_UINT", "CNT_NUM_FLOAT",
                                   "CNT_NUM_UINT64", "CNT_NUM_DOUBLE",
                                   "CNT_NUM_BOOL", "CNT_NUM_INT64"};

    std::cout << "    Metric #" << c->id() << ": " << c->name()
              << " (type: " << metricType[c->type()] << ", num. type: "
              << metricNumType[c->numType()] << ").\n";
    std::cout << "           Description: " << c->description() << "\n";
}

void listMetrics_groupCallback(unsigned g, int error, void* userData) {
    MetricBackend* b = reinterpret_cast<MetricBackend*>(userData);
    std::cout << "\n  Group #" << g << ": " << b->getGroupName(g) << ".\n";
    b->enumMetrics(g, listMetrics_metricCallback, userData);
}

void listMetricsCLI() {
    // backends is to be populated with backend names
    std::string backends[] = {"GL_AMD_performance_monitor",
                              "GL_INTEL_performance_query",
                              "opengl"};
    std::cout << "Available metrics: \n";
    for (auto s : backends) {
        auto b = getBackend(s);
        if (!b->isSupported()) {
            continue;
        }
        std::cout << "\nBackend " << s << ":\n";
        b->enumGroups(listMetrics_groupCallback, b);
        std::cout << std::endl;
    }
}

void enableMetricsFromCLI(const char* metrics, QueryBoundary pollingRule) {
    const std::regex rOuter("\\s*([^:]+):\\s*([^;]*);?"); // backend: (...)
    const std::regex rInner("\\s*\\[\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\]\\s*,?"
                            "|\\s*([^;,]+),?"); // [g, i] | metricName
    std::unique_ptr<Metric> p;
    std::string metricName;

    auto rOuter_it = std::cregex_token_iterator(metrics,
                                                metrics+std::strlen(metrics),
                                                rOuter, {1,2});
    auto rOuter_end = std::cregex_token_iterator();
    while (rOuter_it != rOuter_end) {
        static std::set<MetricBackend*> backendsHash; // for not allowing duplicates
        std::string backendName = (rOuter_it++)->str();
        MetricBackend* backend = getBackend(backendName);
        if (!backend) {
            std::cerr << "Warning: No backend \"" << backendName << "\"."
                      << std::endl;
            rOuter_it++;
            continue;
        }
        if (!backend->isSupported()) {
            std::cerr << "Warning: Backend \"" << backendName
                      << "\" is not supported." << std::endl;
            rOuter_it++;
            continue;
        }
        /**
         * order in metricBackends is important for output
         * also there should be no duplicates
         */
        if (backendsHash.find(backend) == backendsHash.end()) {
            metricBackends.push_back(backend);
            backendsHash.insert(backend);
        }

        auto rInner_it = std::cregex_token_iterator(rOuter_it->first, rOuter_it->second,
                                                    rInner, {1,2,3});
        auto rInner_end = std::cregex_token_iterator();
        while (rInner_it != rInner_end) {
            if (rInner_it->matched) {
                std::string groupId = (rInner_it++)->str();
                std::string metricId = (rInner_it++)->str();
                rInner_it++;
                p = backend->getMetricById(std::stoi(groupId), std::stoi(metricId));
                metricName = "[" + groupId + ", " + metricId + "]";
            } else {
                rInner_it++;
                rInner_it++;
                metricName = (rInner_it++)->str();
                p = backend->getMetricByName(metricName);
            }

            if (!p) {
                std::cerr << "Warning: No metric \"" << metricName
                    << "\"." << std::endl;
                continue;
            }
            int error = backend->enableMetric(p.get(), pollingRule);
            if (error) {
                std::cerr << "Warning: Metric " << metricName << " not enabled"
                             " (error " << error << ")." << std::endl;
            } else {
                profilingBoundaries[pollingRule] = true;
            }
        }
        rOuter_it++;
    }
}

} /* namespace glretrace */
<|endoftext|>


<commit_before>/* Copyright 2016 Carnegie Mellon University, NVIDIA Corporation
 *
 * 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.
 */

#include "lightscan/util/caffe.h"
#include "lightscan/util/queue.h"
#include "lightscan/util/cuda.h"

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/errors.hpp>

#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudawarping.hpp>
#include <opencv2/cudaarithm.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/core/cuda_stream_accessor.hpp>

#include <fstream>
#include <thread>

namespace po = boost::program_options;

int GLOBAL_BATCH_SIZE = 64;      // Batch size for network

const std::string KCAM_DIRECTORY = "/Users/abpoms/kcam";

void worker(
  int gpu_device_id,
  std::vector<std::string>& video_paths,
  Queue<int>& work_items)
{
  // Set ourselves to the correct GPU
  CU_CHECK(cudaSetDevice(gpu_device_id));

  // Setup network to use for evaluation
  lightscan::NetInfo net_info =
    load_neural_net(lightscan::NetType::VGG, gpu_device_id);
  caffe::Net<float>* net = net_info.net;

  int dim = net_info.input_size;

  cv::Mat base_mean_frame(
    net_info.mean_width, net_info.mean_height, CV_32FC3, net_info.mean_image);

  cv::Mat mean_frame;
  cv::resize(base_mean_frame, mean_frame, cv::Size(dim, dim));

  const boost::shared_ptr<caffe::Blob<float>> data_blob{
    net->blob_by_name("data")};

  // Setup net input blob to feed frames into network
  caffe::Blob<float> net_input{GLOBAL_BATCH_SIZE, 3, dim, dim};

  cv::VideoCapture video;
  cv::Mat frame;
  cv::Mat resize_frame;
  cv::Mat float_frame;
  cv::Mat input_frame;

  while (true) {
    int work_item_index;
    work_items.pop(work_item_index);

    if (work_item_index == -1) {
      break;
    }

    const std::string& video_path = video_paths[work_item_index];

    video.open(KCAM_DIRECTORY + "/" + video_path);

    bool done = false;
    int frame_index = 0;
    while (!done) {
      int batch_size = GLOBAL_BATCH_SIZE;
      float* net_input_buffer = net_input.mutable_cpu_data();
      // Get batch of frames and convert into proper net input format
      int i = 0;
      for (; i < batch_size; ++i) {
        bool valid_frame = video.read(frame);
        if (!valid_frame) {
          done = true;
          break;
        }
        (void) valid_frame; assert(valid_frame);

        // Resize frame to net input, convert to float, and subract mean image
        cv::resize(frame, resize_frame, cv::Size(dim, dim));
        resize_frame.convertTo(float_frame, CV_32FC3);
        cv::subtract(float_frame, mean_frame, input_frame);

        memcpy(net_input_buffer + i * (dim * dim * 3),
               input_frame.data,
               dim * dim * 3 * sizeof(float));

        frame_index += 1;
      }
      batch_size = i;

      if (data_blob->shape(0) != batch_size) {
        data_blob->Reshape({batch_size, 3, dim, dim});
        net_input.Reshape({batch_size, 3, dim, dim});
      }

      // Evaluate net on batch of frames
      net->Forward({&net_input});
    }
  }
}

int main(int argc, char** argv) {
  std::string video_paths_file;
  {
    po::variables_map vm;
    po::options_description desc("Allowed options");
    desc.add_options()
      ("help", "Produce help message")
      ("video_paths_file", po::value<std::string>()->required(),
       "File which contains paths to video files to process")
      ("batch_size", po::value<int>(), "Neural Net input batch size")
      ("gpus_per_node", po::value<int>(), "GPUs to use per node");
    try {
      po::store(po::parse_command_line(argc, argv, desc), vm);
      po::notify(vm);

      if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
      }

      if (vm.count("batch_size")) {
        GLOBAL_BATCH_SIZE = vm["batch_size"].as<int>();
      }

      if (vm.count("gpus_per_node")) {
        GPUS_PER_NODE = vm["gpus_per_node"].as<int>();
      }

      video_paths_file = vm["video_paths_file"].as<std::string>();

    } catch (const po::required_option& e) {
      if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
      } else {
        throw e;
      }
    }
  }

  // Read in list of video paths
  std::vector<std::string> video_paths;
  {
    std::fstream fs(video_paths_file, std::fstream::in);
    while (fs) {
      std::string path;
      fs >> path;
      if (path.empty()) continue;
      video_paths.push_back(path);
    }
  }

  // Setup queue of work to distribute to threads
  Queue<int64_t> work_items;
  for (size_t i = 0; i < video_paths.size(); ++i) {
    work_items.push(i);
  }

  // Start up workers to process videos
  std::vector<std::thread> workers;
  for (int gpu = 0; gpu < GPUS_PER_NODE; ++gpu) {
    workers.emplace_back(worker, std::ref(video_paths), std::ref(work_items));
  }
  // Place sentinel values to end workers
  for (size_t i = 0; i < GPUS_PER_NODE; ++i) {
    work_items.push(-1);
  }
  // Wait for workers to finish
  for (int gpu = 0; gpu < GPUS_PER_NODE; ++gpu) {
    workers[gpu].join();
  }
}
<commit_msg>Fix typos<commit_after>/* Copyright 2016 Carnegie Mellon University, NVIDIA Corporation
 *
 * 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.
 */

#include "lightscan/util/caffe.h"
#include "lightscan/util/queue.h"
#include "lightscan/util/cuda.h"

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/errors.hpp>

#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudawarping.hpp>
#include <opencv2/cudaarithm.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/core/cuda_stream_accessor.hpp>

#include <fstream>
#include <thread>

namespace po = boost::program_options;

int GPUS_PER_NODE = 1;           // GPUs to use per node
int GLOBAL_BATCH_SIZE = 64;      // Batch size for network

const std::string KCAM_DIRECTORY = "/Users/abpoms/kcam";

void worker(
  int gpu_device_id,
  std::vector<std::string>& video_paths,
  Queue<int>& work_items)
{
  // Set ourselves to the correct GPU
  CU_CHECK(cudaSetDevice(gpu_device_id));

  // Setup network to use for evaluation
  lightscan::NetInfo net_info =
    load_neural_net(lightscan::NetType::VGG, gpu_device_id);
  caffe::Net<float>* net = net_info.net;

  int dim = net_info.input_size;

  cv::Mat base_mean_frame(
    net_info.mean_width, net_info.mean_height, CV_32FC3, net_info.mean_image);

  cv::Mat mean_frame;
  cv::resize(base_mean_frame, mean_frame, cv::Size(dim, dim));

  const boost::shared_ptr<caffe::Blob<float>> data_blob{
    net->blob_by_name("data")};

  // Setup net input blob to feed frames into network
  caffe::Blob<float> net_input{GLOBAL_BATCH_SIZE, 3, dim, dim};

  cv::VideoCapture video;
  cv::Mat frame;
  cv::Mat resize_frame;
  cv::Mat float_frame;
  cv::Mat input_frame;

  while (true) {
    int work_item_index;
    work_items.pop(work_item_index);

    if (work_item_index == -1) {
      break;
    }

    const std::string& video_path = video_paths[work_item_index];

    video.open(KCAM_DIRECTORY + "/" + video_path);

    bool done = false;
    int frame_index = 0;
    while (!done) {
      int batch_size = GLOBAL_BATCH_SIZE;
      float* net_input_buffer = net_input.mutable_cpu_data();
      // Get batch of frames and convert into proper net input format
      int i = 0;
      for (; i < batch_size; ++i) {
        bool valid_frame = video.read(frame);
        if (!valid_frame) {
          done = true;
          break;
        }
        (void) valid_frame; assert(valid_frame);

        // Resize frame to net input, convert to float, and subract mean image
        cv::resize(frame, resize_frame, cv::Size(dim, dim));
        resize_frame.convertTo(float_frame, CV_32FC3);
        cv::subtract(float_frame, mean_frame, input_frame);

        memcpy(net_input_buffer + i * (dim * dim * 3),
               input_frame.data,
               dim * dim * 3 * sizeof(float));

        frame_index += 1;
      }
      batch_size = i;

      if (data_blob->shape(0) != batch_size) {
        data_blob->Reshape({batch_size, 3, dim, dim});
        net_input.Reshape({batch_size, 3, dim, dim});
      }

      // Evaluate net on batch of frames
      net->Forward({&net_input});
    }
  }
}

int main(int argc, char** argv) {
  std::string video_paths_file;
  {
    po::variables_map vm;
    po::options_description desc("Allowed options");
    desc.add_options()
      ("help", "Produce help message")
      ("video_paths_file", po::value<std::string>()->required(),
       "File which contains paths to video files to process")
      ("batch_size", po::value<int>(), "Neural Net input batch size")
      ("gpus_per_node", po::value<int>(), "GPUs to use per node");
    try {
      po::store(po::parse_command_line(argc, argv, desc), vm);
      po::notify(vm);

      if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
      }

      if (vm.count("batch_size")) {
        GLOBAL_BATCH_SIZE = vm["batch_size"].as<int>();
      }

      if (vm.count("gpus_per_node")) {
        GPUS_PER_NODE = vm["gpus_per_node"].as<int>();
      }

      video_paths_file = vm["video_paths_file"].as<std::string>();

    } catch (const po::required_option& e) {
      if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
      } else {
        throw e;
      }
    }
  }

  // Read in list of video paths
  std::vector<std::string> video_paths;
  {
    std::fstream fs(video_paths_file, std::fstream::in);
    while (fs) {
      std::string path;
      fs >> path;
      if (path.empty()) continue;
      video_paths.push_back(path);
    }
  }

  // Setup queue of work to distribute to threads
  Queue<int64_t> work_items;
  for (size_t i = 0; i < video_paths.size(); ++i) {
    work_items.push(i);
  }

  // Start up workers to process videos
  std::vector<std::thread> workers;
  for (int gpu = 0; gpu < GPUS_PER_NODE; ++gpu) {
    workers.emplace_back(
      worker,
      gpu,
      std::ref(video_paths),
      std::ref(work_items));
  }
  // Place sentinel values to end workers
  for (size_t i = 0; i < GPUS_PER_NODE; ++i) {
    work_items.push(-1);
  }
  // Wait for workers to finish
  for (int gpu = 0; gpu < GPUS_PER_NODE; ++gpu) {
    workers[gpu].join();
  }
}
<|endoftext|>