<commit_before>#include "AnalysisSolver.h"

#include <sofa/core/ObjectFactory.h>

#include <Eigen/SVD>
#include <Eigen/Eigenvalues>

namespace sofa {
namespace component {
namespace linearsolver {

SOFA_DECL_CLASS(AnalysisSolver)
int AnalysisSolverClass = core::RegisterObject("Analysis solver: runs other KKTSolvers successively on a given problem and performs extra analysis on KKT system").add< AnalysisSolver >();

AnalysisSolver::AnalysisSolver()
    : condest(initData(&condest, false, "condest", "compute condition number with svd"))
    , eigenvaluesign(initData(&eigenvaluesign, false, "eigenvaluesign", "computing the sign of the eigenvalues (of the implicit matrix H)"))
    , dump_qp(initData(&dump_qp, "dump_qp", "dump qp to file if non-empty"))

{}

void AnalysisSolver::init() {

	solvers.clear();
	this->getContext()->get<KKTSolver>( &solvers, core::objectmodel::BaseContext::Local );

	if( solvers.size() < 2 ) {
		std::cerr << "warning: no other kkt solvers found" << std::endl;
	} else {
		std::cout << "AnalysisSolver: dynamics/correction will use "
				  << solvers.back()->getName()
				  << std::endl;
	}
}

void AnalysisSolver::factor(const system_type& system) {

	// start at 1 since 0 is current solver
    for( unsigned i = 1, n = solvers.size() ; i < n; ++i ) {
		solvers[i]->factor(system);
	}

    typedef system_type::dmat dmat;

    if( condest.getValue() ) {

        dmat kkt;

        kkt.setZero(system.size(), system.size());

        kkt <<
            dmat(system.H), dmat(-system.J.transpose()),
            dmat(-system.J), dmat(-system.C);

        system_type::vec eigen = kkt.jacobiSvd().singularValues();

        real min = eigen.tail<1>()(0);
        real max = eigen(0);

        if( min < std::numeric_limits<real>::epsilon() ) std::cout << "AnalysisSolver: singular KKT system"<<std::endl;
        else
        {
            const real cond = max/min;
            std::cout << "condition number (KKT system): " << cond << " ("<<max<<"/"<<min<<")"<<std::endl;
            std::cout << "required precision (KKT system):  "<<ceil(log(cond))<<" bits"<<std::endl;
        }

        eigen = dmat(system.H).jacobiSvd().singularValues();

        min = eigen.tail<1>()(0);
        max = eigen(0);

        if( min < std::numeric_limits<real>::epsilon() ) std::cout << "AnalysisSolver: singular implicit system"<<std::endl;
        else
        {
            const real cond = max/min;
            std::cout << "condition number (implicit system): " << cond << " ("<<max<<"/"<<min<<")"<<std::endl;
            std::cout << "required precision (implicit system):  "<<ceil(log(cond))<<" bits"<<std::endl;
        }
    }

     if( eigenvaluesign.getValue() ) {

        Eigen::EigenSolver<dmat> es( dmat(system.H) );
//        Eigen::MatrixXcd D = es.eigenvalues().asDiagonal();
        unsigned positive = 0, negative = 0;
        for( dmat::Index i =0 ; i< es.eigenvalues().rows() ; ++i )
            if( es.eigenvalues()[i].real() < 0 ) negative++;
            else positive++;

        std::cout << "eigenvalues H: neg="<<negative<<" pos="<<positive<<std::endl;
        if( negative )
        {
            getContext()->getRootContext()->setAnimate(false);

            std::cerr<<es.eigenvalues().array().abs().minCoeff()<<std::endl;
            std::cerr<<" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n";
        }

    }

    // TODO add more as needed
}

static void write_qp(std::ofstream& out,
                     const AssembledSystem& sys,
                     const AssembledSystem::vec& rhs) {

    const char endl = '\n';

    out << sys.m << ' ' << sys.n << endl;

    out << sys.H << endl;
    out << -rhs.head(sys.m).transpose() << endl;
    out << sys.P << endl;

    if( sys.n ) {
        out << sys.J << endl;
        out << rhs.tail(sys.n).transpose() << endl;

        // TODO unilateral mask !
    }

}

// solution is that of the first solver
void AnalysisSolver::correct(vec& res,
                             const system_type& sys,
                             const vec& rhs,
                             real damping) const {
	assert( solvers.size() > 1 );
	solvers.back()->correct(res, sys, rhs, damping);

    if(!dump_qp.getValue().empty() ) {
        const std::string filename = dump_qp.getValue() + ".correction";
        std::ofstream out(filename.c_str());

        write_qp(out, sys, rhs);
    }
}

// solution is that of the last solver
void AnalysisSolver::solve(vec& res,
							const system_type& sys,
							const vec& rhs) const {

    vec backup = res; // backup initial solution

	// start at 1 since 0 is current solver
    for( unsigned i = 1, n = solvers.size(); i < n; ++i ) {
		res = backup;
		solvers[i]->solve(res, sys, rhs);
	}

    if(!dump_qp.getValue().empty() ) {
        const std::string filename = dump_qp.getValue() + ".correction";
        std::ofstream out(filename.c_str());

        write_qp(out, sys, rhs);
    }

}

}
}
}
<commit_msg>[Compilant] Propagate the #include changes introduced in (CONT)<commit_after>#include "AnalysisSolver.h"
#include <fstream>
#include <sofa/core/ObjectFactory.h>

#include <Eigen/SVD>
#include <Eigen/Eigenvalues>

namespace sofa {
namespace component {
namespace linearsolver {

SOFA_DECL_CLASS(AnalysisSolver)
int AnalysisSolverClass = core::RegisterObject("Analysis solver: runs other KKTSolvers successively on a given problem and performs extra analysis on KKT system").add< AnalysisSolver >();

AnalysisSolver::AnalysisSolver()
    : condest(initData(&condest, false, "condest", "compute condition number with svd"))
    , eigenvaluesign(initData(&eigenvaluesign, false, "eigenvaluesign", "computing the sign of the eigenvalues (of the implicit matrix H)"))
    , dump_qp(initData(&dump_qp, "dump_qp", "dump qp to file if non-empty"))

{}

void AnalysisSolver::init() {

    solvers.clear();
    this->getContext()->get<KKTSolver>( &solvers, core::objectmodel::BaseContext::Local );

    if( solvers.size() < 2 ) {
        std::cerr << "warning: no other kkt solvers found" << std::endl;
    } else {
        std::cout << "AnalysisSolver: dynamics/correction will use "
                  << solvers.back()->getName()
                  << std::endl;
    }
}

void AnalysisSolver::factor(const system_type& system) {

    // start at 1 since 0 is current solver
    for( unsigned i = 1, n = solvers.size() ; i < n; ++i ) {
        solvers[i]->factor(system);
    }

    typedef system_type::dmat dmat;

    if( condest.getValue() ) {

        dmat kkt;

        kkt.setZero(system.size(), system.size());

        kkt <<
            dmat(system.H), dmat(-system.J.transpose()),
            dmat(-system.J), dmat(-system.C);

        system_type::vec eigen = kkt.jacobiSvd().singularValues();

        real min = eigen.tail<1>()(0);
        real max = eigen(0);

        if( min < std::numeric_limits<real>::epsilon() ) std::cout << "AnalysisSolver: singular KKT system"<<std::endl;
        else
        {
            const real cond = max/min;
            std::cout << "condition number (KKT system): " << cond << " ("<<max<<"/"<<min<<")"<<std::endl;
            std::cout << "required precision (KKT system):  "<<ceil(log(cond))<<" bits"<<std::endl;
        }

        eigen = dmat(system.H).jacobiSvd().singularValues();

        min = eigen.tail<1>()(0);
        max = eigen(0);

        if( min < std::numeric_limits<real>::epsilon() ) std::cout << "AnalysisSolver: singular implicit system"<<std::endl;
        else
        {
            const real cond = max/min;
            std::cout << "condition number (implicit system): " << cond << " ("<<max<<"/"<<min<<")"<<std::endl;
            std::cout << "required precision (implicit system):  "<<ceil(log(cond))<<" bits"<<std::endl;
        }
    }

     if( eigenvaluesign.getValue() ) {

        Eigen::EigenSolver<dmat> es( dmat(system.H) );
//        Eigen::MatrixXcd D = es.eigenvalues().asDiagonal();
        unsigned positive = 0, negative = 0;
        for( dmat::Index i =0 ; i< es.eigenvalues().rows() ; ++i )
            if( es.eigenvalues()[i].real() < 0 ) negative++;
            else positive++;

        std::cout << "eigenvalues H: neg="<<negative<<" pos="<<positive<<std::endl;
        if( negative )
        {
            getContext()->getRootContext()->setAnimate(false);

            std::cerr<<es.eigenvalues().array().abs().minCoeff()<<std::endl;
            std::cerr<<" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n";
        }

    }

    // TODO add more as needed
}

static void write_qp(std::ofstream& out,
                     const AssembledSystem& sys,
                     const AssembledSystem::vec& rhs) {

    const char endl = '\n';

    out << sys.m << ' ' << sys.n << endl;

    out << sys.H << endl;
    out << -rhs.head(sys.m).transpose() << endl;
    out << sys.P << endl;

    if( sys.n ) {
        out << sys.J << endl;
        out << rhs.tail(sys.n).transpose() << endl;

        // TODO unilateral mask !
    }

}

// solution is that of the first solver
void AnalysisSolver::correct(vec& res,
                             const system_type& sys,
                             const vec& rhs,
                             real damping) const {
    assert( solvers.size() > 1 );
    solvers.back()->correct(res, sys, rhs, damping);

    if(!dump_qp.getValue().empty() ) {
        const std::string filename = dump_qp.getValue() + ".correction";
        std::ofstream out(filename.c_str());

        write_qp(out, sys, rhs);
    }
}

// solution is that of the last solver
void AnalysisSolver::solve(vec& res,
                            const system_type& sys,
                            const vec& rhs) const {

    vec backup = res; // backup initial solution

    // start at 1 since 0 is current solver
    for( unsigned i = 1, n = solvers.size(); i < n; ++i ) {
        res = backup;
        solvers[i]->solve(res, sys, rhs);
    }

    if(!dump_qp.getValue().empty() ) {
        const std::string filename = dump_qp.getValue() + ".correction";
        std::ofstream out(filename.c_str());

        write_qp(out, sys, rhs);
    }

}

}
}
}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <chrono>
#include <thread>
#include <unistd.h>
#include <vector>

#include "acmacs-base/filesystem.hh"
#include "acmacs-base/quicklook.hh"
#include "acmacs-base/log.hh"

// ----------------------------------------------------------------------

#ifdef __APPLE__

template <typename T> static inline std::string command_with_path(T&& cmd)
{
    return fmt::format("{}/bin/{}", std::getenv("ACMACSD_ROOT"), std::forward<T>(cmd));
}

void acmacs::quicklook(std::string_view aFilename, size_t aDelayInSeconds, std::optional<size_t> aRemoveAfterDelay)
{
    if (aRemoveAfterDelay.has_value())
        run_and_detach(command_with_path("open-with-delay"), "-q", "-a", aDelayInSeconds, "-r", *aRemoveAfterDelay, aFilename);
    else
        run_and_detach(command_with_path("open-with-delay"), "-q", "-a", aDelayInSeconds, aFilename);

} // acmacs::quicklook

// ----------------------------------------------------------------------

void acmacs::open(std::string_view aFilename, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds, std::optional<size_t> aRemoveAfterDelay)
{
    if (aRemoveAfterDelay.has_value())
        run_and_detach(command_with_path("open-with-delay"), "-e", "-b", aDelayBeforeInSeconds, "-a", aDelayAfterInSeconds, "-r", *aRemoveAfterDelay, aFilename);
    else
        run_and_detach(command_with_path("open-with-delay"), "-e", "-b", aDelayBeforeInSeconds, "-a", aDelayAfterInSeconds, aFilename);

} // acmacs::quicklook

// ----------------------------------------------------------------------

void acmacs::preview(std::string_view aFilename, std::string_view position, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds)
{
    run_and_detach(command_with_path("preview"), "-p", position, "-e", "-b", aDelayBeforeInSeconds, "-a", aDelayAfterInSeconds, aFilename);

} // acmacs::preview

// ----------------------------------------------------------------------

// inline bool return_to_emacs()
// {
//     if (const auto* xpc = std::getenv("XPC_SERVICE_NAME"), *inside = std::getenv("INSIDE_EMACS"); (xpc && std::string_view{xpc}.find("Emacs") != std::string_view::npos) || inside)
//         return true;
//     else
//         return false;
// }

// // ----------------------------------------------------------------------

// void acmacs::quicklook(std::string_view aFilename, size_t aDelayInSeconds, std::optional<size_t> aRemoveAfterDelay)
// {
//     run_and_detach_with_delay({"/usr/bin/qlmanage", "-p", aFilename.data()}, 0);
//     if (aDelayInSeconds) {
//         using namespace std::chrono_literals;
//         std::this_thread::sleep_for(1s * aDelayInSeconds);
//     }

// } // acmacs::quicklook

// // ----------------------------------------------------------------------

// void acmacs::open(std::string_view aFilename, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds, std::optional<size_t> aRemoveAfterDelay)
// {
//     using namespace std::chrono_literals;

//     if (aDelayBeforeInSeconds)
//         run_and_detach_with_delay({"/usr/bin/open", aFilename.data()}, aDelayBeforeInSeconds); // , "-g"
//     else
//         std::system(fmt::format("/usr/bin/open '{}'", aFilename).data());

//     if (return_to_emacs())
//         run_and_detach_with_delay({"/usr/bin/open", "-a", "/Applications/Emacs.app"}, aDelayBeforeInSeconds + 1);

//     if (aDelayAfterInSeconds)
//         std::this_thread::sleep_for(1s * aDelayAfterInSeconds);

// } // acmacs::quicklook

// ----------------------------------------------------------------------

// void acmacs::preview(std::string_view aFilename, std::string_view position, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds)
// {
//     using namespace std::chrono_literals;

//     if (const fs::path preview_path{fmt::format("{}/bin/preview", std::getenv("HOME"))}; fs::exists(preview_path)) {

//         if (aDelayBeforeInSeconds)
//             run_and_detach_with_delay({preview_path.c_str(), "-p", position.data(), aFilename.data()}, aDelayBeforeInSeconds); // , "-g"
//         else
//             std::system(fmt::format("{} -p {} '{}'", preview_path, position, aFilename).data());

//         if (return_to_emacs())
//             run_and_detach_with_delay({"/usr/bin/open", "-a", "/Applications/Emacs.app"}, aDelayBeforeInSeconds + 1);

//         if (aDelayAfterInSeconds)
//             std::this_thread::sleep_for(1s * aDelayAfterInSeconds);
//     }
//     else
//         open(aFilename, aDelayBeforeInSeconds, aDelayAfterInSeconds);

// } // acmacs::preview

// ======================================================================

#else

void acmacs::quicklook(std::string_view /*aFilename*/, size_t /*aDelayInSeconds*/)
{
}

void acmacs::open(std::string_view /*aFilename*/, size_t /*aDelayBeforeInSeconds*/, size_t /*aDelayAfterInSeconds*/)
{
}

void acmacs::preview(std::string_view /*aFilename*/, std::string_view /*position*/, size_t /*aDelayBeforeInSeconds*/, size_t /*aDelayAfterInSeconds*/)
{
}

#endif

// ======================================================================

void acmacs::run_and_detach_with_delay(const std::vector<std::string>& argv, size_t aDelayBeforeInSeconds)
{
    if (!fork()) {
        close(0);
        // close(1);
        // close(2);
        setsid();
        if (aDelayBeforeInSeconds) {
            using namespace std::chrono_literals;
            std::this_thread::sleep_for(1s * aDelayBeforeInSeconds);
        }
        std::vector<const char *> argv_v(argv.size() + 1, nullptr);
        std::transform(std::begin(argv), std::end(argv), std::begin(argv_v), [](const auto& aa) { return aa.data(); });
        execvp(argv_v[0], const_cast<char *const *>(argv_v.data()));
        perror(argv_v[0]);
        std::exit(-1);
    }

} // acmacs::run_and_detach_with_delay

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>improvements in preview, quicklook<commit_after>#include <cstdlib>
#include <chrono>
#include <thread>
#include <unistd.h>
#include <vector>

#include "acmacs-base/filesystem.hh"
#include "acmacs-base/quicklook.hh"
#include "acmacs-base/log.hh"

// ----------------------------------------------------------------------

#ifdef __APPLE__

template <typename T> static inline std::string command_with_path(T&& cmd)
{
    return fmt::format("{}/bin/{}", std::getenv("ACMACSD_ROOT"), std::forward<T>(cmd));
}

void acmacs::quicklook(std::string_view aFilename, size_t aDelayInSeconds, std::optional<size_t> aRemoveAfterDelay)
{
    if (aRemoveAfterDelay.has_value())
        run_and_detach(command_with_path("open-with-delay"), "-q", "-a", aDelayInSeconds, "-r", *aRemoveAfterDelay, aFilename);
    else
        run_and_detach(command_with_path("open-with-delay"), "-q", "-a", aDelayInSeconds, aFilename);

} // acmacs::quicklook

// ----------------------------------------------------------------------

void acmacs::open(std::string_view aFilename, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds, std::optional<size_t> aRemoveAfterDelay)
{
    if (aRemoveAfterDelay.has_value())
        run_and_detach(command_with_path("open-with-delay"), "-e", "-b", aDelayBeforeInSeconds, "-a", aDelayAfterInSeconds, "-r", *aRemoveAfterDelay, aFilename);
    else
        run_and_detach(command_with_path("open-with-delay"), "-e", "-b", aDelayBeforeInSeconds, "-a", aDelayAfterInSeconds, aFilename);

} // acmacs::quicklook

// ----------------------------------------------------------------------

void acmacs::preview(std::string_view aFilename, std::string_view position, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds)
{
    run_and_detach(command_with_path("preview"), "-p", position, "-e", "-b", aDelayBeforeInSeconds, "-a", aDelayAfterInSeconds, aFilename);

} // acmacs::preview

// ----------------------------------------------------------------------

// inline bool return_to_emacs()
// {
//     if (const auto* xpc = std::getenv("XPC_SERVICE_NAME"), *inside = std::getenv("INSIDE_EMACS"); (xpc && std::string_view{xpc}.find("Emacs") != std::string_view::npos) || inside)
//         return true;
//     else
//         return false;
// }

// // ----------------------------------------------------------------------

// void acmacs::quicklook(std::string_view aFilename, size_t aDelayInSeconds, std::optional<size_t> aRemoveAfterDelay)
// {
//     run_and_detach_with_delay({"/usr/bin/qlmanage", "-p", aFilename.data()}, 0);
//     if (aDelayInSeconds) {
//         using namespace std::chrono_literals;
//         std::this_thread::sleep_for(1s * aDelayInSeconds);
//     }

// } // acmacs::quicklook

// // ----------------------------------------------------------------------

// void acmacs::open(std::string_view aFilename, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds, std::optional<size_t> aRemoveAfterDelay)
// {
//     using namespace std::chrono_literals;

//     if (aDelayBeforeInSeconds)
//         run_and_detach_with_delay({"/usr/bin/open", aFilename.data()}, aDelayBeforeInSeconds); // , "-g"
//     else
//         std::system(fmt::format("/usr/bin/open '{}'", aFilename).data());

//     if (return_to_emacs())
//         run_and_detach_with_delay({"/usr/bin/open", "-a", "/Applications/Emacs.app"}, aDelayBeforeInSeconds + 1);

//     if (aDelayAfterInSeconds)
//         std::this_thread::sleep_for(1s * aDelayAfterInSeconds);

// } // acmacs::quicklook

// ----------------------------------------------------------------------

// void acmacs::preview(std::string_view aFilename, std::string_view position, size_t aDelayBeforeInSeconds, size_t aDelayAfterInSeconds)
// {
//     using namespace std::chrono_literals;

//     if (const fs::path preview_path{fmt::format("{}/bin/preview", std::getenv("HOME"))}; fs::exists(preview_path)) {

//         if (aDelayBeforeInSeconds)
//             run_and_detach_with_delay({preview_path.c_str(), "-p", position.data(), aFilename.data()}, aDelayBeforeInSeconds); // , "-g"
//         else
//             std::system(fmt::format("{} -p {} '{}'", preview_path, position, aFilename).data());

//         if (return_to_emacs())
//             run_and_detach_with_delay({"/usr/bin/open", "-a", "/Applications/Emacs.app"}, aDelayBeforeInSeconds + 1);

//         if (aDelayAfterInSeconds)
//             std::this_thread::sleep_for(1s * aDelayAfterInSeconds);
//     }
//     else
//         open(aFilename, aDelayBeforeInSeconds, aDelayAfterInSeconds);

// } // acmacs::preview

// ======================================================================

#else

void acmacs::quicklook(std::string_view /*aFilename*/, size_t /*aDelayInSeconds*/, std::optional<size_t> /*aRemoveAfterDelay*/)
{
}

void acmacs::open(std::string_view /*aFilename*/, size_t /*aDelayBeforeInSeconds*/, size_t /*aDelayAfterInSeconds*/, std::optional<size_t> /*aRemoveAfterDelay*/)
{
}

void acmacs::preview(std::string_view /*aFilename*/, std::string_view /*position*/, size_t /*aDelayBeforeInSeconds*/, size_t /*aDelayAfterInSeconds*/)
{
}

#endif

// ======================================================================

void acmacs::run_and_detach_with_delay(const std::vector<std::string>& argv, size_t aDelayBeforeInSeconds)
{
    if (!fork()) {
        close(0);
        // close(1);
        // close(2);
        setsid();
        if (aDelayBeforeInSeconds) {
            using namespace std::chrono_literals;
            std::this_thread::sleep_for(1s * aDelayBeforeInSeconds);
        }
        std::vector<const char *> argv_v(argv.size() + 1, nullptr);
        std::transform(std::begin(argv), std::end(argv), std::begin(argv_v), [](const auto& aa) { return aa.data(); });
        execvp(argv_v[0], const_cast<char *const *>(argv_v.data()));
        perror(argv_v[0]);
        std::exit(-1);
    }

} // acmacs::run_and_detach_with_delay

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 PLUMgrid, Inc.
 *
 * 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 "parser.h"
#include "type_check.h"
#include "codegen_llvm.h"
#include "loader.h"

using std::string;
using std::unique_ptr;
using std::vector;

namespace ebpf {

BLoader::BLoader(unsigned flags) : flags_(flags) {
  (void)flags_;
}

BLoader::~BLoader() {
}

int BLoader::parse(llvm::Module *mod, const string &filename, const string &proto_filename,
                   TableStorage &ts, const string &id, const std::string &maps_ns) {
  int rc;

  proto_parser_ = make_unique<ebpf::cc::Parser>(proto_filename);
  rc = proto_parser_->parse();
  if (rc) {
    fprintf(stderr, "In file: %s\n", filename.c_str());
    return rc;
  }

  parser_ = make_unique<ebpf::cc::Parser>(filename);
  rc = parser_->parse();
  if (rc) {
    fprintf(stderr, "In file: %s\n", filename.c_str());
    return rc;
  }

  //ebpf::cc::Printer printer(stderr);
  //printer.visit(parser_->root_node_);

  ebpf::cc::TypeCheck type_check(parser_->scopes_.get(), proto_parser_->scopes_.get());
  auto ret = type_check.visit(parser_->root_node_);
  if (ret.code() != 0 || ret.msg().size()) {
    fprintf(stderr, "Type error @line=%d: %s\n", ret.code(), ret.msg().c_str());
    return -1;
  }

  codegen_ = ebpf::make_unique<ebpf::cc::CodegenLLVM>(mod, parser_->scopes_.get(), proto_parser_->scopes_.get());
  ret = codegen_->visit(parser_->root_node_, ts, id, maps_ns);
  if (ret.code() != 0 || ret.msg().size()) {
    fprintf(stderr, "Codegen error @line=%d: %s\n", ret.code(), ret.msg().c_str());
    return ret.code();
  }

  return 0;
}

}  // namespace ebpf
<commit_msg>include common.h for std::make_unique<commit_after>/*
 * Copyright (c) 2015 PLUMgrid, Inc.
 *
 * 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 "common.h"
#include "parser.h"
#include "type_check.h"
#include "codegen_llvm.h"
#include "loader.h"

using std::string;
using std::unique_ptr;
using std::vector;

namespace ebpf {

BLoader::BLoader(unsigned flags) : flags_(flags) {
  (void)flags_;
}

BLoader::~BLoader() {
}

int BLoader::parse(llvm::Module *mod, const string &filename, const string &proto_filename,
                   TableStorage &ts, const string &id, const std::string &maps_ns) {
  int rc;

  proto_parser_ = make_unique<ebpf::cc::Parser>(proto_filename);
  rc = proto_parser_->parse();
  if (rc) {
    fprintf(stderr, "In file: %s\n", filename.c_str());
    return rc;
  }

  parser_ = make_unique<ebpf::cc::Parser>(filename);
  rc = parser_->parse();
  if (rc) {
    fprintf(stderr, "In file: %s\n", filename.c_str());
    return rc;
  }

  //ebpf::cc::Printer printer(stderr);
  //printer.visit(parser_->root_node_);

  ebpf::cc::TypeCheck type_check(parser_->scopes_.get(), proto_parser_->scopes_.get());
  auto ret = type_check.visit(parser_->root_node_);
  if (ret.code() != 0 || ret.msg().size()) {
    fprintf(stderr, "Type error @line=%d: %s\n", ret.code(), ret.msg().c_str());
    return -1;
  }

  codegen_ = ebpf::make_unique<ebpf::cc::CodegenLLVM>(mod, parser_->scopes_.get(), proto_parser_->scopes_.get());
  ret = codegen_->visit(parser_->root_node_, ts, id, maps_ns);
  if (ret.code() != 0 || ret.msg().size()) {
    fprintf(stderr, "Codegen error @line=%d: %s\n", ret.code(), ret.msg().c_str());
    return ret.code();
  }

  return 0;
}

}  // namespace ebpf
<|endoftext|>


<commit_before>#include "Process.hpp"

#include <libslic3r/AppConfig.hpp>

#include "../GUI/GUI.hpp"
// for file_wildcards()
#include "../GUI/GUI_App.hpp"
// localization
#include "../GUI/I18N.hpp"

#include <iostream>
#include <fstream>

#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>

// For starting another PrusaSlicer instance on OSX.
// Fails to compile on Windows on the build server.
#ifdef __APPLE__
    #include <boost/process/spawn.hpp>
    #include <boost/process/args.hpp>
#endif

#include <wx/stdpaths.h>

namespace Slic3r {
namespace GUI {

enum class NewSlicerInstanceType {
	Slicer,
	GCodeViewer
};

// Start a new Slicer process instance either in a Slicer mode or in a G-code mode.
// Optionally load a 3MF, STL or a G-code on start.
static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance_type, const std::vector<wxString> paths_to_open, bool single_instance)
{
#ifdef _WIN32
	wxString path;
	wxFileName::SplitPath(wxStandardPaths::Get().GetExecutablePath(), &path, nullptr, nullptr, wxPATH_NATIVE);
	path += "\\";
	path += (instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer.exe" : "prusa-gcodeviewer.exe";
	std::vector<const wchar_t*> args;
	args.reserve(4);
	args.emplace_back(path.wc_str());
	if (!paths_to_open.empty()) {
		for (const auto& file : paths_to_open)
			args.emplace_back(file);
	}
	if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
		args.emplace_back(L"--single-instance");
	args.emplace_back(nullptr);
	BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << into_u8(path) << "\"";
	// Don't call with wxEXEC_HIDE_CONSOLE, PrusaSlicer in GUI mode would just show the splash screen. It would not open the main window though, it would
	// just hang in the background.
	if (wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC) <= 0)
		BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << into_u8(path);
#else
	// Own executable path.
	boost::filesystem::path bin_path = into_path(wxStandardPaths::Get().GetExecutablePath());
#if defined(__APPLE__)
	{
		// Maybe one day we will be able to run PrusaGCodeViewer, but for now the Apple notarization
		// process refuses Apps with multiple binaries and Vojtech does not know any workaround.
		// ((instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer");
		// Just run PrusaSlicer and give it a --gcodeviewer parameter.
		bin_path = bin_path.parent_path() / "PrusaSlicer";
		// On Apple the wxExecute fails, thus we use boost::process instead.
		BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << bin_path.string() << "\"";
		try {
			std::vector<std::string> args;
			if (instance_type == NewSlicerInstanceType::GCodeViewer)
				args.emplace_back("--gcodeviewer");
			if (!paths_to_open.empty()) {
				for (const auto& file : paths_to_open)
					args.emplace_back(into_u8(file));
			}
			if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
				args.emplace_back("--single-instance");
			boost::process::spawn(bin_path, args);
		}
		catch (const std::exception& ex) {
			BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what();
		}
	}
#else // Linux or Unix
	{
		std::vector<const char*> args;
		args.reserve(3);
#ifdef __linux
		static const char* gcodeviewer_param = "--gcodeviewer";
		{
			// If executed by an AppImage, start the AppImage, not the main process.
			// see https://docs.appimage.org/packaging-guide/environment-variables.html#id2
			const char* appimage_binary = std::getenv("APPIMAGE");
			if (appimage_binary) {
				args.emplace_back(appimage_binary);
				if (instance_type == NewSlicerInstanceType::GCodeViewer)
					args.emplace_back(gcodeviewer_param);
			}
		}
#endif // __linux
		std::string my_path;
		if (args.empty()) {
			// Binary path was not set to the AppImage in the Linux specific block above, call the application directly.
			my_path = (bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer" : "prusa-gcodeviewer")).string();
			args.emplace_back(my_path.c_str());
		}
		std::string to_open;
		if (!paths_to_open.empty()) {
			for (const auto& file : paths_to_open) {
				to_open = into_u8(file);
				args.emplace_back(to_open.c_str());
			}
		}
		if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
			args.emplace_back("--single-instance");
		args.emplace_back(nullptr);
		BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << args[0] << "\"";
		if (wxExecute(const_cast<char**>(args.data()), wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER) <= 0)
			BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << args[0];
	}
#endif // Linux or Unix
#endif // Win32
}
static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance_type, const wxString* path_to_open, bool single_instance)
{
	std::vector<wxString> paths;
	if (path_to_open != nullptr)
		paths.emplace_back(path_to_open->wc_str());
	start_new_slicer_or_gcodeviewer(instance_type, paths, single_instance);
}

void start_new_slicer(const wxString *path_to_open, bool single_instance)
{
	start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::Slicer, path_to_open, single_instance);
}
void start_new_slicer(const std::vector<wxString>& files, bool single_instance)
{
	start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::Slicer, files, single_instance);
}

void start_new_gcodeviewer(const wxString *path_to_open)
{
	start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::GCodeViewer, path_to_open, false);
}

void start_new_gcodeviewer_open_file(wxWindow *parent)
{
    wxFileDialog dialog(parent ? parent : wxGetApp().GetTopWindow(),
        _L("Open G-code file:"),
        from_u8(wxGetApp().app_config->get_last_dir()), wxString(),
        file_wildcards(FT_GCODE), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (dialog.ShowModal() == wxID_OK) {
        wxString path = dialog.GetPath();
		start_new_gcodeviewer(&path);
    }
}

} // namespace GUI
} // namespace Slic3r
<commit_msg>boost::process::spawn() sets SIGINT to SIGIGN, which collides with boost::process waiting for a child to finish! https://jmmv.dev/2008/10/boostprocess-and-sigchld.html Thus reset the SIGINT to its default, so that posix waitpid() and similar continue to work. Fixes Crash on Eject in Second Instance on macOS #5507<commit_after>#include "Process.hpp"

#include <libslic3r/AppConfig.hpp>

#include "../GUI/GUI.hpp"
// for file_wildcards()
#include "../GUI/GUI_App.hpp"
// localization
#include "../GUI/I18N.hpp"

#include <iostream>
#include <fstream>

#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>

// For starting another PrusaSlicer instance on OSX.
// Fails to compile on Windows on the build server.
#ifdef __APPLE__
	#include <signal.h>
    #include <boost/process/spawn.hpp>
    #include <boost/process/args.hpp>
#endif

#include <wx/stdpaths.h>

namespace Slic3r {
namespace GUI {

enum class NewSlicerInstanceType {
	Slicer,
	GCodeViewer
};

// Start a new Slicer process instance either in a Slicer mode or in a G-code mode.
// Optionally load a 3MF, STL or a G-code on start.
static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance_type, const std::vector<wxString> paths_to_open, bool single_instance)
{
#ifdef _WIN32
	wxString path;
	wxFileName::SplitPath(wxStandardPaths::Get().GetExecutablePath(), &path, nullptr, nullptr, wxPATH_NATIVE);
	path += "\\";
	path += (instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer.exe" : "prusa-gcodeviewer.exe";
	std::vector<const wchar_t*> args;
	args.reserve(4);
	args.emplace_back(path.wc_str());
	if (!paths_to_open.empty()) {
		for (const auto& file : paths_to_open)
			args.emplace_back(file);
	}
	if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
		args.emplace_back(L"--single-instance");
	args.emplace_back(nullptr);
	BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << into_u8(path) << "\"";
	// Don't call with wxEXEC_HIDE_CONSOLE, PrusaSlicer in GUI mode would just show the splash screen. It would not open the main window though, it would
	// just hang in the background.
	if (wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC) <= 0)
		BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << into_u8(path);
#else
	// Own executable path.
	boost::filesystem::path bin_path = into_path(wxStandardPaths::Get().GetExecutablePath());
#if defined(__APPLE__)
	{
		// Maybe one day we will be able to run PrusaGCodeViewer, but for now the Apple notarization
		// process refuses Apps with multiple binaries and Vojtech does not know any workaround.
		// ((instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer");
		// Just run PrusaSlicer and give it a --gcodeviewer parameter.
		bin_path = bin_path.parent_path() / "PrusaSlicer";
		// On Apple the wxExecute fails, thus we use boost::process instead.
		BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << bin_path.string() << "\"";
		try {
			std::vector<std::string> args;
			if (instance_type == NewSlicerInstanceType::GCodeViewer)
				args.emplace_back("--gcodeviewer");
			if (!paths_to_open.empty()) {
				for (const auto& file : paths_to_open)
					args.emplace_back(into_u8(file));
			}
			if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
				args.emplace_back("--single-instance");
			boost::process::spawn(bin_path, args);
			// boost::process::spawn() sets SIGINT to SIGIGN, which collides with boost::process waiting for a child to finish!
			// https://jmmv.dev/2008/10/boostprocess-and-sigchld.html
			// Thus reset the SIGINT to its default, so that posix waitpid() and similar continue to work.
			// Fixes Crash on Eject in Second Instance on macOS #5507
			signal(SIGINT, SIG_DFL);
		}
		catch (const std::exception& ex) {
			BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what();
		}
	}
#else // Linux or Unix
	{
		std::vector<const char*> args;
		args.reserve(3);
#ifdef __linux
		static const char* gcodeviewer_param = "--gcodeviewer";
		{
			// If executed by an AppImage, start the AppImage, not the main process.
			// see https://docs.appimage.org/packaging-guide/environment-variables.html#id2
			const char* appimage_binary = std::getenv("APPIMAGE");
			if (appimage_binary) {
				args.emplace_back(appimage_binary);
				if (instance_type == NewSlicerInstanceType::GCodeViewer)
					args.emplace_back(gcodeviewer_param);
			}
		}
#endif // __linux
		std::string my_path;
		if (args.empty()) {
			// Binary path was not set to the AppImage in the Linux specific block above, call the application directly.
			my_path = (bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer" : "prusa-gcodeviewer")).string();
			args.emplace_back(my_path.c_str());
		}
		std::string to_open;
		if (!paths_to_open.empty()) {
			for (const auto& file : paths_to_open) {
				to_open = into_u8(file);
				args.emplace_back(to_open.c_str());
			}
		}
		if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
			args.emplace_back("--single-instance");
		args.emplace_back(nullptr);
		BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << args[0] << "\"";
		if (wxExecute(const_cast<char**>(args.data()), wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER) <= 0)
			BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << args[0];
	}
#endif // Linux or Unix
#endif // Win32
}
static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance_type, const wxString* path_to_open, bool single_instance)
{
	std::vector<wxString> paths;
	if (path_to_open != nullptr)
		paths.emplace_back(path_to_open->wc_str());
	start_new_slicer_or_gcodeviewer(instance_type, paths, single_instance);
}

void start_new_slicer(const wxString *path_to_open, bool single_instance)
{
	start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::Slicer, path_to_open, single_instance);
}
void start_new_slicer(const std::vector<wxString>& files, bool single_instance)
{
	start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::Slicer, files, single_instance);
}

void start_new_gcodeviewer(const wxString *path_to_open)
{
	start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::GCodeViewer, path_to_open, false);
}

void start_new_gcodeviewer_open_file(wxWindow *parent)
{
    wxFileDialog dialog(parent ? parent : wxGetApp().GetTopWindow(),
        _L("Open G-code file:"),
        from_u8(wxGetApp().app_config->get_last_dir()), wxString(),
        file_wildcards(FT_GCODE), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (dialog.ShowModal() == wxID_OK) {
        wxString path = dialog.GetPath();
		start_new_gcodeviewer(&path);
    }
}

} // namespace GUI
} // namespace Slic3r
<|endoftext|>


<commit_before>#include "ranking.hpp"

extern int debug;

Ranking::Ranking(ACOParameters *params, vector<Ant *> &ants)
: params(params)
, ants(ants)     // copy constructor
, best_solution(NULL)
{
  no_ranking_ants = params->get_no_ranking_ants();
}

void Ranking::update() {
  sort(ants.begin(), ants.end(), Ranking::ants_comparator);

  if (debug >= 5) { cout << "Ranking> Setting best" << endl; }
  if ((best_solution == NULL) || (solutions_comparator(best_solution, ants.front()->get_solution()))) {
    best_solution = new Solution(*ants.front()->get_solution());
  }
}

void Ranking::free_memory() {
  if (debug >= 5) { cout << "Ranking> freeing solutions" << endl; }
  for (unsigned i = 0; i < no_ranking_ants; ++i) {
    if (debug >= 6) { cout << "Ranking> freeing #" << i << endl; }
    ants[i]->free_solution();
    if (debug >= 6) { cout << "Ranking> freed #" << i << endl; }
  }
  if (debug >= 5) { cout << "Ranking> freed" << endl; }
}

void Ranking::prepare_pheromones() {
  for (unsigned i = 0; i < no_ranking_ants; ++i) {
    prepare_pheromones_for_one_solution(ants[i]->get_solution(), i);
  }
}

double Ranking::calculate_additional_pheromones(Solution *solution, unsigned ranking_position) {
  return params->get_q() * (ants.size() - ranking_position) * solution->get_quality();
}

void Ranking::prepare_pheromones_for_one_solution(Solution *solution, unsigned ranking_position) {
  double additional_pheromones = calculate_additional_pheromones(solution, ranking_position);
  if (debug >= 4) { cout << "Ranking> additional pheromones for ant#" << ranking_position << ":\t" << additional_pheromones << endl; }

  vector<Edge*> edges = solution->get_edges();
  for (unsigned i = 0, len = edges.size(); i < len; ++i) {
    edges[i]->add_pheromones(additional_pheromones);
  }
}

bool Ranking::ants_comparator(Ant *a1, Ant *a2) {
  return solutions_comparator(a1->get_solution(), a2->get_solution());
}

bool Ranking::solutions_comparator(Solution *s1, Solution *s2) {
  return s1->get_quality() < s2->get_quality();
}
<commit_msg>Ranking - normalised pheromones amount<commit_after>#include "ranking.hpp"

extern int debug;

Ranking::Ranking(ACOParameters *params, vector<Ant *> &ants)
: params(params)
, ants(ants)     // copy constructor
, best_solution(NULL)
{
  no_ranking_ants = params->get_no_ranking_ants();
}

void Ranking::update() {
  sort(ants.begin(), ants.end(), Ranking::ants_comparator);

  if (debug >= 5) { cout << "Ranking> Setting best" << endl; }
  if ((best_solution == NULL) || (solutions_comparator(best_solution, ants.front()->get_solution()))) {
    best_solution = new Solution(*ants.front()->get_solution());
  }
}

void Ranking::free_memory() {
  if (debug >= 5) { cout << "Ranking> freeing solutions" << endl; }
  for (unsigned i = 0; i < no_ranking_ants; ++i) {
    if (debug >= 6) { cout << "Ranking> freeing #" << i << endl; }
    ants[i]->free_solution();
    if (debug >= 6) { cout << "Ranking> freed #" << i << endl; }
  }
  if (debug >= 5) { cout << "Ranking> freed" << endl; }
}

void Ranking::prepare_pheromones() {
  for (unsigned i = 0; i < no_ranking_ants; ++i) {
    prepare_pheromones_for_one_solution(ants[i]->get_solution(), i);
  }
}

double Ranking::calculate_additional_pheromones(Solution *solution, unsigned ranking_position) {
  double position_multiplier = ((double)(ants.size() - ranking_position)) * 2 / (ants.size() * (ants.size() + 1));
  return params->get_q() * position_multiplier * solution->get_quality();
}

void Ranking::prepare_pheromones_for_one_solution(Solution *solution, unsigned ranking_position) {
  double additional_pheromones = calculate_additional_pheromones(solution, ranking_position);
  if (debug >= 4) { cout << "Ranking> additional pheromones for ant#" << ranking_position << ":\t" << additional_pheromones << endl; }

  vector<Edge*> edges = solution->get_edges();
  for (unsigned i = 0, len = edges.size(); i < len; ++i) {
    edges[i]->add_pheromones(additional_pheromones);
  }
}

bool Ranking::ants_comparator(Ant *a1, Ant *a2) {
  return solutions_comparator(a1->get_solution(), a2->get_solution());
}

bool Ranking::solutions_comparator(Solution *s1, Solution *s2) {
  return s1->get_quality() < s2->get_quality();
}
<|endoftext|>


<commit_before>#include "server.h"

rocksdb::DB* db = NULL;
bool nosync = false;
int nprocs = 1;
uv_loop_t *loop = NULL;
bool inmem = false;
const char *dir = "data";

const char *ERR_INCOMPLETE = "incomplete";
const char *ERR_QUIT = "quit";

void get_buffer(uv_handle_t *handle, size_t size, uv_buf_t *buf){
	client *c = (client*)handle;
	if (c->buf_cap-c->buf_idx-c->buf_len < size){
		while (c->buf_cap-c->buf_idx-c->buf_len < size){
			if (c->buf_cap==0){
				c->buf_cap=1;
			}else{
				c->buf_cap*=2;
			}
		}
		c->buf = (char*)realloc(c->buf, c->buf_cap);
		if (!c->buf){
			err(1, "malloc");
		}
	}
	buf->base = c->buf+c->buf_idx+c->buf_len;
	buf->len = size;
}

void on_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf){
	client *c = (client*)stream;
	if (nread < 0) {
		client_close(c);
		return;
	}
	c->buf_len += nread;
	client_clear(c);
	bool keep_alive = client_exec_commands(c);
	client_flush_offset(c, c->output_offset);
	if (!keep_alive){
		client_close(c);
	}
}

void on_accept_work(uv_work_t *worker) {
	client *c = (client*)worker->data;
	uv_tcp_init(loop, &c->tcp);
	if (uv_accept(c->server, (uv_stream_t *)&c->tcp) == 0) {
		if (uv_read_start((uv_stream_t *)&c->tcp, get_buffer, on_read)){
			c->must_close = 1;
		}
		// read has started
	}else{
		c->must_close = 1;
	}
}

void on_accept_work_done(uv_work_t *worker, int status) {
	client *c = (client*)worker->data;
	if (c->must_close){
		client_close(c);
	}
}

void on_accept(uv_stream_t *server, int status) {
	if (status == -1) {
		return;
	}
	client *c = client_new();
	c->server = server;
	if (0){
		// future thread-pool stuff, perhaps rip this out
		uv_queue_work(loop, &c->worker, on_accept_work, on_accept_work_done);
	}else{
		on_accept_work(&c->worker);
		on_accept_work_done(&c->worker, 0);
	}
}

void log(char c, const char *format, ...){
	time_t rawtime;
	struct tm *info;
	char tbuf[32];
	struct timespec spec;
    clock_gettime(CLOCK_REALTIME, &spec);
	rawtime = spec.tv_sec;
	info = localtime( &rawtime );
	strftime(tbuf,sizeof(tbuf),"%d %b %H:%M:%S", info);
	char buffer[512];
	va_list args;
	va_start(args, format);
	vsnprintf(buffer,sizeof(buffer),format, args);
	char cc[32];
	if (isatty(1)){
		switch (c) {
		default: cc[0] = c; cc[1] = 0;
		case '.': strcpy(cc, "\x1b[35m.\x1b[0m"); break;
		case '*': strcpy(cc, "\x1b[1m*\x1b[0m"); break;
		case '#': strcpy(cc, "\x1b[33m#\x1b[0m"); break;
		}
	}else{
		cc[0] = c; cc[1] = 0;
	}
	fprintf(stderr, "%d:M %s.%d %s %s\n", getpid(), tbuf, ((int)(spec.tv_nsec/1.0e6))%1000, cc, buffer);
	va_end(args);
}

void opendb(){
	rocksdb::Options options;
	options.create_if_missing = true;
	if (inmem){
		options.env = rocksdb::NewMemEnv(rocksdb::Env::Default());
	}
	rocksdb::Status s = rocksdb::DB::Open(options, dir, &db);
	if (!s.ok()){
		err(1, "%s", s.ToString().c_str());
	}
}

void flushdb(){
	delete db;
	if (remove_directory(dir, false)){
		err(1, "remove_directory");
	}
	opendb();
}

int main(int argc, char **argv) {
	int tcp_port = 5555;
	bool tcp_port_provided = false;
	for (int i=1;i<argc;i++){
		if (strcmp(argv[i], "-h")==0||
			strcmp(argv[i], "--help")==0||
			strcmp(argv[i], "-?")==0){
			fprintf(stdout, "RocksDB version " ROCKSDB_VERSION ", Libuv version " LIBUV_VERSION ", Server version " SERVER_VERSION "\n");
			fprintf(stdout, "usage: %s [-d data_path] [-p tcp_port] [--nosync]\n", argv[0]);
			return 0;
		}else if (strcmp(argv[i], "--version")==0){
			fprintf(stdout, "RocksDB version " ROCKSDB_VERSION ", Libuv version " LIBUV_VERSION ", Server version " SERVER_VERSION "\n");
			return 0;
		}else if (strcmp(argv[i], "-d")==0){
			if (i+1 == argc){
				fprintf(stderr, "argument missing after: \"%s\"\n", argv[i]);
				return 1;
			}
			dir = argv[++i];
		}else if (strcmp(argv[i], "--nosync")==0){
			nosync = true;
		}else if (strcmp(argv[i], "--inmem")==0){
			inmem = true;
		}else if (strcmp(argv[i], "-p")==0){
			if (i+1 == argc){
				fprintf(stderr, "argument missing after: \"%s\"\n", argv[i]);
				return 1;
			}
			tcp_port = atoi(argv[i+1]);
			if (!tcp_port){
				fprintf(stderr, "invalid option '%s' for argument: \"%s\"\n", argv[i+1], argv[i]);
			}
			i++;
			tcp_port_provided = true;
		}else{
			fprintf(stderr, "unknown option argument: \"%s\"\n", argv[i]);
			return 1;
		}
	}
	log('#', "Server started, RocksDB version " ROCKSDB_VERSION ", Libuv version " LIBUV_VERSION ", Server version " SERVER_VERSION);
	opendb();

	uv_tcp_t server;
	loop = uv_default_loop();

	struct sockaddr_in addr;
	uv_ip4_addr("0.0.0.0", tcp_port, &addr);

	uv_tcp_init(loop, &server);
	uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);

	int r = uv_listen((uv_stream_t *)&server, -1, on_accept);
	if (r) {
		err(1, "uv_listen");
	}
	log('*', "The server is now ready to accept connections on port %d", tcp_port);
	return uv_run(loop, UV_RUN_DEFAULT);
}
<commit_msg>flags<commit_after>#include "server.h"

rocksdb::DB* db = NULL;
bool nosync = false;
int nprocs = 1;
uv_loop_t *loop = NULL;
bool inmem = false;
const char *dir = "data";

const char *ERR_INCOMPLETE = "incomplete";
const char *ERR_QUIT = "quit";

void get_buffer(uv_handle_t *handle, size_t size, uv_buf_t *buf){
	client *c = (client*)handle;
	if (c->buf_cap-c->buf_idx-c->buf_len < size){
		while (c->buf_cap-c->buf_idx-c->buf_len < size){
			if (c->buf_cap==0){
				c->buf_cap=1;
			}else{
				c->buf_cap*=2;
			}
		}
		c->buf = (char*)realloc(c->buf, c->buf_cap);
		if (!c->buf){
			err(1, "malloc");
		}
	}
	buf->base = c->buf+c->buf_idx+c->buf_len;
	buf->len = size;
}

void on_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf){
	client *c = (client*)stream;
	if (nread < 0) {
		client_close(c);
		return;
	}
	c->buf_len += nread;
	client_clear(c);
	bool keep_alive = client_exec_commands(c);
	client_flush_offset(c, c->output_offset);
	if (!keep_alive){
		client_close(c);
	}
}

void on_accept_work(uv_work_t *worker) {
	client *c = (client*)worker->data;
	uv_tcp_init(loop, &c->tcp);
	if (uv_accept(c->server, (uv_stream_t *)&c->tcp) == 0) {
		if (uv_read_start((uv_stream_t *)&c->tcp, get_buffer, on_read)){
			c->must_close = 1;
		}
		// read has started
	}else{
		c->must_close = 1;
	}
}

void on_accept_work_done(uv_work_t *worker, int status) {
	client *c = (client*)worker->data;
	if (c->must_close){
		client_close(c);
	}
}

void on_accept(uv_stream_t *server, int status) {
	if (status == -1) {
		return;
	}
	client *c = client_new();
	c->server = server;
	if (0){
		// future thread-pool stuff, perhaps rip this out
		uv_queue_work(loop, &c->worker, on_accept_work, on_accept_work_done);
	}else{
		on_accept_work(&c->worker);
		on_accept_work_done(&c->worker, 0);
	}
}

void log(char c, const char *format, ...){
	time_t rawtime;
	struct tm *info;
	char tbuf[32];
	struct timespec spec;
    clock_gettime(CLOCK_REALTIME, &spec);
	rawtime = spec.tv_sec;
	info = localtime( &rawtime );
	strftime(tbuf,sizeof(tbuf),"%d %b %H:%M:%S", info);
	char buffer[512];
	va_list args;
	va_start(args, format);
	vsnprintf(buffer,sizeof(buffer),format, args);
	char cc[32];
	if (isatty(1)){
		switch (c) {
		default: cc[0] = c; cc[1] = 0;
		case '.': strcpy(cc, "\x1b[35m.\x1b[0m"); break;
		case '*': strcpy(cc, "\x1b[1m*\x1b[0m"); break;
		case '#': strcpy(cc, "\x1b[33m#\x1b[0m"); break;
		}
	}else{
		cc[0] = c; cc[1] = 0;
	}
	fprintf(stderr, "%d:M %s.%d %s %s\n", getpid(), tbuf, ((int)(spec.tv_nsec/1.0e6))%1000, cc, buffer);
	va_end(args);
}

void opendb(){
	rocksdb::Options options;
	options.create_if_missing = true;
	if (inmem){
		options.env = rocksdb::NewMemEnv(rocksdb::Env::Default());
	}
	rocksdb::Status s = rocksdb::DB::Open(options, dir, &db);
	if (!s.ok()){
		err(1, "%s", s.ToString().c_str());
	}
}

void flushdb(){
	delete db;
	if (remove_directory(dir, false)){
		err(1, "remove_directory");
	}
	opendb();
}

int main(int argc, char **argv) {
	int tcp_port = 5555;
	bool tcp_port_provided = false;
	for (int i=1;i<argc;i++){
		if (strcmp(argv[i], "-h")==0||
			strcmp(argv[i], "--help")==0||
			strcmp(argv[i], "-?")==0){
			fprintf(stdout, "RocksDB version " ROCKSDB_VERSION ", Libuv version " LIBUV_VERSION ", Server version " SERVER_VERSION "\n");
			fprintf(stdout, "usage: %s [-d data_path] [-p tcp_port] [--nosync] [--inmem]\n", argv[0]);
			return 0;
		}else if (strcmp(argv[i], "--version")==0){
			fprintf(stdout, "RocksDB version " ROCKSDB_VERSION ", Libuv version " LIBUV_VERSION ", Server version " SERVER_VERSION "\n");
			return 0;
		}else if (strcmp(argv[i], "-d")==0){
			if (i+1 == argc){
				fprintf(stderr, "argument missing after: \"%s\"\n", argv[i]);
				return 1;
			}
			dir = argv[++i];
		}else if (strcmp(argv[i], "--nosync")==0){
			nosync = true;
		}else if (strcmp(argv[i], "--inmem")==0){
			inmem = true;
		}else if (strcmp(argv[i], "-p")==0){
			if (i+1 == argc){
				fprintf(stderr, "argument missing after: \"%s\"\n", argv[i]);
				return 1;
			}
			tcp_port = atoi(argv[i+1]);
			if (!tcp_port){
				fprintf(stderr, "invalid option '%s' for argument: \"%s\"\n", argv[i+1], argv[i]);
			}
			i++;
			tcp_port_provided = true;
		}else{
			fprintf(stderr, "unknown option argument: \"%s\"\n", argv[i]);
			return 1;
		}
	}
	log('#', "Server started, RocksDB version " ROCKSDB_VERSION ", Libuv version " LIBUV_VERSION ", Server version " SERVER_VERSION);
	opendb();

	uv_tcp_t server;
	loop = uv_default_loop();

	struct sockaddr_in addr;
	uv_ip4_addr("0.0.0.0", tcp_port, &addr);

	uv_tcp_init(loop, &server);
	uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);

	int r = uv_listen((uv_stream_t *)&server, -1, on_accept);
	if (r) {
		err(1, "uv_listen");
	}
	log('*', "The server is now ready to accept connections on port %d", tcp_port);
	return uv_run(loop, UV_RUN_DEFAULT);
}
<|endoftext|>


<commit_before>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// SingleCellView plugin
//==============================================================================

#include "cellmlfilemanager.h"
#include "cellmlsupportplugin.h"
#include "combinefilemanager.h"
#include "combinesupportplugin.h"
#include "coreguiutils.h"
#include "sedmlfilemanager.h"
#include "sedmlsupportplugin.h"
#include "singlecellviewplugin.h"
#include "singlecellviewwidget.h"

//==============================================================================

#include <QMainWindow>
#include <QSettings>

//==============================================================================

namespace OpenCOR {
namespace SingleCellView {

//==============================================================================

PLUGININFO_FUNC SingleCellViewPluginInfo()
{
    Descriptions descriptions;

    descriptions.insert("en", QString::fromUtf8("a plugin to run single cell simulations."));
    descriptions.insert("fr", QString::fromUtf8("une extension pour exécuter des simulations unicellulaires."));

    return new PluginInfo("Simulation", true, false,
                          QStringList() << "CellMLSupport" << "COMBINESupport"<< "Qwt" << "SEDMLSupport",
                          descriptions);
}

//==============================================================================

SingleCellViewPlugin::SingleCellViewPlugin() :
    mSolverInterfaces(SolverInterfaces()),
    mDataStoreInterfaces(DataStoreInterfaces()),
    mCellmlEditingViewPlugins(Plugins()),
    mSedmlFileTypes(FileTypes()),
    mCombineFileTypes(FileTypes())
{
}

//==============================================================================
// File handling interface
//==============================================================================

bool SingleCellViewPlugin::isIndirectRemoteFile(const QString &pFileName)
{
    // Check whether the given file is an indirect remote file

    return mViewWidget->isIndirectRemoteFile(pFileName);
}

//==============================================================================

bool SingleCellViewPlugin::saveFile(const QString &pOldFileName,
                                    const QString &pNewFileName,
                                    bool &pNeedFeedback)
{
    Q_UNUSED(pNeedFeedback);

    // Let our view widget know that we want to save a file

    return mViewWidget->saveFile(pOldFileName, pNewFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileOpened(const QString &pFileName)
{
    // Let our view widget know that a file has been opened

    mViewWidget->fileOpened(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::filePermissionsChanged(const QString &pFileName)
{
    // The given file has been un/locked, so let our view widget know about it

    mViewWidget->filePermissionsChanged(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileModified(const QString &pFileName)
{
    // Let our view widget know that a file has been modified

    mViewWidget->fileModified(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileReloaded(const QString &pFileName)
{
    // The given file has been reloaded, so let its corresponding view widget
    // know about it

    if (mViewWidget->contains(pFileName))
        mViewWidget->fileReloaded(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileRenamed(const QString &pOldFileName,
                                       const QString &pNewFileName)
{
    // Let our view widget know that a file has been renamed

    mViewWidget->fileRenamed(pOldFileName, pNewFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileSaved(const QString &pFileName)
{
    Q_UNUSED(pFileName);

    // We don't handle this interface...
}

//==============================================================================

void SingleCellViewPlugin::fileClosed(const QString &pFileName)
{
    // Let our view widget know that a file has been closed

    mViewWidget->fileClosed(pFileName);
}

//==============================================================================
// I18n interface
//==============================================================================

void SingleCellViewPlugin::retranslateUi()
{
    // Retranslate our single cell view widget

    mViewWidget->retranslateUi();
}

//==============================================================================
// Plugin interface
//==============================================================================

void SingleCellViewPlugin::initializePlugin()
{
    // Create our single view widget

    mViewWidget = new SingleCellViewWidget(this, Core::mainWindow());

    // Hide our single view widget since it may not initially be shown in our
    // central widget

    mViewWidget->setVisible(false);
}

//==============================================================================

void SingleCellViewPlugin::finalizePlugin()
{
    // We don't handle this interface...
}

//==============================================================================

void SingleCellViewPlugin::pluginsInitialized(const Plugins &pLoadedPlugins)
{
    // Retrieve the different solvers and data stores that are available to us,
    // as well as the file types supported by the SEDMLSupport plugin

    foreach (Plugin *plugin, pLoadedPlugins) {
        // Look for a solver

        SolverInterface *solverInterface = qobject_cast<SolverInterface *>(plugin->instance());

        if (solverInterface)
            mSolverInterfaces << solverInterface;

        // Look for a data store

        DataStoreInterface *dataStoreInterface = qobject_cast<DataStoreInterface *>(plugin->instance());

        if (dataStoreInterface)
            mDataStoreInterfaces << dataStoreInterface;

        // Look for a CellML capable editing view

        ViewInterface *viewInterface = qobject_cast<ViewInterface *>(plugin->instance());

        if (    viewInterface
            && (viewInterface->viewMode() == ViewInterface::EditingMode)
            &&  viewInterface->viewMimeTypes().contains(CellMLSupport::CellmlMimeType)) {
            mCellmlEditingViewPlugins << plugin;
        }

        // File types supported by the SEDMLSupport and COMBINESupport plugins

        FileTypeInterface *fileTypeInterface = qobject_cast<FileTypeInterface *>(plugin->instance());

        if (fileTypeInterface) {
            if (!plugin->name().compare("SEDMLSupport"))
                mSedmlFileTypes << fileTypeInterface->fileTypes();
            else if (!plugin->name().compare("COMBINESupport"))
                mCombineFileTypes << fileTypeInterface->fileTypes();
        }
    }
}

//==============================================================================

void SingleCellViewPlugin::loadSettings(QSettings *pSettings)
{
    // Retrieve our single cell view settings

    pSettings->beginGroup(mViewWidget->objectName());
        mViewWidget->loadSettings(pSettings);
    pSettings->endGroup();
}

//==============================================================================

void SingleCellViewPlugin::saveSettings(QSettings *pSettings) const
{
    // Keep track of our single cell view settings

    pSettings->beginGroup(mViewWidget->objectName());
        mViewWidget->saveSettings(pSettings);
    pSettings->endGroup();
}

//==============================================================================

void SingleCellViewPlugin::handleUrl(const QUrl &pUrl)
{
    Q_UNUSED(pUrl);

    // We don't handle this interface...
}

//==============================================================================
// View interface
//==============================================================================

ViewInterface::Mode SingleCellViewPlugin::viewMode() const
{
    // Return our mode

    return ViewInterface::SimulationMode;
}

//==============================================================================

QStringList SingleCellViewPlugin::viewMimeTypes() const
{
    // Return the MIME types we support

    return QStringList() << CellMLSupport::CellmlMimeType
                         << SEDMLSupport::SedmlMimeType
                         << COMBINESupport::CombineMimeType;
}

//==============================================================================

QString SingleCellViewPlugin::viewDefaultFileExtension() const
{
    // Return the default file extension we support

    return CellMLSupport::CellmlFileExtension;
}

//==============================================================================

bool SingleCellViewPlugin::hasViewWidget(const QString &pFileName)
{
    // Make sure that we are dealing with a CellML file

    if (!CellMLSupport::CellmlFileManager::instance()->cellmlFile(pFileName))
        return false;

    // Return whether we have a view widget for the given CellML file

    return mViewWidget->contains(pFileName);
}

//==============================================================================

QWidget * SingleCellViewPlugin::viewWidget(const QString &pFileName)
{
    // Make sure that we are dealing with a CellML file, a SED-ML file or a
    // COMBINE archive

    if (   !CellMLSupport::CellmlFileManager::instance()->cellmlFile(pFileName)
        && !SEDMLSupport::SedmlFileManager::instance()->sedmlFile(pFileName)
        && !COMBINESupport::CombineFileManager::instance()->combineArchive(pFileName)) {
        return 0;
    }

    // Update and return our simulation view widget using the given CellML file,
    // SED-ML file or COMBINE archive
    // Note: we temporarily disable updates for our simulation view widget, so
    //       as to avoid any risk of known/unknown/potential flickering...

    mViewWidget->setUpdatesEnabled(false);
        mViewWidget->initialize(pFileName);
    mViewWidget->setUpdatesEnabled(true);

    return mViewWidget;
}

//==============================================================================

void SingleCellViewPlugin::removeViewWidget(const QString &pFileName)
{
    // Ask our view widget to finalise the given CellML file

    mViewWidget->finalize(pFileName);
}

//==============================================================================

QString SingleCellViewPlugin::viewName() const
{
    // Return our single cell view's name

    return tr("Single Cell");
}

//==============================================================================

QIcon SingleCellViewPlugin::fileTabIcon(const QString &pFileName) const
{
    // Return the requested file tab icon

    return mViewWidget->fileTabIcon(pFileName);
}

//==============================================================================
// Plugin specific
//==============================================================================

SingleCellViewWidget * SingleCellViewPlugin::viewWidget() const
{
    // Return our view widget

    return mViewWidget;
}

//==============================================================================

SolverInterfaces SingleCellViewPlugin::solverInterfaces() const
{
    // Return our solver interfaces

    return mSolverInterfaces;
}

//==============================================================================

DataStoreInterfaces SingleCellViewPlugin::dataStoreInterfaces() const
{
    // Return our data store interfaces

    return mDataStoreInterfaces;
}

//==============================================================================

Plugins SingleCellViewPlugin::cellmlEditingViewPlugins() const
{
    // Return our CellML editing view plugins

    return mCellmlEditingViewPlugins;
}

//==============================================================================

FileTypes SingleCellViewPlugin::sedmlFileTypes() const
{
    // Return our SED-ML file types

    return mSedmlFileTypes;
}

//==============================================================================

FileTypes SingleCellViewPlugin::combineFileTypes() const
{
    // Return our COMBINE file types

    return mCombineFileTypes;
}

//==============================================================================

}   // namespace SingleCellView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// SingleCellView plugin
//==============================================================================

#include "cellmlfilemanager.h"
#include "cellmlsupportplugin.h"
#include "combinefilemanager.h"
#include "combinesupportplugin.h"
#include "coreguiutils.h"
#include "sedmlfilemanager.h"
#include "sedmlsupportplugin.h"
#include "singlecellviewplugin.h"
#include "singlecellviewwidget.h"

//==============================================================================

#include <QMainWindow>
#include <QSettings>

//==============================================================================

namespace OpenCOR {
namespace SingleCellView {

//==============================================================================

PLUGININFO_FUNC SingleCellViewPluginInfo()
{
    Descriptions descriptions;

    descriptions.insert("en", QString::fromUtf8("a plugin to run single cell simulations."));
    descriptions.insert("fr", QString::fromUtf8("une extension pour exécuter des simulations unicellulaires."));

    return new PluginInfo("Simulation", true, false,
                          QStringList() << "CellMLSupport" << "COMBINESupport"<< "Qwt" << "SEDMLSupport",
                          descriptions);
}

//==============================================================================

SingleCellViewPlugin::SingleCellViewPlugin() :
    mSolverInterfaces(SolverInterfaces()),
    mDataStoreInterfaces(DataStoreInterfaces()),
    mCellmlEditingViewInterfaces(ViewInterfaces()),
    mSedmlFileTypes(FileTypes()),
    mCombineFileTypes(FileTypes())
{
}

//==============================================================================
// File handling interface
//==============================================================================

bool SingleCellViewPlugin::isIndirectRemoteFile(const QString &pFileName)
{
    // Check whether the given file is an indirect remote file

    return mViewWidget->isIndirectRemoteFile(pFileName);
}

//==============================================================================

bool SingleCellViewPlugin::saveFile(const QString &pOldFileName,
                                    const QString &pNewFileName,
                                    bool &pNeedFeedback)
{
    Q_UNUSED(pNeedFeedback);

    // Let our view widget know that we want to save a file

    return mViewWidget->saveFile(pOldFileName, pNewFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileOpened(const QString &pFileName)
{
    // Let our view widget know that a file has been opened

    mViewWidget->fileOpened(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::filePermissionsChanged(const QString &pFileName)
{
    // The given file has been un/locked, so let our view widget know about it

    mViewWidget->filePermissionsChanged(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileModified(const QString &pFileName)
{
    // Let our view widget know that a file has been modified

    mViewWidget->fileModified(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileReloaded(const QString &pFileName)
{
    // The given file has been reloaded, so let its corresponding view widget
    // know about it

    if (mViewWidget->contains(pFileName))
        mViewWidget->fileReloaded(pFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileRenamed(const QString &pOldFileName,
                                       const QString &pNewFileName)
{
    // Let our view widget know that a file has been renamed

    mViewWidget->fileRenamed(pOldFileName, pNewFileName);
}

//==============================================================================

void SingleCellViewPlugin::fileSaved(const QString &pFileName)
{
    Q_UNUSED(pFileName);

    // We don't handle this interface...
}

//==============================================================================

void SingleCellViewPlugin::fileClosed(const QString &pFileName)
{
    // Let our view widget know that a file has been closed

    mViewWidget->fileClosed(pFileName);
}

//==============================================================================
// I18n interface
//==============================================================================

void SingleCellViewPlugin::retranslateUi()
{
    // Retranslate our single cell view widget

    mViewWidget->retranslateUi();
}

//==============================================================================
// Plugin interface
//==============================================================================

void SingleCellViewPlugin::initializePlugin()
{
    // Create our single view widget

    mViewWidget = new SingleCellViewWidget(this, Core::mainWindow());

    // Hide our single view widget since it may not initially be shown in our
    // central widget

    mViewWidget->setVisible(false);
}

//==============================================================================

void SingleCellViewPlugin::finalizePlugin()
{
    // We don't handle this interface...
}

//==============================================================================

void SingleCellViewPlugin::pluginsInitialized(const Plugins &pLoadedPlugins)
{
    // Retrieve the different solvers and data stores that are available to us,
    // as well as the file types supported by the SEDMLSupport plugin

    foreach (Plugin *plugin, pLoadedPlugins) {
        // Look for a solver

        SolverInterface *solverInterface = qobject_cast<SolverInterface *>(plugin->instance());

        if (solverInterface)
            mSolverInterfaces << solverInterface;

        // Look for a data store

        DataStoreInterface *dataStoreInterface = qobject_cast<DataStoreInterface *>(plugin->instance());

        if (dataStoreInterface)
            mDataStoreInterfaces << dataStoreInterface;

        // Look for a CellML capable editing view

        ViewInterface *viewInterface = qobject_cast<ViewInterface *>(plugin->instance());

        if (    viewInterface
            && (viewInterface->viewMode() == ViewInterface::EditingMode)
            &&  viewInterface->viewMimeTypes().contains(CellMLSupport::CellmlMimeType)) {
            mCellmlEditingViewInterfaces << viewInterface;
        }

        // File types supported by the SEDMLSupport and COMBINESupport plugins

        FileTypeInterface *fileTypeInterface = qobject_cast<FileTypeInterface *>(plugin->instance());

        if (fileTypeInterface) {
            if (!plugin->name().compare("SEDMLSupport"))
                mSedmlFileTypes << fileTypeInterface->fileTypes();
            else if (!plugin->name().compare("COMBINESupport"))
                mCombineFileTypes << fileTypeInterface->fileTypes();
        }
    }
}

//==============================================================================

void SingleCellViewPlugin::loadSettings(QSettings *pSettings)
{
    // Retrieve our single cell view settings

    pSettings->beginGroup(mViewWidget->objectName());
        mViewWidget->loadSettings(pSettings);
    pSettings->endGroup();
}

//==============================================================================

void SingleCellViewPlugin::saveSettings(QSettings *pSettings) const
{
    // Keep track of our single cell view settings

    pSettings->beginGroup(mViewWidget->objectName());
        mViewWidget->saveSettings(pSettings);
    pSettings->endGroup();
}

//==============================================================================

void SingleCellViewPlugin::handleUrl(const QUrl &pUrl)
{
    Q_UNUSED(pUrl);

    // We don't handle this interface...
}

//==============================================================================
// View interface
//==============================================================================

ViewInterface::Mode SingleCellViewPlugin::viewMode() const
{
    // Return our mode

    return ViewInterface::SimulationMode;
}

//==============================================================================

QStringList SingleCellViewPlugin::viewMimeTypes() const
{
    // Return the MIME types we support

    return QStringList() << CellMLSupport::CellmlMimeType
                         << SEDMLSupport::SedmlMimeType
                         << COMBINESupport::CombineMimeType;
}

//==============================================================================

QString SingleCellViewPlugin::viewDefaultFileExtension() const
{
    // Return the default file extension we support

    return CellMLSupport::CellmlFileExtension;
}

//==============================================================================

bool SingleCellViewPlugin::hasViewWidget(const QString &pFileName)
{
    // Make sure that we are dealing with a CellML file

    if (!CellMLSupport::CellmlFileManager::instance()->cellmlFile(pFileName))
        return false;

    // Return whether we have a view widget for the given CellML file

    return mViewWidget->contains(pFileName);
}

//==============================================================================

QWidget * SingleCellViewPlugin::viewWidget(const QString &pFileName)
{
    // Make sure that we are dealing with a CellML file, a SED-ML file or a
    // COMBINE archive

    if (   !CellMLSupport::CellmlFileManager::instance()->cellmlFile(pFileName)
        && !SEDMLSupport::SedmlFileManager::instance()->sedmlFile(pFileName)
        && !COMBINESupport::CombineFileManager::instance()->combineArchive(pFileName)) {
        return 0;
    }

    // Update and return our simulation view widget using the given CellML file,
    // SED-ML file or COMBINE archive
    // Note: we temporarily disable updates for our simulation view widget, so
    //       as to avoid any risk of known/unknown/potential flickering...

    mViewWidget->setUpdatesEnabled(false);
        mViewWidget->initialize(pFileName);
    mViewWidget->setUpdatesEnabled(true);

    return mViewWidget;
}

//==============================================================================

void SingleCellViewPlugin::removeViewWidget(const QString &pFileName)
{
    // Ask our view widget to finalise the given CellML file

    mViewWidget->finalize(pFileName);
}

//==============================================================================

QString SingleCellViewPlugin::viewName() const
{
    // Return our single cell view's name

    return tr("Single Cell");
}

//==============================================================================

QIcon SingleCellViewPlugin::fileTabIcon(const QString &pFileName) const
{
    // Return the requested file tab icon

    return mViewWidget->fileTabIcon(pFileName);
}

//==============================================================================
// Plugin specific
//==============================================================================

SingleCellViewWidget * SingleCellViewPlugin::viewWidget() const
{
    // Return our view widget

    return mViewWidget;
}

//==============================================================================

SolverInterfaces SingleCellViewPlugin::solverInterfaces() const
{
    // Return our solver interfaces

    return mSolverInterfaces;
}

//==============================================================================

DataStoreInterfaces SingleCellViewPlugin::dataStoreInterfaces() const
{
    // Return our data store interfaces

    return mDataStoreInterfaces;
}

//==============================================================================

ViewInterfaces SingleCellViewPlugin::cellmlEditingViewInterfaces() const
{
    // Return our CellML editing view interfaces

    return mCellmlEditingViewInterfaces;
}

//==============================================================================

FileTypes SingleCellViewPlugin::sedmlFileTypes() const
{
    // Return our SED-ML file types

    return mSedmlFileTypes;
}

//==============================================================================

FileTypes SingleCellViewPlugin::combineFileTypes() const
{
    // Return our COMBINE file types

    return mCombineFileTypes;
}

//==============================================================================

}   // namespace SingleCellView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>#include "solver_lbfgs.h"
#include <deque>

using namespace nano;

tuner_t solver_lbfgs_t::tuner() const
{
        tuner_t tuner;
        tuner.add_enum<lsearch_t::initializer>("init");
        tuner.add_enum<lsearch_t::strategy>("strat");
        return tuner;
}

void solver_lbfgs_t::from_json(const json_t& json)
{
        nano::from_json(json,
                "init", m_init, "strat", m_strat,
                "c1", m_c1, "c2", m_c2, "history", m_history_size);
}

void solver_lbfgs_t::to_json(json_t& json) const
{
        nano::to_json(json,
                "init", m_init, "inits", join(enum_values<lsearch_t::initializer>()),
                "strat", m_strat, "strats", join(enum_values<lsearch_t::strategy>()),
                "c1", m_c1, "c2", m_c2, "history", m_history_size);
}

solver_state_t solver_lbfgs_t::minimize(const size_t max_iterations, const scalar_t epsilon,
        const function_t& function, const vector_t& x0, const logger_t& logger) const
{
        lsearch_t lsearch(m_init, m_strat, m_c1, m_c2);

        // previous state
        solver_state_t pstate(function.size());

        std::deque<vector_t> ss, ys;
        vector_t q, r;

        const auto op = [&] (solver_state_t& cstate, const std::size_t i)
        {
                // descent direction
                //      (see "Numerical optimization", Nocedal & Wright, 2nd edition, p.178)
                q = cstate.g;

                auto itr_s = ss.rbegin();
                auto itr_y = ys.rbegin();
                std::vector<scalar_t> alphas;
                for (std::size_t j = 1; j <= m_history_size && i >= j; j ++)
                {
                        const vector_t& s = (*itr_s ++);
                        const vector_t& y = (*itr_y ++);

                        const scalar_t alpha = s.dot(q) / s.dot(y);
                        q.noalias() -= alpha * y;
                        alphas.push_back(alpha);
                }

                if (i == 0)
                {
                        r = q;
                }
                else
                {
                        const vector_t& s = *ss.rbegin();
                        const vector_t& y = *ys.rbegin();
                        r = s.dot(y) / y.dot(y) * q;
                }

                auto it_s = ss.begin();
                auto it_y = ys.begin();
                auto itr_alpha = alphas.rbegin();
                for (std::size_t j = 1; j <= m_history_size && i >= j; j ++)
                {
                        const vector_t& s = (*it_s ++);
                        const vector_t& y = (*it_y ++);

                        const scalar_t alpha = *(itr_alpha ++);
                        const scalar_t beta = y.dot(r) / s.dot(y);
                        r.noalias() += s * (alpha - beta);
                }

                cstate.d = -r;

                // line-search
                pstate = cstate;
                if (!lsearch(function, cstate))
                {
                        return false;
                }

                // todo: may skip the update if the curvature condition is not satisfied
                // see: "A Multi-Batch L-BFGS Method for Machine Learning", page 6 - the non-convex case
                ss.emplace_back(cstate.x - pstate.x);
                ys.emplace_back(cstate.g - pstate.g);
                if (ss.size() > m_history_size)
                {
                        ss.pop_front();
                        ys.pop_front();
                }

                return true;
        };

        // assembly the solver
        return loop(function, x0, max_iterations, epsilon, logger, op);
}
<commit_msg>clearer lbfgs implementation<commit_after>#include <deque>
#include "solver_lbfgs.h"

using namespace nano;

tuner_t solver_lbfgs_t::tuner() const
{
        tuner_t tuner;
        tuner.add_enum<lsearch_t::initializer>("init");
        tuner.add_enum<lsearch_t::strategy>("strat");
        return tuner;
}

void solver_lbfgs_t::from_json(const json_t& json)
{
        nano::from_json(json,
                "init", m_init, "strat", m_strat,
                "c1", m_c1, "c2", m_c2, "history", m_history_size);
}

void solver_lbfgs_t::to_json(json_t& json) const
{
        nano::to_json(json,
                "init", m_init, "inits", join(enum_values<lsearch_t::initializer>()),
                "strat", m_strat, "strats", join(enum_values<lsearch_t::strategy>()),
                "c1", m_c1, "c2", m_c2, "history", m_history_size);
}

solver_state_t solver_lbfgs_t::minimize(const size_t max_iterations, const scalar_t epsilon,
        const function_t& function, const vector_t& x0, const logger_t& logger) const
{
        lsearch_t lsearch(m_init, m_strat, m_c1, m_c2);

        // previous state
        solver_state_t pstate(function.size());

        std::deque<vector_t> ss, ys;
        vector_t q, r;

        const auto op = [&] (solver_state_t& cstate, const size_t)
        {
                // descent direction
                //      (see "Numerical optimization", Nocedal & Wright, 2nd edition, p.178)
                q = cstate.g;

                const auto hsize = ss.size();

                std::vector<scalar_t> alphas(hsize);
                for (size_t j = 0; j < hsize; ++ j)
                {
                        const auto& s = ss[hsize - 1 - j];
                        const auto& y = ys[hsize - 1 - j];

                        const scalar_t alpha = s.dot(q) / s.dot(y);
                        q.noalias() -= alpha * y;
                        alphas[j] = alpha;
                }

                if (ss.empty())
                {
                        r = q;
                }
                else
                {
                        const auto& s = ss[hsize - 1];
                        const auto& y = ys[hsize - 1];

                        r = s.dot(y) / y.dot(y) * q;
                }

                for (size_t j = 0; j < hsize; ++ j)
                {
                        const auto& s = ss[j];
                        const auto& y = ys[j];

                        const scalar_t alpha = alphas[hsize - 1 - j];
                        const scalar_t beta = y.dot(r) / s.dot(y);
                        r.noalias() += s * (alpha - beta);
                }

                cstate.d = -r;

                // line-search
                pstate = cstate;
                if (!lsearch(function, cstate))
                {
                        return false;
                }

                // todo: may skip the update if the curvature condition is not satisfied
                // see: "A Multi-Batch L-BFGS Method for Machine Learning", page 6 - the non-convex case
                ss.emplace_back(cstate.x - pstate.x);
                ys.emplace_back(cstate.g - pstate.g);
                if (ss.size() > m_history_size)
                {
                        ss.pop_front();
                        ys.pop_front();
                }

                return true;
        };

        // assembly the solver
        return loop(function, x0, max_iterations, epsilon, logger, op);
}
<|endoftext|>