<commit_before>#include "NormalPrior.h"

#include <iomanip>

#include <SmurffCpp/Utils/chol.h>
#include <SmurffCpp/Utils/linop.h>
#include <SmurffCpp/IO/MatrixIO.h>

#include <Eigen/Dense>
#include <Eigen/Sparse>

#include <SmurffCpp/Utils/Distribution.h>

using namespace Eigen;
using namespace smurff;

//  base class NormalPrior

NormalPrior::NormalPrior(std::shared_ptr<BaseSession> session, int mode, std::string name)
   : ILatentPrior(session, mode, name)
{

}

void NormalPrior::init()
{
   //does not look that there was such init previously
   ILatentPrior::init();

   //this is some new initialization
   initUU();

   const int K = num_latent();
   mu.resize(K);
   mu.setZero();

   Lambda.resize(K, K);
   Lambda.setIdentity();
   Lambda *= 10;

   // parameters of Inv-Whishart distribution
   WI.resize(K, K);
   WI.setIdentity();
   mu0.resize(K);
   mu0.setZero();
   b0 = 2;
   df = K;
}

const Eigen::VectorXd NormalPrior::getMu(int) const
{
    return mu;
}

void NormalPrior::update_prior()
{
   const int N = num_cols();

   const auto cov = UUcol.combine_and_reset();
   const auto sum = Ucol.combine_and_reset();

   std::tie(mu, Lambda) = CondNormalWishart(N, cov, sum, mu0, b0, WI, df);
}

void NormalPrior::sample_latent(int n)
{
   const auto &mu_u = getMu(n);

   VectorXd &rr = rrs.local();
   MatrixXd &MM = MMs.local();

   rr.setZero();
   MM.setZero();

   // add pnm
   data()->get_pnm(model(), m_mode, n, rr, MM);

   // add hyperparams
   rr.noalias() += Lambda * mu_u;
   MM.noalias() += Lambda;

   Eigen::LLT<MatrixXd> chol = MM.llt(); // compute the Cholesky decomposition
   if(chol.info() != Eigen::Success)
   {
      throw std::runtime_error("Cholesky Decomposition failed!");
   }

   chol.matrixL().solveInPlace(rr); // retrieve factor L  in the decomposition (lower triangular matrix)
                                    // rr = inverse(L) * rr
   rr.noalias() += nrandn(num_latent());
   chol.matrixU().solveInPlace(rr); // retrieve factor L  in the decomposition (upper triangular matrix)
                                    // rr = inverse(U) * rr
   U().col(n).noalias() = rr;
   Ucol.local().noalias() += rr;
   UUcol.local().noalias() += rr * rr.transpose();
}

void NormalPrior::save(std::string prefix, std::string suffix)
{
}

void NormalPrior::restore(std::string prefix, std::string suffix)
{
   initUU();
}

std::ostream &NormalPrior::status(std::ostream &os, std::string indent) const
{
   os << indent << m_name << ": mu = " <<  mu.norm() << std::endl;
   return os;
}

void NormalPrior::initUU()
{
    const int K = num_latent();
    Ucol.init(VectorXd::Zero(K));
    UUcol.init(MatrixXd::Zero(K, K));
    UUcol.local() = U() * U().transpose();
    Ucol.local() = U().rowwise().sum();
}

//macau Probit sample latents
/*
void BPMFPrior::sample_latents(ProbitNoise & noise, Eigen::MatrixXd &U, const Eigen::SparseMatrix<double> &mat,
   double mean_value, const Eigen::MatrixXd &samples, const int num_latent)
{
   const int N = U.cols();

   #pragma omp parallel for schedule(dynamic, 2)
   for(int n = 0; n < N; n++)
   {
      sample_latent_blas_probit(U, n, mat, mean_value, samples, mu, Lambda, num_latent);
   }
}
*/

//macau Tensor methods
/*
void BPMFPrior::sample_latents(ProbitNoise& noiseModel, TensorData & data,
                               std::vector< std::unique_ptr<Eigen::MatrixXd> > & samples,
                               int mode,
                               const int num_latent
                              )
{
  // TODO
  throw std::runtime_error("Unimplemented: sample_latents");
}
*/
/*
void BPMFPrior::sample_latents(double noisePrecision,
                               TensorData & data, // array of sparse views per dimention
                               std::vector< std::unique_ptr<Eigen::MatrixXd> > & samples, //vector of matrices per dimention ?
                               const int mode, //dimention index
                               const int num_latent //number of latent dimentions
                              )
{
  auto& sparseMode = (*data.Y)[mode]; // select sparse view by dimention index
  auto& U = samples[mode]; // select U matrix by dimention index
  const int N = U->cols();
  VectorView<Eigen::MatrixXd> view(samples, mode); // select all other samples except from dimention index

  #pragma omp parallel for schedule(dynamic, 2)
  for (int n = 0; n < N; n++) //iterate through each column of U
  {
    sample_latent_tensor(U, n, sparseMode, view, data.mean_value, noisePrecision, mu, Lambda);
  }
}
*/
<commit_msg>add more comments to NormalPrior<commit_after>#include "NormalPrior.h"

#include <iomanip>

#include <SmurffCpp/Utils/chol.h>
#include <SmurffCpp/Utils/linop.h>
#include <SmurffCpp/IO/MatrixIO.h>

#include <Eigen/Dense>
#include <Eigen/Sparse>

#include <SmurffCpp/Utils/Distribution.h>

using namespace Eigen;
using namespace smurff;

//  base class NormalPrior

NormalPrior::NormalPrior(std::shared_ptr<BaseSession> session, int mode, std::string name)
   : ILatentPrior(session, mode, name)
{

}

void NormalPrior::init()
{
   //does not look that there was such init previously
   ILatentPrior::init();

   //this is some new initialization
   initUU();

   const int K = num_latent();
   mu.resize(K);
   mu.setZero();

   Lambda.resize(K, K);
   Lambda.setIdentity();
   Lambda *= 10;

   // parameters of Inv-Whishart distribution
   WI.resize(K, K);
   WI.setIdentity();
   mu0.resize(K);
   mu0.setZero();
   b0 = 2;
   df = K;
}

const Eigen::VectorXd NormalPrior::getMu(int) const
{
    return mu;
}

void NormalPrior::update_prior()
{
   const int N = num_cols();

   const auto cov = UUcol.combine_and_reset();
   const auto sum = Ucol.combine_and_reset();

   std::tie(mu, Lambda) = CondNormalWishart(N, cov, sum, mu0, b0, WI, df);
}

void NormalPrior::sample_latent(int n)
{
   const auto &mu_u = getMu(n);

   VectorXd &rr = rrs.local();
   MatrixXd &MM = MMs.local();

   rr.setZero();
   MM.setZero();

   // add pnm
   data()->get_pnm(model(), m_mode, n, rr, MM);

   // add hyperparams
   rr.noalias() += Lambda * mu_u;
   MM.noalias() += Lambda;

   //Solve system of linear equations for x: MM * x = rr

   Eigen::LLT<MatrixXd> chol = MM.llt(); // compute the Cholesky decomposition X = L * U
   if(chol.info() != Eigen::Success)
   {
      throw std::runtime_error("Cholesky Decomposition failed!");
   }

   chol.matrixL().solveInPlace(rr); // solve for y: y = L^-1 * b
   rr.noalias() += nrandn(num_latent());
   chol.matrixU().solveInPlace(rr); // solve for x: x = U^-1 * y

   U().col(n).noalias() = rr; // rr is equal to x
   Ucol.local().noalias() += rr;
   UUcol.local().noalias() += rr * rr.transpose();
}

void NormalPrior::save(std::string prefix, std::string suffix)
{
}

void NormalPrior::restore(std::string prefix, std::string suffix)
{
   initUU();
}

std::ostream &NormalPrior::status(std::ostream &os, std::string indent) const
{
   os << indent << m_name << ": mu = " <<  mu.norm() << std::endl;
   return os;
}

void NormalPrior::initUU()
{
    const int K = num_latent();
    Ucol.init(VectorXd::Zero(K));
    UUcol.init(MatrixXd::Zero(K, K));
    UUcol.local() = U() * U().transpose();
    Ucol.local() = U().rowwise().sum();
}

//macau Probit sample latents
/*
void BPMFPrior::sample_latents(ProbitNoise & noise, Eigen::MatrixXd &U, const Eigen::SparseMatrix<double> &mat,
   double mean_value, const Eigen::MatrixXd &samples, const int num_latent)
{
   const int N = U.cols();

   #pragma omp parallel for schedule(dynamic, 2)
   for(int n = 0; n < N; n++)
   {
      sample_latent_blas_probit(U, n, mat, mean_value, samples, mu, Lambda, num_latent);
   }
}
*/

//macau Tensor methods
/*
void BPMFPrior::sample_latents(ProbitNoise& noiseModel, TensorData & data,
                               std::vector< std::unique_ptr<Eigen::MatrixXd> > & samples,
                               int mode,
                               const int num_latent
                              )
{
  // TODO
  throw std::runtime_error("Unimplemented: sample_latents");
}
*/
/*
void BPMFPrior::sample_latents(double noisePrecision,
                               TensorData & data, // array of sparse views per dimention
                               std::vector< std::unique_ptr<Eigen::MatrixXd> > & samples, //vector of sample matrices
                               const int mode, //dimention index
                               const int num_latent //number of latent dimentions
                              )
{
  auto& sparseMode = (*data.Y)[mode]; // select sparse view by dimention index
  auto& U = samples[mode]; // select U matrix by dimention index
  const int N = U->cols();
  VectorView<Eigen::MatrixXd> view(samples, mode); // select all other samples except from dimention index

  #pragma omp parallel for schedule(dynamic, 2)
  for (int n = 0; n < N; n++) //iterate through each column of U
  {
    sample_latent_tensor(U, n, sparseMode, view, data.mean_value, noisePrecision, mu, Lambda);
  }
}
*/
<|endoftext|>


<commit_before>#include "codesearch.h"
#include "interface.h"
#include "debug.h"
#include "git_indexer.h"
#include "interface-impl.h"

#include <json/json.h>

#include <gflags/gflags.h>

namespace {

json_object *to_json(const string &str) {
    return json_object_new_string(str.c_str());
}

json_object *to_json(const StringPiece &str) {
    return json_object_new_string_len(str.data(),
                                      str.size());
}

json_object *to_json(int i) {
    return json_object_new_int(i);
}

static json_object *to_json(const indexed_path &path) {
    json_object *out = json_object_new_object();
    json_object_object_add(out, "repo", to_json(path.tree->repo->name));
    json_object_object_add(out, "ref",  to_json(path.tree->revision));
    json_object_object_add(out, "path", to_json(path.path));
    return out;
}

json_object *to_json(const indexed_repo &repo) {
    json_object *out = json_object_new_object();
    json_object_object_add(out, "name", to_json(repo.name));
    if (repo.metadata)
        json_object_object_add(out, "metadata", json_object_get(repo.metadata));
    return out;
}

template <class T>
json_object *to_json(vector<T> vec) {
    json_object *out = json_object_new_array();
    for (auto it = vec.begin(); it != vec.end(); it++)
        json_object_array_add(out, to_json(*it));
    return out;
}

json_object *json_info(const code_searcher *cs) {
    json_object *obj = json_object_new_object();
    json_object_object_add(obj, "repos", to_json(cs->repos()));
    json_object_object_add(obj, "name", to_json(cs->name()));
    return obj;
}

long timeval_ms (struct timeval tv) {
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

struct repo_spec {
    string path;
    string name;
    vector<string> revisions;
    json_object *metadata;
};

repo_spec parse_repo_spec(json_object *js) {
    debug(kDebugUI, "Parsing: %s", json_object_to_json_string(js));
    if (!json_object_is_type(js, json_type_object)) {
        fprintf(stderr, "Repo spec is not an object!\n");
        exit(1);
    }

    repo_spec spec;
    json_object *js_path = json_object_object_get(js, "path");
    if (json_object_is_type(js_path, json_type_string))
        spec.path = json_object_get_string(js_path);
    json_object *js_name = json_object_object_get(js, "name");
    if (json_object_is_type(js_name, json_type_string))
        spec.name = json_object_get_string(js_name);
    spec.metadata = json_object_get(json_object_object_get(js, "metadata"));

    json_object *js_revs = json_object_object_get(js, "revisions");
    if (json_object_is_type(js_revs, json_type_array)) {
        for (int i = 0; i < json_object_array_length(js_revs); ++i) {
            json_object *elt = json_object_array_get_idx(js_revs, i);
            if (json_object_is_type(elt, json_type_string))
                spec.revisions.push_back(json_object_get_string(elt));
        }
    }

    return spec;
}

void extract_repo_specs(vector<repo_spec> &out, json_object *js) {
    switch(json_object_get_type(js)) {
    case json_type_object:
        debug(kDebugUI, "Parsing a single repo");
        out.push_back(parse_repo_spec(js));
        break;
    case json_type_array:
        debug(kDebugUI, "Parsing an array of repos...");
        for (int i = 0; i < json_object_array_length(js); ++i) {
            out.push_back(parse_repo_spec(json_object_array_get_idx(js, i)));
        }
        break;
    default:
        fprintf(stderr, "Error: unrecognized object type: %s\n",
                json_type_to_name(json_object_get_type(js)));
        exit(1);
    }
}

class json_interface : public codesearch_interface {
public:
    json_interface(FILE *in, FILE *out) : in_(in), out_(out) { }

    virtual void print_match(const match_result *m) {
        json_object *obj = json_object_new_object();
        json_object *contexts = json_object_new_array();
        for (auto ctx = m->context.begin();
             ctx != m->context.end(); ++ctx) {
            json_object *jctx = json_object_new_object();
            json_object_object_add(jctx, "paths",  to_json(ctx->paths));
            json_object_object_add(jctx, "lno", to_json(ctx->lno));
            json_object_object_add(jctx, "context_before",
                                   to_json(ctx->context_before));
            json_object_object_add(jctx, "context_after",
                                   to_json(ctx->context_after));
            json_object_array_add(contexts, jctx);
        }
        json_object_object_add(obj, "contexts", contexts);
        json_object *bounds = json_object_new_array();
        json_object_array_add(bounds, to_json(m->matchleft));
        json_object_array_add(bounds, to_json(m->matchright));
        json_object_object_add(obj, "bounds", bounds);
        json_object_object_add(obj, "line", to_json(m->line));
        fprintf(out_, "%s\n", json_object_to_json_string(obj));
        json_object_put(obj);
    }

    virtual void print_error(const std::string &err) {
        fprintf(out_, "FATAL %s\n", err.c_str());
    }

    virtual void print_prompt(const code_searcher *cs) {
        json_object *info = json_info(cs);
        fprintf(out_, "READY %s\n", json_object_to_json_string(info));
        json_object_put(info);
    }

    virtual bool getline(std::string &input) {
        return ::getline(input, in_);
    }

    virtual bool parse_query(const std::string &input,
                             std::string &line_re,
                             std::string &file_re,
                             std::string &tree_re) {
        json_object *js = json_tokener_parse(input.c_str());
        if (is_error(js)) {
            print_error("Parse error: " +
                        string(json_tokener_errors[-(unsigned long)js]));
            return false;
        }
        if (json_object_get_type(js) != json_type_object) {
            print_error("Expected a JSON object");
            return false;
        }

        json_object *line_js = json_object_object_get(js, "line");
        if (!line_js || json_object_get_type(line_js) != json_type_string) {
            print_error("No regex specified!");
            return false;
        }
        line_re = json_object_get_string(line_js);

        json_object *file_js = json_object_object_get(js, "file");
        if (file_js && json_object_get_type(file_js) == json_type_string)
            file_re = json_object_get_string(file_js);

        json_object *tree_js = json_object_object_get(js, "repo");
        if (tree_js && json_object_get_type(tree_js) == json_type_string)
            tree_re = json_object_get_string(tree_js);

        json_object_put(js);

        return true;
    }

    virtual void print_stats(timeval elapsed, const match_stats *stats) {
        json_object *obj = json_object_new_object();
        json_object_object_add(obj, "re2_time", json_object_new_int
                               (timeval_ms(stats->re2_time)));
        json_object_object_add(obj, "git_time", json_object_new_int
                               (timeval_ms(stats->git_time)));
        json_object_object_add(obj, "sort_time", json_object_new_int
                               (timeval_ms(stats->sort_time)));
        json_object_object_add(obj, "index_time", json_object_new_int
                               (timeval_ms(stats->index_time)));
        json_object_object_add(obj, "analyze_time", json_object_new_int
                               (timeval_ms(stats->analyze_time)));
        switch(stats->why) {
        case kExitNone: break;
        case kExitMatchLimit:
            json_object_object_add(obj, "why", json_object_new_string("limit"));
            break;
        case kExitTimeout:
            json_object_object_add(obj, "why", json_object_new_string("timeout"));
            break;
        }
        fprintf(out_, "DONE %s\n", json_object_to_json_string(obj));
        json_object_put(obj);
    }

    virtual void build_index(code_searcher *cs, const vector<std::string> &argv) {
        if (argv.size() != 2) {
            print_error("Usage: " + argv[0] + " --json [OPTIONS] config.json");
            exit(1);
        }
        json_object *obj = json_object_from_file(argv[1].c_str());
        if (is_error(obj)) {
            print_error(string("Error parsing `") + argv[1] + string("': ") +
                        string(json_tokener_errors[-(unsigned long)obj]));
            exit(1);
        }

        json_object *name = json_object_object_get(obj, "name");
        if (json_object_is_type(name, json_type_string))
            cs->set_name(json_object_get_string(name));

        vector<repo_spec> repos;
        extract_repo_specs(repos, json_object_object_get(obj, "repositories"));
        json_object_put(obj);

        for (auto it = repos.begin(); it != repos.end(); ++it) {
            debug(kDebugUI, "Walking name=%s, path=%s",
                  it->name.c_str(), it->path.c_str());
            git_indexer indexer(cs, it->path, it->name, it->metadata);
            for (auto rev = it->revisions.begin();
                 rev != it->revisions.end(); ++rev) {
                debug(kDebugUI, "  walking %s..", rev->c_str());
                indexer.walk(*rev);
            }
        }
    }

    virtual void info(const char *msg, ...) {}
    virtual ~json_interface() {}

protected:
    FILE *in_, *out_;
};

};

codesearch_interface *make_json_interface(FILE *in, FILE *out) {
    return new json_interface(in, out);
}
<commit_msg>Some build fixes for older libjson<commit_after>#include "codesearch.h"
#include "interface.h"
#include "debug.h"
#include "git_indexer.h"
#include "interface-impl.h"

#include <json/json.h>

#include <gflags/gflags.h>

namespace {

json_object *to_json(const string &str) {
    return json_object_new_string(str.c_str());
}

json_object *to_json(const StringPiece &str) {
    return json_object_new_string_len(str.data(),
                                      str.size());
}

json_object *to_json(int i) {
    return json_object_new_int(i);
}

static json_object *to_json(const indexed_path &path) {
    json_object *out = json_object_new_object();
    json_object_object_add(out, "repo", to_json(path.tree->repo->name));
    json_object_object_add(out, "ref",  to_json(path.tree->revision));
    json_object_object_add(out, "path", to_json(path.path));
    return out;
}

json_object *to_json(const indexed_repo &repo) {
    json_object *out = json_object_new_object();
    json_object_object_add(out, "name", to_json(repo.name));
    if (repo.metadata)
        json_object_object_add(out, "metadata", json_object_get(repo.metadata));
    return out;
}

template <class T>
json_object *to_json(vector<T> vec) {
    json_object *out = json_object_new_array();
    for (auto it = vec.begin(); it != vec.end(); it++)
        json_object_array_add(out, to_json(*it));
    return out;
}

json_object *json_info(const code_searcher *cs) {
    json_object *obj = json_object_new_object();
    json_object_object_add(obj, "repos", to_json(cs->repos()));
    json_object_object_add(obj, "name", to_json(cs->name()));
    return obj;
}

long timeval_ms (struct timeval tv) {
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

struct repo_spec {
    string path;
    string name;
    vector<string> revisions;
    json_object *metadata;
};

repo_spec parse_repo_spec(json_object *js) {
    debug(kDebugUI, "Parsing: %s", json_object_to_json_string(js));
    if (!json_object_is_type(js, json_type_object)) {
        fprintf(stderr, "Repo spec is not an object!\n");
        exit(1);
    }

    repo_spec spec;
    json_object *js_path = json_object_object_get(js, "path");
    if (json_object_is_type(js_path, json_type_string))
        spec.path = json_object_get_string(js_path);
    json_object *js_name = json_object_object_get(js, "name");
    if (json_object_is_type(js_name, json_type_string))
        spec.name = json_object_get_string(js_name);
    spec.metadata = json_object_get(json_object_object_get(js, "metadata"));

    json_object *js_revs = json_object_object_get(js, "revisions");
    if (json_object_is_type(js_revs, json_type_array)) {
        for (int i = 0; i < json_object_array_length(js_revs); ++i) {
            json_object *elt = json_object_array_get_idx(js_revs, i);
            if (json_object_is_type(elt, json_type_string))
                spec.revisions.push_back(json_object_get_string(elt));
        }
    }

    return spec;
}

void extract_repo_specs(vector<repo_spec> &out, json_object *js) {
    switch(json_object_get_type(js)) {
    case json_type_object:
        debug(kDebugUI, "Parsing a single repo");
        out.push_back(parse_repo_spec(js));
        break;
    case json_type_array:
        debug(kDebugUI, "Parsing an array of repos...");
        for (int i = 0; i < json_object_array_length(js); ++i) {
            out.push_back(parse_repo_spec(json_object_array_get_idx(js, i)));
        }
        break;
    default:
        fprintf(stderr, "Error: unrecognized type for repo spec: %s\n",
                json_object_to_json_string(js));
        exit(1);
    }
}

class json_interface : public codesearch_interface {
public:
    json_interface(FILE *in, FILE *out) : in_(in), out_(out) { }

    virtual void print_match(const match_result *m) {
        json_object *obj = json_object_new_object();
        json_object *contexts = json_object_new_array();
        for (auto ctx = m->context.begin();
             ctx != m->context.end(); ++ctx) {
            json_object *jctx = json_object_new_object();
            json_object_object_add(jctx, "paths",  to_json(ctx->paths));
            json_object_object_add(jctx, "lno", to_json(ctx->lno));
            json_object_object_add(jctx, "context_before",
                                   to_json(ctx->context_before));
            json_object_object_add(jctx, "context_after",
                                   to_json(ctx->context_after));
            json_object_array_add(contexts, jctx);
        }
        json_object_object_add(obj, "contexts", contexts);
        json_object *bounds = json_object_new_array();
        json_object_array_add(bounds, to_json(m->matchleft));
        json_object_array_add(bounds, to_json(m->matchright));
        json_object_object_add(obj, "bounds", bounds);
        json_object_object_add(obj, "line", to_json(m->line));
        fprintf(out_, "%s\n", json_object_to_json_string(obj));
        json_object_put(obj);
    }

    virtual void print_error(const std::string &err) {
        fprintf(out_, "FATAL %s\n", err.c_str());
    }

    virtual void print_prompt(const code_searcher *cs) {
        json_object *info = json_info(cs);
        fprintf(out_, "READY %s\n", json_object_to_json_string(info));
        json_object_put(info);
    }

    virtual bool getline(std::string &input) {
        return ::getline(input, in_);
    }

    virtual bool parse_query(const std::string &input,
                             std::string &line_re,
                             std::string &file_re,
                             std::string &tree_re) {
        json_object *js = json_tokener_parse(input.c_str());
        if (is_error(js)) {
            print_error("Parse error: " +
                        string(json_tokener_errors[-(unsigned long)js]));
            return false;
        }
        if (json_object_get_type(js) != json_type_object) {
            print_error("Expected a JSON object");
            return false;
        }

        json_object *line_js = json_object_object_get(js, "line");
        if (!line_js || json_object_get_type(line_js) != json_type_string) {
            print_error("No regex specified!");
            return false;
        }
        line_re = json_object_get_string(line_js);

        json_object *file_js = json_object_object_get(js, "file");
        if (file_js && json_object_get_type(file_js) == json_type_string)
            file_re = json_object_get_string(file_js);

        json_object *tree_js = json_object_object_get(js, "repo");
        if (tree_js && json_object_get_type(tree_js) == json_type_string)
            tree_re = json_object_get_string(tree_js);

        json_object_put(js);

        return true;
    }

    virtual void print_stats(timeval elapsed, const match_stats *stats) {
        json_object *obj = json_object_new_object();
        json_object_object_add(obj, "re2_time", json_object_new_int
                               (timeval_ms(stats->re2_time)));
        json_object_object_add(obj, "git_time", json_object_new_int
                               (timeval_ms(stats->git_time)));
        json_object_object_add(obj, "sort_time", json_object_new_int
                               (timeval_ms(stats->sort_time)));
        json_object_object_add(obj, "index_time", json_object_new_int
                               (timeval_ms(stats->index_time)));
        json_object_object_add(obj, "analyze_time", json_object_new_int
                               (timeval_ms(stats->analyze_time)));
        switch(stats->why) {
        case kExitNone: break;
        case kExitMatchLimit:
            json_object_object_add(obj, "why", json_object_new_string("limit"));
            break;
        case kExitTimeout:
            json_object_object_add(obj, "why", json_object_new_string("timeout"));
            break;
        }
        fprintf(out_, "DONE %s\n", json_object_to_json_string(obj));
        json_object_put(obj);
    }

    virtual void build_index(code_searcher *cs, const vector<std::string> &argv) {
        if (argv.size() != 2) {
            print_error("Usage: " + argv[0] + " --json [OPTIONS] config.json");
            exit(1);
        }
        json_object *obj = json_object_from_file(const_cast<char*>(argv[1].c_str()));
        if (is_error(obj)) {
            print_error(string("Error parsing `") + argv[1] + string("': ") +
                        string(json_tokener_errors[-(unsigned long)obj]));
            exit(1);
        }

        json_object *name = json_object_object_get(obj, "name");
        if (json_object_is_type(name, json_type_string))
            cs->set_name(json_object_get_string(name));

        vector<repo_spec> repos;
        extract_repo_specs(repos, json_object_object_get(obj, "repositories"));
        json_object_put(obj);

        for (auto it = repos.begin(); it != repos.end(); ++it) {
            debug(kDebugUI, "Walking name=%s, path=%s",
                  it->name.c_str(), it->path.c_str());
            git_indexer indexer(cs, it->path, it->name, it->metadata);
            for (auto rev = it->revisions.begin();
                 rev != it->revisions.end(); ++rev) {
                debug(kDebugUI, "  walking %s..", rev->c_str());
                indexer.walk(*rev);
            }
        }
    }

    virtual void info(const char *msg, ...) {}
    virtual ~json_interface() {}

protected:
    FILE *in_, *out_;
};

};

codesearch_interface *make_json_interface(FILE *in, FILE *out) {
    return new json_interface(in, out);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/test/TestRunner.h"

#include <cassert>
#include <iostream>

#include "db/test/Test.h"
#include "db/rt/Exception.h"

using namespace std;
using namespace db::rt;
using namespace db::test;

TestRunner::TestRunner(
   db::app::App* app, bool doneOnException, OutputLevel outputLevel)
{
   mApp = app;
   mOutputLevel = outputLevel;
   mTotal = 0;
   mPassed = 0;
   mWarnings = 0;
   mFailed = 0;
   mDoneOnException = doneOnException;
}

TestRunner::~TestRunner()
{
}

string TestRunner::getTestName()
{
   vector<string>::iterator i;
   string res;

   for(i = mTestPath.begin();
       i != mTestPath.end();
       i++)
   {
      res += *i;
   }

   return res;
}

db::app::App* TestRunner::getApp()
{
   return mApp;
}

TestRunner::OutputLevel TestRunner::getOutputLevel()
{
   return mOutputLevel;
}

/**
 * Map to convert output level option names to TestRunner::OutputLevel types
 */
struct outputLevelMap {
   const char* key;
   TestRunner::OutputLevel level;
};
static const struct outputLevelMap outputLevelsMap[] = {
   {"none", TestRunner::None},
   {"f", TestRunner::Final},
   {"final", TestRunner::Final},
   {"p", TestRunner::Progress},
   {"progress", TestRunner::Progress},
   {"n", TestRunner::Names},
   {"names", TestRunner::Names},
   {"t", TestRunner::Times},
   {"times", TestRunner::Times},
   {NULL, TestRunner::None}
};

bool TestRunner::stringToLevel(const char* slevel, OutputLevel& level)
{
   bool found = false;
   for(int mapi = 0;
      slevel != NULL&& !found && outputLevelsMap[mapi].key != NULL;
      mapi++)
   {
      if(strcasecmp(slevel, outputLevelsMap[mapi].key) == 0)
      {
         level = outputLevelsMap[mapi].level;
         found = true;
      }
   }

   return found;
}

const char* TestRunner::levelToString(OutputLevel level)
{
   const char* rval;

   switch(level)
   {
      case None:
         rval = "None";
         break;
      case Final:
         rval = "Final";
         break;
      case Progress:
         rval = "Progress";
         break;
      case Names:
         rval = "Names";
         break;
      case Times:
         rval = "Times";
         break;
      default:
         rval = NULL;
   }

   return rval;
}

void TestRunner::group(const char* name)
{
   mTestPath.push_back(string(name) + "/");
}

void TestRunner::ungroup()
{
   mTestPath.pop_back();
}

void TestRunner::test(const char* name)
{
   mTotal++;
   mTestPath.push_back(string(name));
   switch(mOutputLevel)
   {
      case Names:
      case Times:
         cout << getTestName() << "... ";
         cout.flush();
         break;
      default:
         break;
   }
   mTestPath.pop_back();
}

void TestRunner::pass()
{
   mPassed++;
   switch(mOutputLevel)
   {
      case Progress:
         cout << ".";
         cout.flush();
         break;
      case Names:
      case Times:
         cout << "PASS." << endl;
         cout.flush();
         break;
      default:
         break;
   }
}

void TestRunner::passIfNoException()
{
   if(Exception::hasLast())
   {
      fail();
      ExceptionRef e = Exception::getLast();
      dumpException(e);
      if(mDoneOnException)
      {
         done();
         assert(!Exception::hasLast());
      }
   }
   else
   {
      pass();
   }
}

void TestRunner::passIfException(bool dump)
{
   if(Exception::hasLast())
   {
      if(dump)
      {
         dumpException();
      }
      Exception::clearLast();
      pass();
   }
   else
   {
      // FIXME throw failure with expected exception
      fail();
   }
}

void TestRunner::fail(const char* reason)
{
   mFailed++;
   switch(mOutputLevel)
   {
      case Progress:
         cout << "F";
         cout.flush();
         break;
      case Names:
      case Times:
         cout << "FAIL." << endl;
         if(reason != NULL)
         {
            cout << reason << endl;
         }
         cout.flush();
         break;
      default:
         break;
   }
}

void TestRunner::warning(const char* reason)
{
   mWarnings++;
   switch(mOutputLevel)
   {
      case Progress:
         cout << "W";
         cout.flush();
         break;
      case Names:
      case Times:
         cout << "WARNING: ";
         if(reason != NULL)
         {
            cout << reason << endl;
         }
         else
         {
            cout << "(no reason given)" << endl;
         }
         cout.flush();
         break;
      default:
         break;
   }
}

void TestRunner::done()
{
   int unknown = mTotal - mPassed - mFailed;

   // Check that totals are sane.  Likely failure is mismatched
   // group/ungroup or test/pass/fail.
   assert(unknown >= 0);

   switch(mOutputLevel)
   {
      case Progress:
         // Progress just prints chars so force a newline if tests were done
         if(mTotal > 0)
         {
            cout << endl;
         }
         // fall through
      case Final:
      case Names:
      case Times:
         cout << "Done.";
         cout << " Total:" << mTotal;
         cout << " Passed:" << mPassed;
         cout << " Failed:" << mFailed;
         cout << " Warnings:" << mWarnings;
         cout << " Unknown:" << unknown;
         cout << "." << endl;
         break;
      default:
         break;
   }
}
<commit_msg>Test runner removes previous exception for PassIfException now.<commit_after>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/test/TestRunner.h"

#include <cassert>
#include <iostream>

#include "db/test/Test.h"
#include "db/rt/Exception.h"

using namespace std;
using namespace db::rt;
using namespace db::test;

TestRunner::TestRunner(
   db::app::App* app, bool doneOnException, OutputLevel outputLevel)
{
   mApp = app;
   mOutputLevel = outputLevel;
   mTotal = 0;
   mPassed = 0;
   mWarnings = 0;
   mFailed = 0;
   mDoneOnException = doneOnException;
}

TestRunner::~TestRunner()
{
}

string TestRunner::getTestName()
{
   vector<string>::iterator i;
   string res;

   for(i = mTestPath.begin();
       i != mTestPath.end();
       i++)
   {
      res += *i;
   }

   return res;
}

db::app::App* TestRunner::getApp()
{
   return mApp;
}

TestRunner::OutputLevel TestRunner::getOutputLevel()
{
   return mOutputLevel;
}

/**
 * Map to convert output level option names to TestRunner::OutputLevel types
 */
struct outputLevelMap {
   const char* key;
   TestRunner::OutputLevel level;
};
static const struct outputLevelMap outputLevelsMap[] = {
   {"none", TestRunner::None},
   {"f", TestRunner::Final},
   {"final", TestRunner::Final},
   {"p", TestRunner::Progress},
   {"progress", TestRunner::Progress},
   {"n", TestRunner::Names},
   {"names", TestRunner::Names},
   {"t", TestRunner::Times},
   {"times", TestRunner::Times},
   {NULL, TestRunner::None}
};

bool TestRunner::stringToLevel(const char* slevel, OutputLevel& level)
{
   bool found = false;
   for(int mapi = 0;
      slevel != NULL&& !found && outputLevelsMap[mapi].key != NULL;
      mapi++)
   {
      if(strcasecmp(slevel, outputLevelsMap[mapi].key) == 0)
      {
         level = outputLevelsMap[mapi].level;
         found = true;
      }
   }

   return found;
}

const char* TestRunner::levelToString(OutputLevel level)
{
   const char* rval;

   switch(level)
   {
      case None:
         rval = "None";
         break;
      case Final:
         rval = "Final";
         break;
      case Progress:
         rval = "Progress";
         break;
      case Names:
         rval = "Names";
         break;
      case Times:
         rval = "Times";
         break;
      default:
         rval = NULL;
   }

   return rval;
}

void TestRunner::group(const char* name)
{
   mTestPath.push_back(string(name) + "/");
}

void TestRunner::ungroup()
{
   mTestPath.pop_back();
}

void TestRunner::test(const char* name)
{
   mTotal++;
   mTestPath.push_back(string(name));
   switch(mOutputLevel)
   {
      case Names:
      case Times:
         cout << getTestName() << "... ";
         cout.flush();
         break;
      default:
         break;
   }
   mTestPath.pop_back();
}

void TestRunner::pass()
{
   mPassed++;
   switch(mOutputLevel)
   {
      case Progress:
         cout << ".";
         cout.flush();
         break;
      case Names:
      case Times:
         cout << "PASS." << endl;
         cout.flush();
         break;
      default:
         break;
   }
}

void TestRunner::passIfNoException()
{
   if(Exception::hasLast())
   {
      fail();
      ExceptionRef e = Exception::getLast();
      dumpException(e);
      if(mDoneOnException)
      {
         done();
         assert(!Exception::hasLast());
      }
      else
      {
         Exception::clearLast();
      }
   }
   else
   {
      pass();
   }
}

void TestRunner::passIfException(bool dump)
{
   if(Exception::hasLast())
   {
      if(dump)
      {
         dumpException();
      }
      Exception::clearLast();
      pass();
   }
   else
   {
      // FIXME throw failure with expected exception
      fail();
   }
}

void TestRunner::fail(const char* reason)
{
   mFailed++;
   switch(mOutputLevel)
   {
      case Progress:
         cout << "F";
         cout.flush();
         break;
      case Names:
      case Times:
         cout << "FAIL." << endl;
         if(reason != NULL)
         {
            cout << reason << endl;
         }
         cout.flush();
         break;
      default:
         break;
   }
}

void TestRunner::warning(const char* reason)
{
   mWarnings++;
   switch(mOutputLevel)
   {
      case Progress:
         cout << "W";
         cout.flush();
         break;
      case Names:
      case Times:
         cout << "WARNING: ";
         if(reason != NULL)
         {
            cout << reason << endl;
         }
         else
         {
            cout << "(no reason given)" << endl;
         }
         cout.flush();
         break;
      default:
         break;
   }
}

void TestRunner::done()
{
   int unknown = mTotal - mPassed - mFailed;

   // Check that totals are sane.  Likely failure is mismatched
   // group/ungroup or test/pass/fail.
   assert(unknown >= 0);

   switch(mOutputLevel)
   {
      case Progress:
         // Progress just prints chars so force a newline if tests were done
         if(mTotal > 0)
         {
            cout << endl;
         }
         // fall through
      case Final:
      case Names:
      case Times:
         cout << "Done.";
         cout << " Total:" << mTotal;
         cout << " Passed:" << mPassed;
         cout << " Failed:" << mFailed;
         cout << " Warnings:" << mWarnings;
         cout << " Unknown:" << unknown;
         cout << "." << endl;
         break;
      default:
         break;
   }
}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
#include "config.h"

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

#include <dune/grid/alugrid.hh>

#include <dune/stuff/functions/global.hh>
#include <dune/stuff/functions/constant.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/grid/provider/cube.hh>

#include <dune/gdt/products/l2.hh>
#include <dune/gdt/products/hcurl.hh>

#include "curlcurldiscretization.hh"

using namespace Dune;

int main() {
  // instantiate alugrid
  typedef Dune::ALUGrid< 3, 3, simplex, conforming > GridType;
  Stuff::Grid::Providers::Cube< GridType > grid_provider(0.0, 1.0, 4);
  auto& grid = grid_provider.grid();
  typedef GridType::LeafGridView LeafGridView;
  auto leafView = grid.leafGridView();
  typedef LeafGridView::Codim< 0 >::Entity EntityType;

  //test real discretization
  typedef Stuff::Functions::Expression< EntityType, double, 3, double, 3 > ExpressionFct;
  typedef Stuff::Functions::Constant< EntityType, double, 3, double, 1 >  ConstantFct;
  typedef Stuff::Functions::Constant< EntityType, double, 3, double, 3> VectorFct;

  const ConstantFct scalar1(1.0);
  const ConstantFct scalar2(-1.0);
  const ExpressionFct expsol("x", {"sin(pi*x[1])*sin(pi*x[2])", "sin(pi*x[0])*sin(pi*x[2])", "sin(pi*x[0])*sin(pi*x[1])"}, 2, "expectedsolution",
                             {{"0", "pi*cos(pi*x[1])*sin(pi*x[2])", "pi*sin(pi*x[1])*cos(pi*x[2])"},
                              {"pi*cos(pi*x[0])*sin(pi*x[2])", "0", "pi*sin(pi*x[0])*cos(pi*x[2])"},
                              {"pi*cos(pi*x[0])*sin(pi*x[1])", "pi*sin(pi*x[0])*cos(pi*x[1])", "0"}});
  const ConstantFct realweight(2*pi*pi-1.0);   //2*pi^2+scalar2
  const ConstantFct imagweight(1.0);           //scalar1

  const Stuff::Functions::Product< ConstantFct, ExpressionFct > freal(realweight, expsol);
  const Stuff::Functions::Product< ConstantFct, ExpressionFct > fimag(imagweight, expsol);

  DSG::BoundaryInfos::AllDirichlet< LeafGridView::Intersection > bdry_info;
  Discretization< LeafGridView, 1> realdiscr(leafView, bdry_info, scalar1, scalar2, scalar1, freal, fimag);
  typedef std::complex< double > complextype;
  Dune::Stuff::LA::Container< complextype >::VectorType sol;
  realdiscr.solve(sol);
  //realdiscr.visualize(sol, "discrete_solution", "discrete_solution");

  typedef Stuff::LA::Container< double, Stuff::LA::ChooseBackend::eigen_sparse>::VectorType VectorType;
  typedef GDT::Spaces::Nedelec::PdelabBased< LeafGridView, 1, double, 3> SpaceType;
  typedef GDT::ConstDiscreteFunction< SpaceType, VectorType > ConstDiscreteFct;
  Stuff::LA::Container< double >::VectorType solreal(sol.size());
  solreal.backend() = sol.backend().real();
  ConstDiscreteFct solasfunc(realdiscr.space(), solreal, "solution_as_discrete_function");

  //error computation
  typedef Stuff::Functions::Difference< ExpressionFct, ConstDiscreteFct > DifferenceFct;
  DifferenceFct myerror(expsol, solasfunc);
  GDT::Products::L2< LeafGridView> l2_product_operator(leafView);
  GDT::Products::HcurlSemi< LeafGridView > hcurl_product_operator(leafView);
  //  std::cout<< std::sqrt(l2_product_operator.apply2(myerror, myerror) + hcurl_product_operator.apply2(myerror, myerror))<< std::endl;

    return 0;
}

<commit_msg>[test/curlcurl-discretization] easy test case for curl curl discretization, with error computation<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
#include "config.h"

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

#include <dune/grid/alugrid.hh>

#include <dune/stuff/functions/global.hh>
#include <dune/stuff/functions/constant.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/grid/provider/cube.hh>

#include <dune/gdt/products/l2.hh>
#include <dune/gdt/products/hcurl.hh>

#include "curlcurldiscretization.hh"

// ------------------------------------------------------------------------
#include <dune/fem/gridpart/periodicgridpart/periodicgridpart.hh>
//#include <dune/gdt/localevaluation/hmm.hh>
#include "hmm-discretization.hh"
// ------------------------------------------------------------------------

using namespace Dune;

int main() {
  // instantiate alugrid
  typedef Dune::ALUGrid< 3, 3, simplex, conforming > GridType;
  Stuff::Grid::Providers::Cube< GridType > grid_provider(0.0, 1.0, 8);
  auto& grid = grid_provider.grid();
  typedef GridType::LeafGridView LeafGridView;
  auto leafView = grid.leafGridView();
  typedef LeafGridView::Codim< 0 >::Entity EntityType;

  //test real discretization
  typedef Stuff::Functions::Expression< EntityType, double, 3, double, 3 > ExpressionFct;
  typedef Stuff::Functions::Constant< EntityType, double, 3, double, 1 >  ConstantFct;
  typedef Stuff::Functions::Constant< EntityType, double, 3, double, 3> VectorFct;

  const ConstantFct scalar1(1.0);
  const ConstantFct scalar2(-1.0);
  const ExpressionFct expsol("x", {"sin(pi*x[1])*sin(pi*x[2])", "sin(pi*x[0])*sin(pi*x[2])", "sin(pi*x[0])*sin(pi*x[1])"}, 2, "expectedsolution",
                             {{"0", "pi*cos(pi*x[1])*sin(pi*x[2])", "pi*sin(pi*x[1])*cos(pi*x[2])"},
                              {"pi*cos(pi*x[0])*sin(pi*x[2])", "0", "pi*sin(pi*x[0])*cos(pi*x[2])"},
                              {"pi*cos(pi*x[0])*sin(pi*x[1])", "pi*sin(pi*x[0])*cos(pi*x[1])", "0"}});
  const double pi = 3.141592653589793;
  const ConstantFct realweight(2*pi*pi-1.0);   //2*pi^2+scalar2
  const ConstantFct imagweight(1.0);           //scalar1

  const Stuff::Functions::Product< ConstantFct, ExpressionFct > freal(realweight, expsol);
  const Stuff::Functions::Product< ConstantFct, ExpressionFct > fimag(imagweight, expsol);

  //expsol.visualize(leafView, "expectedsolution", false);

  DSG::BoundaryInfos::AllDirichlet< LeafGridView::Intersection > bdry_info;
  Discretization< LeafGridView, 1> realdiscr(leafView, bdry_info, scalar1, scalar2, scalar1, freal, fimag);
  typedef std::complex< double > complextype;
  std::cout<< "assembling"<<std::endl;
  realdiscr.assemble();
  Dune::Stuff::LA::Container< complextype >::VectorType sol;
  std::cout<<"solving with bicgstab.diagonal"<<std::endl;
  realdiscr.solve(sol);
  std::cout<< (realdiscr.system_matrix()*sol-realdiscr.rhs_vector()).sup_norm()<< std::endl;
  //realdiscr.visualize(sol, "discrete_solution", "discrete_solution");

  typedef Stuff::LA::Container< double, Stuff::LA::ChooseBackend::eigen_sparse>::VectorType VectorType;
  typedef GDT::Spaces::Nedelec::PdelabBased< LeafGridView, 1, double, 3> SpaceType;
  typedef GDT::ConstDiscreteFunction< SpaceType, VectorType > ConstDiscreteFct;
  Stuff::LA::Container< double >::VectorType solreal(sol.size());
  solreal.backend() = sol.backend().cwiseAbs();
  ConstDiscreteFct solasfunc(realdiscr.space(), solreal, "solution_as_discrete_function");

  //error computation
  typedef Stuff::Functions::Difference< ExpressionFct, ConstDiscreteFct > DifferenceFct;
  DifferenceFct myerror(expsol, solasfunc);
  std::cout<< "error computation"<<std::endl;
  GDT::Products::L2< LeafGridView> l2_product_operator(leafView);
  GDT::Products::HcurlSemi< LeafGridView > hcurl_product_operator(leafView);
  const double abserror = std::sqrt(l2_product_operator.apply2(myerror, myerror) + hcurl_product_operator.apply2(myerror, myerror));
  const double relerror = abserror/(std::sqrt(l2_product_operator.apply2(expsol, expsol) + hcurl_product_operator.apply2(expsol, expsol)));
  std::cout<< "absolute error: "<< abserror << std::endl;
  std::cout<< "relative error: "<< relerror <<std::endl;

  //------------------------------------------------------------------------------------------------------------------------------------------------
  //test hmm-discretization
  // elliptic cell problem
  /*typedef Fem::PeriodicLeafGridPart< GridType >::GridType PeriodicGridType;
  Stuff::Grid::Providers::Cube< PeriodicGridType > periodic_grid_provider(0.0, 1.0, 6);
  auto& periodic_grid = periodic_grid_provider.grid();
  typedef PeriodicGridType::LeafGridView PeriodicLeafView;
  auto periodic_leafview = periodic_grid.leafGridView();
  FieldVector< double, 3> wert(0.0);
  wert[0] = 1.0;
  VectorFct vectorial(wert);
  Cell< PeriodicLeafView, 1, LeafGridView, ChooseCellProblem::Elliptic > ellipticell(periodic_leafview, scalar1);
  auto cellsol = ellipticell.create_vector();
  ellipticell.solve(cellsol, vectorial, 0.1, Dune::FieldVector< double, 3 >(0.5));
  std::cout<< (ellipticell.system_matrix()*cellsol-ellipticell.rhs_vector()).sup_norm() <<std::endl;
  // in this case error.sup_norm()=1.5e-5>post_cehck_solves_system=1e-5 but wiht more elements it works pretty well
  // isn't it better possible or is there a bug in the code?

  //curlcurl cell problem
  Cell< PeriodicLeafView, 1, LeafGridView, ChooseCellProblem::CurlcurlDivreg> curlcell(periodic_leafview, scalar1);
  VectorFct zero(0.0);
  auto cellsol1 = curlcell.create_vector();
  curlcell.solve(cellsol1, vectorial, 0.1, Dune::FieldVector< double, 3 >(0.5));
  std::cout<< (curlcell.system_matrix()*cellsol1-curlcell.rhs_vector()).sup_norm() <<std::endl;*/
  return 0;
}

<|endoftext|>


<commit_before>// -*- coding: us-ascii-unix -*-
// Copyright 2015 Lukas Kemmer
//
// 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 "bitmap/bitmap-exception.hh"
#include "formats/png/file-png.hh"
#include "formats/png/png-util.hh"
#include "formats/png/read-libpng.hh"
#include "formats/png/write-libpng.hh"
#include "geo/limits.hh"
#include "text/formatting.hh"

namespace faint{

int to_png_color_type(PngColorType c){
  switch (c){
  case PngColorType::RGB:
    return PNG_COLOR_TYPE_RGB;

  case PngColorType::RGB_ALPHA:
    return PNG_COLOR_TYPE_RGB_ALPHA;

  case PngColorType::GRAY:
    return PNG_COLOR_TYPE_GRAY;

  case PngColorType::GRAY_ALPHA:
    return PNG_COLOR_TYPE_GRAY_ALPHA;
  }
  assert(false);
  return -1;
}

static utf8_string to_string(PngReadResult result, const FilePath& p){
  using R = PngReadResult;

  auto failed_read = [](const utf8_string& s){
    return endline_sep("Failed reading png.\n", s);
  };

  auto failed_read_libpng = [&](const utf8_string& func){
    return failed_read(space_sep("libpng", quoted(func), "exited with error."));
  };

  if (result == R::OK){
    return "No error";
  }
  else if (result == R::ERROR_OPEN_FILE){
    return failed_read(endline_sep("File could not be opened for reading.",
      space_sep("File:", p.Str())));
  }
  else if (result == R::ERROR_PNG_SIGNATURE){
    return failed_read("Incorrect PNG signature.");
  }
  else if (result == R::ERROR_CREATE_READ_STRUCT){
    return failed_read_libpng("create_read_struct");
  }
  else if (result == R::ERROR_CREATE_INFO_STRUCT){
    return failed_read_libpng("png_create_info_struct");
  }
  else if (result == R::ERROR_INIT_IO){
    return failed_read_libpng("png_init_io");
  }
  else if (result == R::ERROR_READ_DATA){
    return failed_read_libpng("png_read_image");
  }
  else if (result == R::ERROR_MALLOC){
    return failed_read_libpng("Out of memory.");
  }
  else{
    return failed_read("For reasons unknown.");
  }
}

static utf8_string color_type_to_string(png_byte colorType){
  if (colorType == PNG_COLOR_TYPE_GRAY){
    return "PNG_COLOR_TYPE_GRAY";
  }
  else if (colorType == PNG_COLOR_TYPE_PALETTE){
    return "PNG_COLOR_TYPE_PALETTE";
  }
  else if (colorType == PNG_COLOR_TYPE_RGB){
    return "PNG_COLOR_TYPE_RGB";
  }
  else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA){
    return "PNG_COLOR_TYPE_ALPHA";
  }
  else if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA){
    return "PNG_COLOR_TYPE_GRAY_ALPHA";
  }
  else{
    return space_sep("UNKNOWN", bracketed(str_int(colorType)));
  }
}

OrError<Bitmap_and_tEXt> read_png_meta(const FilePath& path){

  // --
  // Output parameters
  png_byte* rows = nullptr;
  png_uint_32 width;
  png_uint_32 height;
  png_byte colorType;
  png_byte bitDepth;
  int pngBitsPerPixel;
  png_tEXt_map textChunks;
  png_color* palette = nullptr;
  int numPalette = 0;

  PngReadResult result = read_with_libpng(path.Str().c_str(),
    &rows,
    &width,
    &height,
    &colorType,
    &bitDepth,
    &pngBitsPerPixel,
    &palette,
    &numPalette,
    textChunks);
  // --

  if (result != PngReadResult::OK){
    return to_string(result, path);
  }

  if (bitDepth != 8){
    free(rows);
    return {"Unsupported bit depth: " + str_int(bitDepth)};
  }

  if (!rgb_or_rgba(colorType) && !gray_or_gray_alpha(colorType) &&
    !palettized(colorType))
  {
    free(rows);
    return {"Unsuppored png color-type: " + color_type_to_string(colorType)};
  }

  if (colorType == PNG_COLOR_TYPE_GRAY){
    if (pngBitsPerPixel != 8){
      return {"Unsupported bits-per-pixel for PNG_COLOR_TYPE GRAY: " +
          str_int(pngBitsPerPixel)};
    }
  }
  else if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA){
    if (pngBitsPerPixel != 16){
      return {"Unsupported bits-per-pixel for PNG_COLOR_TYPE_GRAY_ALPHA: " +
          str_int(pngBitsPerPixel)};
    }
  }
  else if (colorType == PNG_COLOR_TYPE_PALETTE){
    if (pngBitsPerPixel != 8){
      free(palette);
      return {"Unsupported bits-per-pixel for PNG_COLOR_TYPE_PALETTE; " +
          str_int(pngBitsPerPixel)};
    }
  }
  else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA){
    if (pngBitsPerPixel != 32 && pngBitsPerPixel != 24){
      return {"Unsupported bits-per-pixel: " + str_int(pngBitsPerPixel)};
    }
  }

  if (!can_represent<IntSize::value_type>(width)){
    return {"Unsupported png-width"};
  }

  if (!can_represent<IntSize::value_type>(height)){
    return {"Unsupported png-height"};
  }

  try {
    // Read the data into a faint-Bitmap
    Bitmap bmp(IntSize(static_cast<int>(width), static_cast<int>(height)));
    auto* p = bmp.GetRaw();
    const png_uint_32 stride = convert(bmp.GetStride());
    const png_uint_32 BMP_BPP = convert(faint::BPP);
    const png_uint_32 PNG_BPP = convert(pngBitsPerPixel / 8);

    if (gray_or_gray_alpha(colorType)){
      // Read GRAY

      for (png_uint_32 y = 0; y < height; y++){
        const auto* row = rows + y * width * PNG_BPP;
        for (png_uint_32 x = 0; x < width; x++){
          auto i =  y * stride + x * BMP_BPP;
          const png_byte v = row[x * PNG_BPP];
          p[i + faint::iR] = v;
          p[i + faint::iG] = v;
          p[i + faint::iB] = v;
          p[i + faint::iA] = (colorType == PNG_COLOR_TYPE_GRAY_ALPHA) ?
            row[x * PNG_BPP + 1] : faint::CHANNEL_MAX;
        }
      }
    }
    else if (rgb_or_rgba(colorType)){
      // Read RGB or RGBA

      for (png_uint_32 y = 0; y < height; y++){
        const auto* row = rows + y * width * PNG_BPP;
        for (png_uint_32 x = 0; x < width; x++){
          auto i =  y * stride + x * BMP_BPP;
          p[i + faint::iR] = row[x * PNG_BPP];
          p[i + faint::iG] = row[x * PNG_BPP + 1];
          p[i + faint::iB] = row[x * PNG_BPP + 2];
          if (PNG_BPP == 3){
            p[i + faint::iA] = 255;
          }
          else{
            p[i + faint::iA] = row[x * PNG_BPP + 3];
          }
        }
      }
    }
    else if (palettized(colorType)){
      for (png_uint_32 y = 0; y < height; y++){
        const auto* row = rows + y * width * PNG_BPP;

        for (png_uint_32 x = 0; x < width; x++){
          auto i =  y * stride + x * BMP_BPP;
          auto paletteIndex = row[x * PNG_BPP]; // PNG_BPP Should be 1 probably.
          auto color = palette[paletteIndex];

          p[i + faint::iR] = color.red;
          p[i + faint::iG] = color.green;
          p[i + faint::iB] = color.blue;
          p[i + faint::iA] = 255;
        }
      }
      free(palette);
    }

    free(rows);
    return {Bitmap_and_tEXt(std::move(bmp), std::move(textChunks))};
  }
  catch (const BitmapException& e){
    free(rows);
    return {e.what()};
  }
}

OrError<Bitmap> read_png(const FilePath& p){
  return read_png_meta(p).Visit(
    [](const Bitmap_and_tEXt& result){
      return OrError<Bitmap>(result.bmp);
    },
    [](const utf8_string& error){
      return OrError<Bitmap>(error);
    });
}

static utf8_string to_string(PngWriteResult result, const FilePath& p){
  using R = PngWriteResult;

  auto failed_write = [](const utf8_string& s){
    return endline_sep("Failed saving png.\n", s);
  };

  auto failed_write_libpng = [&](const utf8_string& func){
    return failed_write(space_sep("libpng", quoted(func), "exited with error."));
  };

  if (result == R::OK){
    return "No error";
  }
  else if (result == R::ERROR_OPEN_FILE){
    return failed_write(endline_sep("File could not be opened for writing.",
      space_sep("File:", p.Str())));
  }
  else if (result == R::ERROR_CREATE_WRITE_STRUCT){
    return failed_write_libpng("png_create_write_struct");
  }
  else if (result == R::ERROR_INIT_IO){
    return failed_write_libpng("png_init_io");
  }
  else if (result == R::ERROR_WRITE_HEADER){
    return failed_write_libpng("png_write_info");
  }
  else if (result == R::ERROR_WRITE_DATA){
    return failed_write_libpng("png_write_image");
  }
  else if (result == R::ERROR_WRITE_END){
    return failed_write_libpng("png_write_end");
  }
  else if (result == R::ERROR_WRITE_TEXT_KEY_ENCODING){
    return failed_write(endline_sep("A specified tEXt-chunk key was not ascii.",
      "Faint only supports ascii tEXt-chunks."));
  }
  else if (result == R::ERROR_WRITE_TEXT_KEY_EMPTY){
    return failed_write("An empty key was specified for a tEXt-chunk.");
  }
  else if (result == R::ERROR_WRITE_TEXT_KEY_TOO_LONG){
    return failed_write("Keys for tEXt-chunks may be at most " +
      str_int(PNG_KEYWORD_MAX_LENGTH) + "-characters");
  }
  else if (result == R::ERROR_WRITE_TEXT_VALUE_TOO_LONG){
    return failed_write("A value for a tEXt-chunks exceeded capacity of "
      "png_size_t.");
  }
  else{
    return failed_write("For reasons unknown.");
  }
}

SaveResult write_png(const FilePath& path,
  const Bitmap& bmp,
  PngColorType colorType,
  const png_tEXt_map& textChunks)
{
  PngWriteResult result = write_with_libpng(path.Str().c_str(), bmp,
    to_png_color_type(colorType),
    textChunks);

  return result == PngWriteResult::OK ?
    SaveResult::SaveSuccessful() :
    SaveResult::SaveFailed(to_string(result, path));
}

SaveResult write_png(const FilePath& path,
  const Bitmap& bmp,
  PngColorType colorType)
{
  png_tEXt_map noChunks;
  return write_png(path, bmp, colorType, noChunks);
}

const utf8_string get_libpng_version(){
  return utf8_string(PNG_LIBPNG_VER_STRING);
}

} // namespace
<commit_msg>Renamed some variables or something.<commit_after>// -*- coding: us-ascii-unix -*-
// Copyright 2015 Lukas Kemmer
//
// 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 "bitmap/bitmap-exception.hh"
#include "formats/png/file-png.hh"
#include "formats/png/png-util.hh"
#include "formats/png/read-libpng.hh"
#include "formats/png/write-libpng.hh"
#include "geo/limits.hh"
#include "text/formatting.hh"

namespace faint{

int to_png_color_type(PngColorType c){
  switch (c){
  case PngColorType::RGB:
    return PNG_COLOR_TYPE_RGB;

  case PngColorType::RGB_ALPHA:
    return PNG_COLOR_TYPE_RGB_ALPHA;

  case PngColorType::GRAY:
    return PNG_COLOR_TYPE_GRAY;

  case PngColorType::GRAY_ALPHA:
    return PNG_COLOR_TYPE_GRAY_ALPHA;
  }
  assert(false);
  return -1;
}

static utf8_string to_string(PngReadResult result, const FilePath& p){
  using R = PngReadResult;

  auto failed_read = [](const utf8_string& s){
    return endline_sep("Failed reading png.\n", s);
  };

  auto failed_read_libpng = [&](const utf8_string& func){
    return failed_read(space_sep("libpng", quoted(func), "exited with error."));
  };

  if (result == R::OK){
    return "No error";
  }
  else if (result == R::ERROR_OPEN_FILE){
    return failed_read(endline_sep("File could not be opened for reading.",
      space_sep("File:", p.Str())));
  }
  else if (result == R::ERROR_PNG_SIGNATURE){
    return failed_read("Incorrect PNG signature.");
  }
  else if (result == R::ERROR_CREATE_READ_STRUCT){
    return failed_read_libpng("create_read_struct");
  }
  else if (result == R::ERROR_CREATE_INFO_STRUCT){
    return failed_read_libpng("png_create_info_struct");
  }
  else if (result == R::ERROR_INIT_IO){
    return failed_read_libpng("png_init_io");
  }
  else if (result == R::ERROR_READ_DATA){
    return failed_read_libpng("png_read_image");
  }
  else if (result == R::ERROR_MALLOC){
    return failed_read_libpng("Out of memory.");
  }
  else{
    return failed_read("For reasons unknown.");
  }
}

static utf8_string color_type_to_string(png_byte colorType){
  if (colorType == PNG_COLOR_TYPE_GRAY){
    return "PNG_COLOR_TYPE_GRAY";
  }
  else if (colorType == PNG_COLOR_TYPE_PALETTE){
    return "PNG_COLOR_TYPE_PALETTE";
  }
  else if (colorType == PNG_COLOR_TYPE_RGB){
    return "PNG_COLOR_TYPE_RGB";
  }
  else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA){
    return "PNG_COLOR_TYPE_ALPHA";
  }
  else if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA){
    return "PNG_COLOR_TYPE_GRAY_ALPHA";
  }
  else{
    return space_sep("UNKNOWN", bracketed(str_int(colorType)));
  }
}

OrError<Bitmap_and_tEXt> read_png_meta(const FilePath& path){

  // --
  // Output parameters
  png_byte* rows = nullptr;
  png_uint_32 width;
  png_uint_32 height;
  png_byte colorType;
  png_byte bitDepth;
  int pngBitsPerPixel;
  png_tEXt_map textChunks;
  png_color* palette = nullptr;
  int numPalette = 0;

  PngReadResult result = read_with_libpng(path.Str().c_str(),
    &rows,
    &width,
    &height,
    &colorType,
    &bitDepth,
    &pngBitsPerPixel,
    &palette,
    &numPalette,
    textChunks);
  // --

  if (result != PngReadResult::OK){
    return to_string(result, path);
  }

  if (bitDepth != 8){
    free(rows);
    return {"Unsupported bit depth: " + str_int(bitDepth)};
  }

  if (!rgb_or_rgba(colorType) && !gray_or_gray_alpha(colorType) &&
    !palettized(colorType))
  {
    free(rows);
    return {"Unsuppored png color-type: " + color_type_to_string(colorType)};
  }

  if (colorType == PNG_COLOR_TYPE_GRAY){
    if (pngBitsPerPixel != 8){
      return {"Unsupported bits-per-pixel for PNG_COLOR_TYPE GRAY: " +
          str_int(pngBitsPerPixel)};
    }
  }
  else if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA){
    if (pngBitsPerPixel != 16){
      return {"Unsupported bits-per-pixel for PNG_COLOR_TYPE_GRAY_ALPHA: " +
          str_int(pngBitsPerPixel)};
    }
  }
  else if (colorType == PNG_COLOR_TYPE_PALETTE){
    if (pngBitsPerPixel != 8){
      free(palette);
      return {"Unsupported bits-per-pixel for PNG_COLOR_TYPE_PALETTE; " +
          str_int(pngBitsPerPixel)};
    }
  }
  else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA){
    if (pngBitsPerPixel != 32 && pngBitsPerPixel != 24){
      return {"Unsupported bits-per-pixel: " + str_int(pngBitsPerPixel)};
    }
  }

  if (!can_represent<IntSize::value_type>(width)){
    return {"Unsupported png-width"};
  }

  if (!can_represent<IntSize::value_type>(height)){
    return {"Unsupported png-height"};
  }

  try {
    // Read the data into a faint-Bitmap
    Bitmap bmp(IntSize(static_cast<int>(width), static_cast<int>(height)));
    auto* p = bmp.GetRaw();
    const auto bmpStride = bmp.GetStride();
    const auto bmpBpp = faint::BPP;
    const png_uint_32 PNG_BPP = convert(pngBitsPerPixel / 8);

    if (gray_or_gray_alpha(colorType)){
      // Read GRAY

      for (png_uint_32 y = 0; y < height; y++){
        const auto* row = rows + y * width * PNG_BPP;
        for (png_uint_32 x = 0; x < width; x++){
          auto i =  y * bmpStride + x * bmpBpp;
          const png_byte v = row[x * PNG_BPP];
          p[i + faint::iR] = v;
          p[i + faint::iG] = v;
          p[i + faint::iB] = v;
          p[i + faint::iA] = (colorType == PNG_COLOR_TYPE_GRAY_ALPHA) ?
            row[x * PNG_BPP + 1] : faint::CHANNEL_MAX;
        }
      }
    }
    else if (rgb_or_rgba(colorType)){
      // Read RGB or RGBA

      for (png_uint_32 y = 0; y < height; y++){
        const auto* row = rows + y * width * PNG_BPP;
        for (png_uint_32 x = 0; x < width; x++){
          auto i =  y * bmpStride + x * bmpBpp;
          p[i + faint::iR] = row[x * PNG_BPP];
          p[i + faint::iG] = row[x * PNG_BPP + 1];
          p[i + faint::iB] = row[x * PNG_BPP + 2];
          if (PNG_BPP == 3){
            p[i + faint::iA] = 255;
          }
          else{
            p[i + faint::iA] = row[x * PNG_BPP + 3];
          }
        }
      }
    }
    else if (palettized(colorType)){
      for (png_uint_32 y = 0; y < height; y++){
        const auto* row = rows + y * width * PNG_BPP;

        for (png_uint_32 x = 0; x < width; x++){
          auto i =  y * bmpStride + x * bmpBpp;
          auto paletteIndex = row[x * PNG_BPP]; // PNG_BPP Should be 1 probably.
          auto color = palette[paletteIndex];

          p[i + faint::iR] = color.red;
          p[i + faint::iG] = color.green;
          p[i + faint::iB] = color.blue;
          p[i + faint::iA] = 255;
        }
      }
      free(palette);
    }

    free(rows);
    return {Bitmap_and_tEXt(std::move(bmp), std::move(textChunks))};
  }
  catch (const BitmapException& e){
    free(rows);
    return {e.what()};
  }
}

OrError<Bitmap> read_png(const FilePath& p){
  return read_png_meta(p).Visit(
    [](const Bitmap_and_tEXt& result){
      return OrError<Bitmap>(result.bmp);
    },
    [](const utf8_string& error){
      return OrError<Bitmap>(error);
    });
}

static utf8_string to_string(PngWriteResult result, const FilePath& p){
  using R = PngWriteResult;

  auto failed_write = [](const utf8_string& s){
    return endline_sep("Failed saving png.\n", s);
  };

  auto failed_write_libpng = [&](const utf8_string& func){
    return failed_write(space_sep("libpng", quoted(func), "exited with error."));
  };

  if (result == R::OK){
    return "No error";
  }
  else if (result == R::ERROR_OPEN_FILE){
    return failed_write(endline_sep("File could not be opened for writing.",
      space_sep("File:", p.Str())));
  }
  else if (result == R::ERROR_CREATE_WRITE_STRUCT){
    return failed_write_libpng("png_create_write_struct");
  }
  else if (result == R::ERROR_INIT_IO){
    return failed_write_libpng("png_init_io");
  }
  else if (result == R::ERROR_WRITE_HEADER){
    return failed_write_libpng("png_write_info");
  }
  else if (result == R::ERROR_WRITE_DATA){
    return failed_write_libpng("png_write_image");
  }
  else if (result == R::ERROR_WRITE_END){
    return failed_write_libpng("png_write_end");
  }
  else if (result == R::ERROR_WRITE_TEXT_KEY_ENCODING){
    return failed_write(endline_sep("A specified tEXt-chunk key was not ascii.",
      "Faint only supports ascii tEXt-chunks."));
  }
  else if (result == R::ERROR_WRITE_TEXT_KEY_EMPTY){
    return failed_write("An empty key was specified for a tEXt-chunk.");
  }
  else if (result == R::ERROR_WRITE_TEXT_KEY_TOO_LONG){
    return failed_write("Keys for tEXt-chunks may be at most " +
      str_int(PNG_KEYWORD_MAX_LENGTH) + "-characters");
  }
  else if (result == R::ERROR_WRITE_TEXT_VALUE_TOO_LONG){
    return failed_write("A value for a tEXt-chunks exceeded capacity of "
      "png_size_t.");
  }
  else{
    return failed_write("For reasons unknown.");
  }
}

SaveResult write_png(const FilePath& path,
  const Bitmap& bmp,
  PngColorType colorType,
  const png_tEXt_map& textChunks)
{
  PngWriteResult result = write_with_libpng(path.Str().c_str(), bmp,
    to_png_color_type(colorType),
    textChunks);

  return result == PngWriteResult::OK ?
    SaveResult::SaveSuccessful() :
    SaveResult::SaveFailed(to_string(result, path));
}

SaveResult write_png(const FilePath& path,
  const Bitmap& bmp,
  PngColorType colorType)
{
  png_tEXt_map noChunks;
  return write_png(path, bmp, colorType, noChunks);
}

const utf8_string get_libpng_version(){
  return utf8_string(PNG_LIBPNG_VER_STRING);
}

} // namespace
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2015-2018 Skymind, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License, Version 2.0 which is available at
 * https://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 ******************************************************************************/

//
// Created by raver119 on 30.11.17.
//

#include <execution/LaunchContext.h>
#include <logger.h>
#include <exceptions/cuda_exception.h>
#include <thread>

thread_local nd4j::ContextBuffers contextBuffers = nd4j::ContextBuffers();

namespace nd4j {

    LaunchContext::~LaunchContext() {

    }

    std::vector<std::shared_ptr<LaunchContext>> LaunchContext::_contexts = std::vector<std::shared_ptr<LaunchContext>>();

////////////////////////////////////////////////////////////////////////
    LaunchContext::LaunchContext() {
        // default constructor, just to make clang/ranlib happy
        _workspace = nullptr;
        _deviceID = 0;
    }

    LaunchContext::LaunchContext(Nd4jPointer cudaStream, Nd4jPointer reductionPointer, Nd4jPointer scalarPointer, Nd4jPointer allocationPointer) {

    }

    LaunchContext* LaunchContext::defaultContext() {
        // TODO: we need it to be device-aware, but only once we add NUMA support for cpu
        if (LaunchContext::_contexts.empty()) {
           LaunchContext::_contexts.emplace_back(std::make_shared<LaunchContext>());
        }

        // return context for current device
        return LaunchContext::_contexts[0].get();
    }
}<commit_msg>no thread_local for cpu<commit_after>/*******************************************************************************
 * Copyright (c) 2015-2018 Skymind, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License, Version 2.0 which is available at
 * https://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 ******************************************************************************/

//
// Created by raver119 on 30.11.17.
//

#include <execution/LaunchContext.h>
#include <logger.h>
#include <exceptions/cuda_exception.h>
#include <thread>

nd4j::ContextBuffers contextBuffers = nd4j::ContextBuffers();

namespace nd4j {

    LaunchContext::~LaunchContext() {

    }

    std::vector<std::shared_ptr<LaunchContext>> LaunchContext::_contexts = std::vector<std::shared_ptr<LaunchContext>>();

////////////////////////////////////////////////////////////////////////
    LaunchContext::LaunchContext() {
        // default constructor, just to make clang/ranlib happy
        _workspace = nullptr;
        _deviceID = 0;
    }

    LaunchContext::LaunchContext(Nd4jPointer cudaStream, Nd4jPointer reductionPointer, Nd4jPointer scalarPointer, Nd4jPointer allocationPointer) {

    }

    LaunchContext* LaunchContext::defaultContext() {
        // TODO: we need it to be device-aware, but only once we add NUMA support for cpu
        if (LaunchContext::_contexts.empty()) {
           LaunchContext::_contexts.emplace_back(std::make_shared<LaunchContext>());
        }

        // return context for current device
        return LaunchContext::_contexts[0].get();
    }
}<|endoftext|>


<commit_before>// MIT License

// Copyright (c) 2017 Zhuhao Wang

// 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 <cassert>

#include "nekit/transport/tcp_socket.h"
#include "nekit/utils/auto.h"
#include "nekit/utils/boost_error.h"
#include "nekit/utils/error.h"
#include "nekit/utils/log.h"

#undef NECHANNEL
#define NECHANNEL "TCP Socket"

namespace nekit {
namespace transport {

TcpSocket::TcpSocket(boost::asio::ip::tcp::socket &&socket)
    : ConnectionInterface{socket.get_io_service()},
      socket_{std::move(socket)} {}

utils::Cancelable &TcpSocket::Read(std::unique_ptr<utils::Buffer> &&buffer,
                                   TransportInterface::EventHandler handler) {
  NETRACE << "Start reading data.";

  read_cancelable_ = utils::Cancelable();

  if (read_closed_) {
    NEERROR << "Socket reading is already closed. Do nothing.";
    return read_cancelable_;
  }

  socket_.async_read_some(
      boost::asio::mutable_buffers_1(buffer->buffer(), buffer->size()),
      [
        this, buffer{std::move(buffer)}, handler, cancelable{read_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {

        if (cancelable.canceled() || lifetime->canceled() || IsReadClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          if (error == ErrorCode::EndOfFile) {
            this->read_closed_ = true;
            NEDEBUG << "Socket got EOF.";
          } else {
            NEERROR << "Reading from socket failed due to " << error << ".";
          }

          handler(std::move(buffer), error);
          return;
        }

        NETRACE << "Successfully read " << bytes_transferred
                << " bytes from socket.";
        buffer->ReserveBack(buffer->size() - bytes_transferred);
        handler(std::move(buffer), ErrorCode::NoError);
        return;
      });
  return read_cancelable_;
}

utils::Cancelable &TcpSocket::Write(std::unique_ptr<utils::Buffer> &&buffer,
                                    TransportInterface::EventHandler handler) {
  NETRACE << "Start writing data.";

  write_cancelable_ = utils::Cancelable();

  if (write_closed_) {
    NEERROR << "Socket write is already closed. Do nothing.";
    return write_cancelable_;
  }

  boost::asio::async_write(
      socket_, boost::asio::const_buffers_1(buffer->buffer(), buffer->size()),
      [
        this, buffer{std::move(buffer)}, handler, cancelable{write_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {

        if (cancelable.canceled() || lifetime->canceled() || IsWriteClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);
          NEERROR << "Write to socket failed due to " << error << ".";

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          handler(std::move(buffer), error);
          return;
        }

        assert(bytes_transferred == buffer->size());

        NETRACE << "Successfully write " << bytes_transferred
                << " bytes to socket.";
        handler(std::move(buffer), ErrorCode::NoError);
        return;
      });

  return write_cancelable_;
}

utils::Cancelable &TcpSocket::PollRead(
    TransportInterface::PollEventHandler handler) {
  NETRACE << "Start polling for reading.";

  read_cancelable_ = utils::Cancelable();

  if (read_closed_) {
    NEERROR << "Socket reading is already closed. Do nothing.";
    return read_cancelable_;
  }

  socket_.async_read_some(
      boost::asio::null_buffers{},
      [
        this, handler, cancelable{read_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {
        (void)bytes_transferred;

        if (cancelable.canceled() || lifetime->canceled() || IsReadClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          if (error == ErrorCode::EndOfFile) {
            this->read_closed_ = true;
            NEDEBUG << "Socket got EOF.";
          } else {
            NEERROR << "Polling read event failed due to " << error << ".";
          }

          handler(error);
          return;
        }

        boost::system::error_code error;
        boost::asio::socket_base::bytes_readable command(true);
        socket_.io_control(command, error);
        if (error) {
          handler(ConvertBoostError(error));
          return;
        }
        if (!command.get()) {
          read_closed_ = true;
          NEDEBUG << "Socket got EOF.";
          handler(ErrorCode::EndOfFile);
          return;
        }

        NETRACE << "Socket becomes readable.";
        handler(ErrorCode::NoError);
        return;
      });
  return read_cancelable_;
}

utils::Cancelable &TcpSocket::PollWrite(
    TransportInterface::PollEventHandler handler) {
  NETRACE << "Start polling for writing.";

  write_cancelable_ = utils::Cancelable();

  if (write_closed_) {
    NEERROR << "Socket write is already closed. Do nothing.";
    return write_cancelable_;
  }

  socket_.async_write_some(
      boost::asio::null_buffers{},
      [
        this, handler, cancelable{write_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {
        (void)bytes_transferred;

        if (cancelable.canceled() || lifetime->canceled() || IsWriteClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);
          NEERROR << "Polling write event failed due to " << error << ".";

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          handler(error);
          return;
        }

        NETRACE << "Socket becomes writable.";
        handler(ErrorCode::NoError);
        return;
      });

  return write_cancelable_;
}

void TcpSocket::CloseRead() {
  NEDEBUG << "Closing socket reading.";
  if (read_closed_) {
    NEDEBUG << "Socket reading is already closed, nothing happened.";
    return;
  }

  boost::system::error_code ec;
  socket_.shutdown(socket_.shutdown_receive, ec);
  // It is not likely there will be any error other than those related to SSL.
  // But SSL is never used in TcpSocket.
  if (ec && ec != boost::asio::error::not_connected) {
    NEERROR << "Failed to close socket reading due to " << ec << ".";
    assert(!ec);
  }

  read_closed_ = true;
  NEDEBUG << "Socket reading closed.";
}

void TcpSocket::CloseWrite() {
  NEDEBUG << "Closing socket writing.";
  if (write_closed_) {
    NEDEBUG << "Socket writing is already closed, nothing happened.";
    return;
  }

  boost::system::error_code ec;
  socket_.shutdown(socket_.shutdown_send, ec);
  if (ec && ec != boost::asio::error::not_connected) {
    NEERROR << "Failed to close socket writing due to " << ec << ".";
    assert(!ec);
  }

  write_closed_ = true;
  NEDEBUG << "Socket writing closed.";
}

void TcpSocket::Close() {
  NEDEBUG << "Closing socket.";
  CloseRead();
  CloseWrite();
}

bool TcpSocket::IsReadClosed() const { return read_closed_; }

bool TcpSocket::IsWriteClosed() const { return write_closed_; }

bool TcpSocket::IsClosed() const { return IsReadClosed() && IsWriteClosed(); }

boost::asio::ip::tcp::endpoint TcpSocket::localEndpoint() const {
  boost::system::error_code ec;
  boost::asio::ip::tcp::endpoint endpoint = socket_.local_endpoint(ec);
  assert(!ec);
  return endpoint;
}

boost::asio::ip::tcp::endpoint TcpSocket::remoteEndpoint() const {
  boost::system::error_code ec;
  boost::asio::ip::tcp::endpoint endpoint = socket_.remote_endpoint(ec);
  assert(!ec);
  return endpoint;
}

std::error_code TcpSocket::ConvertBoostError(
    const boost::system::error_code &ec) const {
  if (ec.category() == boost::asio::error::system_category) {
    switch (ec.value()) {
      case boost::asio::error::basic_errors::operation_aborted:
        return nekit::utils::NEKitErrorCode::Canceled;
      case boost::asio::error::basic_errors::connection_aborted:
        return ErrorCode::ConnectionAborted;
      case boost::asio::error::basic_errors::connection_reset:
        return ErrorCode::ConnectionReset;
      case boost::asio::error::basic_errors::host_unreachable:
        return ErrorCode::HostUnreachable;
      case boost::asio::error::basic_errors::network_down:
        return ErrorCode::NetworkDown;
      case boost::asio::error::basic_errors::network_reset:
        return ErrorCode::NetworkReset;
      case boost::asio::error::basic_errors::network_unreachable:
        return ErrorCode::NetworkUnreachable;
      case boost::asio::error::basic_errors::timed_out:
        return ErrorCode::TimedOut;
    }
  } else if (ec.category() == boost::asio::error::misc_category) {
    if (ec.value() == boost::asio::error::misc_errors::eof) {
      return ErrorCode::EndOfFile;
    }
  }

  // Semantically we should return UnknownError, but ideally, UnknownError
  // should never occur, we should treat every error carefully, and this
  // provides us the necessary information to handle the origin error.
  return std::make_error_code(ec);
}
}  // namespace transport
}  // namespace nekit
<commit_msg>FIX: Do not handle socket close error<commit_after>// MIT License

// Copyright (c) 2017 Zhuhao Wang

// 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 <cassert>

#include "nekit/transport/tcp_socket.h"
#include "nekit/utils/auto.h"
#include "nekit/utils/boost_error.h"
#include "nekit/utils/error.h"
#include "nekit/utils/log.h"

#undef NECHANNEL
#define NECHANNEL "TCP Socket"

namespace nekit {
namespace transport {

TcpSocket::TcpSocket(boost::asio::ip::tcp::socket &&socket)
    : ConnectionInterface{socket.get_io_service()},
      socket_{std::move(socket)} {}

utils::Cancelable &TcpSocket::Read(std::unique_ptr<utils::Buffer> &&buffer,
                                   TransportInterface::EventHandler handler) {
  NETRACE << "Start reading data.";

  read_cancelable_ = utils::Cancelable();

  if (read_closed_) {
    NEERROR << "Socket reading is already closed. Do nothing.";
    return read_cancelable_;
  }

  socket_.async_read_some(
      boost::asio::mutable_buffers_1(buffer->buffer(), buffer->size()),
      [
        this, buffer{std::move(buffer)}, handler, cancelable{read_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {

        if (cancelable.canceled() || lifetime->canceled() || IsReadClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          if (error == ErrorCode::EndOfFile) {
            this->read_closed_ = true;
            NEDEBUG << "Socket got EOF.";
          } else {
            NEERROR << "Reading from socket failed due to " << error << ".";
          }

          handler(std::move(buffer), error);
          return;
        }

        NETRACE << "Successfully read " << bytes_transferred
                << " bytes from socket.";
        buffer->ReserveBack(buffer->size() - bytes_transferred);
        handler(std::move(buffer), ErrorCode::NoError);
        return;
      });
  return read_cancelable_;
}

utils::Cancelable &TcpSocket::Write(std::unique_ptr<utils::Buffer> &&buffer,
                                    TransportInterface::EventHandler handler) {
  NETRACE << "Start writing data.";

  write_cancelable_ = utils::Cancelable();

  if (write_closed_) {
    NEERROR << "Socket write is already closed. Do nothing.";
    return write_cancelable_;
  }

  boost::asio::async_write(
      socket_, boost::asio::const_buffers_1(buffer->buffer(), buffer->size()),
      [
        this, buffer{std::move(buffer)}, handler, cancelable{write_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {

        if (cancelable.canceled() || lifetime->canceled() || IsWriteClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);
          NEERROR << "Write to socket failed due to " << error << ".";

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          handler(std::move(buffer), error);
          return;
        }

        assert(bytes_transferred == buffer->size());

        NETRACE << "Successfully write " << bytes_transferred
                << " bytes to socket.";
        handler(std::move(buffer), ErrorCode::NoError);
        return;
      });

  return write_cancelable_;
}

utils::Cancelable &TcpSocket::PollRead(
    TransportInterface::PollEventHandler handler) {
  NETRACE << "Start polling for reading.";

  read_cancelable_ = utils::Cancelable();

  if (read_closed_) {
    NEERROR << "Socket reading is already closed. Do nothing.";
    return read_cancelable_;
  }

  socket_.async_read_some(
      boost::asio::null_buffers{},
      [
        this, handler, cancelable{read_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {
        (void)bytes_transferred;

        if (cancelable.canceled() || lifetime->canceled() || IsReadClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          if (error == ErrorCode::EndOfFile) {
            this->read_closed_ = true;
            NEDEBUG << "Socket got EOF.";
          } else {
            NEERROR << "Polling read event failed due to " << error << ".";
          }

          handler(error);
          return;
        }

        boost::system::error_code error;
        boost::asio::socket_base::bytes_readable command(true);
        socket_.io_control(command, error);
        if (error) {
          handler(ConvertBoostError(error));
          return;
        }
        if (!command.get()) {
          read_closed_ = true;
          NEDEBUG << "Socket got EOF.";
          handler(ErrorCode::EndOfFile);
          return;
        }

        NETRACE << "Socket becomes readable.";
        handler(ErrorCode::NoError);
        return;
      });
  return read_cancelable_;
}

utils::Cancelable &TcpSocket::PollWrite(
    TransportInterface::PollEventHandler handler) {
  NETRACE << "Start polling for writing.";

  write_cancelable_ = utils::Cancelable();

  if (write_closed_) {
    NEERROR << "Socket write is already closed. Do nothing.";
    return write_cancelable_;
  }

  socket_.async_write_some(
      boost::asio::null_buffers{},
      [
        this, handler, cancelable{write_cancelable_},
        lifetime{life_time_cancelable_pointer()}
      ](const boost::system::error_code &ec,
        std::size_t bytes_transferred) mutable {
        (void)bytes_transferred;

        if (cancelable.canceled() || lifetime->canceled() || IsWriteClosed()) {
          return;
        }

        if (ec) {
          auto error = ConvertBoostError(ec);
          NEERROR << "Polling write event failed due to " << error << ".";

          if (error == utils::NEKitErrorCode::Canceled) {
            return;
          }

          handler(error);
          return;
        }

        NETRACE << "Socket becomes writable.";
        handler(ErrorCode::NoError);
        return;
      });

  return write_cancelable_;
}

void TcpSocket::CloseRead() {
  NEDEBUG << "Closing socket reading.";
  if (read_closed_) {
    NEDEBUG << "Socket reading is already closed, nothing happened.";
    return;
  }

  boost::system::error_code ec;
  socket_.shutdown(socket_.shutdown_receive, ec);
  // It is not likely there will be any error other than those related to SSL.
  // But SSL is never used in TcpSocket.
  if (ec && ec != boost::asio::error::not_connected) {
    NEERROR << "Failed to close socket reading due to " << ec << ".";
  }

  read_closed_ = true;
  NEDEBUG << "Socket reading closed.";
}

void TcpSocket::CloseWrite() {
  NEDEBUG << "Closing socket writing.";
  if (write_closed_) {
    NEDEBUG << "Socket writing is already closed, nothing happened.";
    return;
  }

  boost::system::error_code ec;
  socket_.shutdown(socket_.shutdown_send, ec);
  if (ec && ec != boost::asio::error::not_connected) {
    NEERROR << "Failed to close socket writing due to " << ec << ".";
  }

  write_closed_ = true;
  NEDEBUG << "Socket writing closed.";
}

void TcpSocket::Close() {
  NEDEBUG << "Closing socket.";
  CloseRead();
  CloseWrite();
}

bool TcpSocket::IsReadClosed() const { return read_closed_; }

bool TcpSocket::IsWriteClosed() const { return write_closed_; }

bool TcpSocket::IsClosed() const { return IsReadClosed() && IsWriteClosed(); }

boost::asio::ip::tcp::endpoint TcpSocket::localEndpoint() const {
  boost::system::error_code ec;
  boost::asio::ip::tcp::endpoint endpoint = socket_.local_endpoint(ec);
  assert(!ec);
  return endpoint;
}

boost::asio::ip::tcp::endpoint TcpSocket::remoteEndpoint() const {
  boost::system::error_code ec;
  boost::asio::ip::tcp::endpoint endpoint = socket_.remote_endpoint(ec);
  assert(!ec);
  return endpoint;
}

std::error_code TcpSocket::ConvertBoostError(
    const boost::system::error_code &ec) const {
  if (ec.category() == boost::asio::error::system_category) {
    switch (ec.value()) {
      case boost::asio::error::basic_errors::operation_aborted:
        return nekit::utils::NEKitErrorCode::Canceled;
      case boost::asio::error::basic_errors::connection_aborted:
        return ErrorCode::ConnectionAborted;
      case boost::asio::error::basic_errors::connection_reset:
        return ErrorCode::ConnectionReset;
      case boost::asio::error::basic_errors::host_unreachable:
        return ErrorCode::HostUnreachable;
      case boost::asio::error::basic_errors::network_down:
        return ErrorCode::NetworkDown;
      case boost::asio::error::basic_errors::network_reset:
        return ErrorCode::NetworkReset;
      case boost::asio::error::basic_errors::network_unreachable:
        return ErrorCode::NetworkUnreachable;
      case boost::asio::error::basic_errors::timed_out:
        return ErrorCode::TimedOut;
    }
  } else if (ec.category() == boost::asio::error::misc_category) {
    if (ec.value() == boost::asio::error::misc_errors::eof) {
      return ErrorCode::EndOfFile;
    }
  }

  // Semantically we should return UnknownError, but ideally, UnknownError
  // should never occur, we should treat every error carefully, and this
  // provides us the necessary information to handle the origin error.
  return std::make_error_code(ec);
}
}  // namespace transport
}  // namespace nekit
<|endoftext|>