<commit_before>#include <iostream>
#include <cassert>
#include <chrono>
#include <random>
#include <algorithm>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cmath>
#include <limits>

#include <assimp/Importer.hpp>  // C++ importer interface
#include <assimp/scene.h>       // Output data structure
#include <assimp/postprocess.h> // Post processing flags

#include "geometry3d.h"
#include "montecarlo.h"
#include "rpc_over_mqtt.h"

#include <particlefilter.grpc.pb.h>

#define N_BOX 8
#define N_SENSORS 4

struct request_t
{
    mesh_t mesh;
    particle_vector_t particles;
    motion_t motion;
    motion_noise_t noise;
    measurements_t measurements;
};

static const btScalar M_2PI = btScalar(M_PI) * 2;

std::ostream& operator << (std::ostream &os, const btVector3 &v)
{
    os << v.x() << " " << v.y() << " " << v.z();
    return os;
}

std::ostream& operator << (std::ostream &os, const btVector4 &v)
{
    os << v.x() << " " << v.y() << " " << v.z() << " " << v.w();
    return os;
}

std::ostream& operator << (std::ostream &os, const box_t &b)
{
    os << "[" << b.first << ", " << b.second << "]";
    return os;
}

class ParticleServer : public RPCServer
{
public:
    ParticleServer(const std::string &svr_id)
        : RPCServer(svr_id)
    {
        //request.motion = {0.0, 500.0}; // delta_theta, s
        //request.noise = {30.0, 1.0 * 0.5, 50.0}; // bearing, steering, distance
    }

    virtual ~ParticleServer() {}

public:

    virtual void on_message(const struct mosquitto_message *message)
    {
        particle::LocRequest loc_request;
        std::string buffer;
        particle::EstimatedLocation response;

        bool ok = loc_request.ParseFromArray(message->payload, message->payloadlen);
        if(!ok)
        {
            response.set_error("Deserialization error");
        }
        else
        {
            // Process request
/*
            if(request.mesh.vertices.empty())
            {
                // Create an instance of the Importer class
                Assimp::Importer importer;
                // And have it read the given file with some example postprocessing
                // Usually - if speed is not the most important aspect for you - you'll
                // propably to request more postprocessing than we do in this example.
                const aiScene* scene = importer.ReadFile("room.obj",
                               //aiProcess_FlipWindingOrder       |
                               //aiProcess_CalcTangentSpace       |
                               aiProcess_Triangulate            |
                               aiProcess_JoinIdenticalVertices  |

                               //aiProcess_PreTransformVertices   |
                               aiProcess_OptimizeGraph          |
                               aiProcess_OptimizeMeshes         |

                               aiProcess_FixInfacingNormals     |
                               aiProcess_GenSmoothNormals       |

                               aiProcess_SortByPType);

                // If the import failed, report it
                if(!scene)
                {
                    std::cout << importer.GetErrorString() << std::endl;
                    return;
                }

                //std::cout << scene->mNumMeshes << " " << scene->mRootNode->mNumMeshes << std::endl;

                unsigned int idx_offset = 0;

                for(unsigned int i = 0; i < scene->mNumMeshes; ++i)
                {
                    const aiMesh &mesh = *(scene->mMeshes[i]);
                    //std::cout << mesh.mNumVertices << std::endl;
                    for(unsigned int v = 0; v < mesh.mNumVertices; ++v)
                    {
                        btVector3 vert(mesh.mVertices[v].x,
                                       mesh.mVertices[v].y,
                                       mesh.mVertices[v].z);
                        request.mesh.vertices.push_back(vert);
                    }
                    for(unsigned int f = 0; f < mesh.mNumFaces; ++f)
                    {
                        const aiFace &face = mesh.mFaces[f];
                        assert(face.mNumIndices == 3);
                        triangleidx_t new_triangle = {face.mIndices[0] + idx_offset,
                                                      face.mIndices[1] + idx_offset,
                                                      face.mIndices[2] + idx_offset};
                        request.mesh.triangles.push_back(new_triangle);

                        const btVector3 &v0 = request.mesh.vertices[new_triangle[0]];
                        const btVector3 &v1 = request.mesh.vertices[new_triangle[1]];
                        const btVector3 &v2 = request.mesh.vertices[new_triangle[2]];
                        request.mesh.edges.push_back({v1-v0, v2-v0});
                    }
                    idx_offset += mesh.mNumVertices;
                }

                bounding_box(request.mesh, bbox);
                world_size = bbox.second - bbox.first;
                std::cout << "Bounding box: " << bbox << std::endl;
                std::cout << "World size: " << world_size << std::endl;
                std::cout << "Vertex count: " << request.mesh.vertices.size() << std::endl;
                std::cout << "Triangle count: " << request.mesh.triangles.size() << std::endl;

                // Split the world evenly with boxes
                btScalar box_x_size = world_size.x() / N_BOX;
                btScalar box_y_size = world_size.y();
                btScalar box_z_size = world_size.z() / N_BOX;
                btScalar box_x_half_size = box_x_size / 2;
                btScalar box_y_half_size = box_y_size / 2;
                btScalar box_z_half_size = box_z_size / 2;
                for(size_t ix = 0; ix < N_BOX; ++ix)
                {
                    for(size_t iz = 0; iz < N_BOX; ++iz)
                    {
                        space_partition_t part =
                        {
                            std::make_pair(
                                btVector3( // box center
                                    box_x_size * ix + box_x_half_size,
                                    box_y_half_size,
                                    box_z_size * iz + box_z_half_size
                                ),
                                btVector3( // box half sizes
                                    box_x_half_size,
                                    box_y_half_size,
                                    box_z_half_size
                                )),
                                {} // placeholder for bounding triangle indexes
                        };
                        partitions.push_back(part);
                    }
                }

                // Calculate list of bounding triangles for each box
                size_t triangles_processed = 0;
                for(space_partition_t &part: partitions)
                {
                    size_t i = 0;
                    for(auto const &tri_indexes: request.mesh.triangles)
                    {
                        trianglevert_t verts = {
                            &request.mesh.vertices[tri_indexes[0]],
                            &request.mesh.vertices[tri_indexes[1]],
                            &request.mesh.vertices[tri_indexes[2]]
                        };
                        if(triboxoverlap(part.box.first, part.box.second, verts))
                        {
                            part.bounding_triangles.push_back(i);
                        }
                        ++i;
                    }
                    triangles_processed += part.bounding_triangles.size();
                    //std::cout << "Triangles in box:" << part.bounding_triangles.size() << std::endl;
                }
                std::cout << "Total triangles in boxes:" << triangles_processed << std::endl;
            }

            static const unsigned seed1 =
                unsigned(std::chrono::system_clock::now().time_since_epoch().count());
            std::default_random_engine generator(seed1);
            std::uniform_real_distribution<btScalar> random_uniform(0.0, 1.0);

            btVector4 location(1000, 0, 1000, 0);

            if(request.particles.empty())
            {
                request.particles.resize(N_PART);
                for(auto &particle: request.particles)
                {
                    particle.setX(random_uniform(generator) * world_size.x() + bbox.first.x());
                    particle.setY(random_uniform(generator) * 3 + bbox.first.y());
                    particle.setZ(random_uniform(generator) * world_size.z() + bbox.first.z());
                    particle.setW(random_uniform(generator) * M_2PI);

                    //particle.setX(random_gauss(location.x(), 500));
                    //particle.setY(random_gauss(location.y(), 500));
                    //particle.setZ(random_gauss(location.z(), 500));
                    //particle.setW(random_gauss(location.w(), M_PI_4));

                    //std::cout << particle.x() << "\t" << particle.y() << std::endl;
                }
            }

            std::array<btScalar, N_PART> weights;
            const btVector3 init_dir(1.0, 0.0, 0.0);
            request.measurements.resize(N_SENSORS);
            btScalar min_dist;
            btVector3 origin;
            btVector3 xpoint;

            for(size_t step = 0; step < 8; ++step)
            {
                // Simulate measurements
                for(size_t s = 0; s < N_SENSORS; ++s) // generate sensor directions
                {
                    rotateY(init_dir, M_2PI / N_SENSORS * s, request.measurements[s].direction);
                }

                size_t m = 0;
                for(measurement_t &meas: request.measurements)
                {
                    ++m;
                    std::cout << "*************** Step: " << step << "  Measurement: " << m << std::endl;
                    meas.origin = btVector3(0.0, 300.0, 0.0);
                    origin = location + meas.origin;
                    std::cout << "Origin: " << origin
                              << "  direction: " <<  meas.direction
                              << std::endl;

                    min_dist = (-std::numeric_limits<btScalar>::infinity());
                    //triangles_processed = 0;
                    for(const auto &part: partitions)
                    {
                        //std::cout << "Triangles in partition: " << part.bounding_triangles.size() << std::endl;
                        // build "bounding box" style box
                        // .first is the middle of the box
                        // .second is half size
                        box_t bb = std::make_pair(
                                part.box.first - part.box.second,
                                part.box.first + part.box.second);

                        //std::cout << "Checking bounding box: " << bb
                        //          << " (" << part.bounding_triangles.size() << " triangles)"
                        //          << std::endl;

                        // Check if measurement ray intersects the box.
                        // Only if it does, we will check relevant triangles.
                        if(boxrayintersect(bb, origin, meas.direction, xpoint))
                        {
                            //std:: cout << "       - intersection" << std::endl;

                            for(const auto &vx: part.bounding_triangles)
                            {
                                const triangleidx_t &tri_verts_idx =
                                    request.mesh.triangles[vx];
                                const btVector3 &vert0 =
                                    request.mesh.vertices[tri_verts_idx[0]];

                                const btVector3 &edge1 = request.mesh.edges[vx][0];
                                const btVector3 &edge2 = request.mesh.edges[vx][1];

                                //triangles_processed += 1;
                                bool x = intersect_triangle(origin, meas.direction,
                                                            vert0, edge1, edge2,
                                                            xpoint, false);
                                btScalar t = xpoint.x();
                                if(x && t > 0)
                                {
                                    //std::cout << "Intersection with tirangle # " << vx << std::endl;
                                    if(min_dist == (-std::numeric_limits<btScalar>::infinity())
                                       || t < min_dist)
                                    {
                                        min_dist = t;
                                    }
                                }
                            }
                        }
                    }
                    meas.distance = min_dist;
                    //std::cout << "Processed triangles: " << triangles_processed << std::endl;
                    std::cout << "Location/distance: " << location << " / " << min_dist << std::endl;
                }

                // Measurement update
                size_t n = 0;
                for(const particle_t &particle: request.particles)
                {
                    weights[n] = measurement_prob(partitions,
                                                  request.mesh,
                                                  particle,
                                                  request.measurements,
                                                  request.noise);
                    //std::cout << weights[n] << std::endl;
                    ++n;
                }

                // Normalization
                btScalar sum_weights = btScalar(0.0);
                for(const auto &w: weights)
                    sum_weights += w;
                std::cout << "Sum(weights): " << sum_weights << std::endl;
                if(sum_weights > 0)
                {
                    btScalar k = request.particles.size() / sum_weights;
                    for(auto &w: weights)
                        w *= k;
                }

                // Resampling
                particle_vector_t p2(request.particles.size());
                particle_vector_t::size_type index =
                    particle_vector_t::size_type(random_uniform(generator)
                                                 * request.particles.size());
                btScalar beta = 0.0;
                const btScalar two_mw =
                    btScalar(2.0) * (*std::max_element(weights.begin(), weights.end()));
                for(particle_vector_t::size_type i = 0; i < request.particles.size(); ++i)
                {
                    beta += random_uniform(generator) * two_mw;
                    while(beta > weights[index])
                    {
                        beta -= weights[index];
                        index = (index + 1) % request.particles.size();
                    }
                    p2[i] = request.particles[index];
                }

                //for(const auto &p: p2) std::cout << p << std::endl;
                //std::cout << std::endl;

                particle_t est_pos;
                //get_position(request.particles, est_pos);
                get_position(p2, est_pos);
                std::cout << "** Estimated position: " << est_pos << std::endl;

                //visualization(location, est_pos, step, particles, p2, weights)

                request.particles = p2;

                std::cout << "======== " << step << " ========" << std::endl;

                // Motion update (prediction)
                for(auto &p: request.particles)
                    move(p, request.motion, request.noise, p);

                location.setX(location.x() + 500);
            }
*/
			particle::vector4 *loc = response.mutable_location();
            loc->set_x(1);
            loc->set_y(2);
            loc->set_z(3);
            loc->set_w(4);
            response.set_error(""); // No error
        }

        ok = response.SerializeToString(&buffer);
        if(!ok)
        {
            std::cout << "Response serialization error" << std::endl;
            return;
        }

        // Search for client_id string in topic which is in format
        // /server_id/client_id/request
        // Answer should be sent to the topic
        // /server_id/client_id/response
        const std::string topic(message->topic);
        size_t first_slash = topic.rfind("/");
        size_t second_slash = topic.rfind("/", first_slash - 1);
        const std::string client_id = topic.substr(second_slash, first_slash - second_slash);
        const std::string publish_topic =
            std::string("/") + server_id + client_id
            + std::string("/response");
        std::cout << "Publish topic: " << publish_topic << std::endl;

        int mid = 0;
        int res = publish(&mid,
                          publish_topic.c_str(),
                          buffer.size(),
                          buffer.c_str());
        if(res)
            std::cerr << "Publish returned: " << res << " " << mosqpp::strerror(res) << std::endl;
        else
            std::cerr << "Publish message id: " << mid << std::endl;
    }

protected:
	request_t request;
    box_t bbox;
    btVector3 world_size;
    partition_vector_t partitions;
};

int main(int argc, char *argv[])
{
    // Verify that the version of the library that we linked against is
    // compatible with the version of the headers we compiled against.
    GOOGLE_PROTOBUF_VERIFY_VERSION;

	mosquitto_lib_init();

	ParticleServer server("server1");
    server.run();

	return 0;
}

<commit_msg>Exchange serialized protobufs over MQTT<commit_after>#include <iostream>
#include <cassert>
#include <chrono>
#include <random>
#include <algorithm>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cmath>
#include <limits>

#include <assimp/Importer.hpp>  // C++ importer interface
#include <assimp/scene.h>       // Output data structure
#include <assimp/postprocess.h> // Post processing flags

#include "geometry3d.h"
#include "montecarlo.h"
#include "rpc_over_mqtt.h"

#include <particlefilter.grpc.pb.h>

#define N_BOX 8
#define N_SENSORS 4

struct request_t
{
    mesh_t mesh;
    particle_vector_t particles;
    motion_t motion;
    motion_noise_t noise;
    measurements_t measurements;
};

static const btScalar M_2PI = btScalar(M_PI) * 2;

std::ostream& operator << (std::ostream &os, const btVector3 &v)
{
    os << v.x() << " " << v.y() << " " << v.z();
    return os;
}

std::ostream& operator << (std::ostream &os, const btVector4 &v)
{
    os << v.x() << " " << v.y() << " " << v.z() << " " << v.w();
    return os;
}

std::ostream& operator << (std::ostream &os, const box_t &b)
{
    os << "[" << b.first << ", " << b.second << "]";
    return os;
}

class ParticleServer : public RPCServer
{
public:
    ParticleServer(const std::string &svr_id)
        : RPCServer(svr_id)
    {
        //request.motion = {0.0, 500.0}; // delta_theta, s
        //request.noise = {30.0, 1.0 * 0.5, 50.0}; // bearing, steering, distance
    }

    virtual ~ParticleServer() {}

public:

    virtual void on_message(const struct mosquitto_message *message)
    {
        particle::LocRequest loc_request;
        particle::EstimatedLocation response;

        bool ok = loc_request.ParseFromArray(message->payload, message->payloadlen);
        if(!ok)
        {
            response.set_error("Deserialization error");
        }
        else
        {
            // Process request

            if(request.mesh.vertices.empty())
            {
                // Create an instance of the Importer class
                Assimp::Importer importer;
                // And have it read the given file with some example postprocessing
                // Usually - if speed is not the most important aspect for you - you'll
                // propably to request more postprocessing than we do in this example.
                const aiScene* scene = importer.ReadFile(loc_request.map_location(),
                               //aiProcess_FlipWindingOrder       |
                               //aiProcess_CalcTangentSpace       |
                               aiProcess_Triangulate            |
                               aiProcess_JoinIdenticalVertices  |

                               //aiProcess_PreTransformVertices   |
                               aiProcess_OptimizeGraph          |
                               aiProcess_OptimizeMeshes         |

                               aiProcess_FixInfacingNormals     |
                               aiProcess_GenSmoothNormals       |

                               aiProcess_SortByPType);

                // If the import failed, report it
                if(!scene)
                {
                    std::cout << importer.GetErrorString() << std::endl;
                    response.set_error(importer.GetErrorString());
                }

                //std::cout << scene->mNumMeshes << " " << scene->mRootNode->mNumMeshes << std::endl;

                unsigned int idx_offset = 0;

                for(unsigned int i = 0; i < scene->mNumMeshes; ++i)
                {
                    const aiMesh &mesh = *(scene->mMeshes[i]);
                    //std::cout << mesh.mNumVertices << std::endl;
                    for(unsigned int v = 0; v < mesh.mNumVertices; ++v)
                    {
                        btVector3 vert(mesh.mVertices[v].x,
                                       mesh.mVertices[v].y,
                                       mesh.mVertices[v].z);
                        request.mesh.vertices.push_back(vert);
                    }
                    for(unsigned int f = 0; f < mesh.mNumFaces; ++f)
                    {
                        const aiFace &face = mesh.mFaces[f];
                        assert(face.mNumIndices == 3);
                        triangleidx_t new_triangle = {face.mIndices[0] + idx_offset,
                                                      face.mIndices[1] + idx_offset,
                                                      face.mIndices[2] + idx_offset};
                        request.mesh.triangles.push_back(new_triangle);

                        const btVector3 &v0 = request.mesh.vertices[new_triangle[0]];
                        const btVector3 &v1 = request.mesh.vertices[new_triangle[1]];
                        const btVector3 &v2 = request.mesh.vertices[new_triangle[2]];
                        request.mesh.edges.push_back({v1-v0, v2-v0});
                    }
                    idx_offset += mesh.mNumVertices;
                }

                bounding_box(request.mesh, bbox);
                world_size = bbox.second - bbox.first;
                std::cout << "Bounding box: " << bbox << std::endl;
                std::cout << "World size: " << world_size << std::endl;
                std::cout << "Vertex count: " << request.mesh.vertices.size() << std::endl;
                std::cout << "Triangle count: " << request.mesh.triangles.size() << std::endl;

                // Split the world evenly with boxes
                btScalar box_x_size = world_size.x() / N_BOX;
                btScalar box_y_size = world_size.y();
                btScalar box_z_size = world_size.z() / N_BOX;
                btScalar box_x_half_size = box_x_size / 2;
                btScalar box_y_half_size = box_y_size / 2;
                btScalar box_z_half_size = box_z_size / 2;
                for(size_t ix = 0; ix < N_BOX; ++ix)
                {
                    for(size_t iz = 0; iz < N_BOX; ++iz)
                    {
                        space_partition_t part =
                        {
                            std::make_pair(
                                btVector3( // box center
                                    box_x_size * ix + box_x_half_size,
                                    box_y_half_size,
                                    box_z_size * iz + box_z_half_size
                                ),
                                btVector3( // box half sizes
                                    box_x_half_size,
                                    box_y_half_size,
                                    box_z_half_size
                                )),
                                {} // placeholder for bounding triangle indexes
                        };
                        partitions.push_back(part);
                    }
                }

                // Calculate list of bounding triangles for each box
                size_t triangles_processed = 0;
                for(space_partition_t &part: partitions)
                {
                    size_t i = 0;
                    for(auto const &tri_indexes: request.mesh.triangles)
                    {
                        trianglevert_t verts = {
                            &request.mesh.vertices[tri_indexes[0]],
                            &request.mesh.vertices[tri_indexes[1]],
                            &request.mesh.vertices[tri_indexes[2]]
                        };
                        if(triboxoverlap(part.box.first, part.box.second, verts))
                        {
                            part.bounding_triangles.push_back(i);
                        }
                        ++i;
                    }
                    triangles_processed += part.bounding_triangles.size();
                    //std::cout << "Triangles in box:" << part.bounding_triangles.size() << std::endl;
                }
                std::cout << "Total triangles in boxes:" << triangles_processed << std::endl;
            }

            static const unsigned seed1 =
                unsigned(std::chrono::system_clock::now().time_since_epoch().count());
            std::default_random_engine generator(seed1);
            std::uniform_real_distribution<btScalar> random_uniform(0.0, 1.0);

            btVector4 location(1000, 0, 1000, 0);

            if(request.particles.empty())
            {
                request.particles.resize(N_PART);
                for(auto &particle: request.particles)
                {
                    particle.setX(random_uniform(generator) * world_size.x() + bbox.first.x());
                    particle.setY(random_uniform(generator) * 3 + bbox.first.y());
                    particle.setZ(random_uniform(generator) * world_size.z() + bbox.first.z());
                    particle.setW(random_uniform(generator) * M_2PI);

                    //particle.setX(random_gauss(location.x(), 500));
                    //particle.setY(random_gauss(location.y(), 500));
                    //particle.setZ(random_gauss(location.z(), 500));
                    //particle.setW(random_gauss(location.w(), M_PI_4));

                    //std::cout << particle.x() << "\t" << particle.y() << std::endl;
                }
            }

            std::array<btScalar, N_PART> weights;
            const btVector3 init_dir(1.0, 0.0, 0.0);
            //btScalar min_dist;
            btVector3 origin;
            btVector3 xpoint;

            request.measurements.resize(loc_request.measurements_size());
            int idx = 0;
            for(measurement_t &meas: request.measurements)
            {
                const particle::measurement &new_meas = loc_request.measurements(idx);
                meas.direction.setX(new_meas.direction().x());
                meas.direction.setY(new_meas.direction().y());
                meas.direction.setZ(new_meas.direction().z());

                meas.origin.setX(new_meas.origin().x());
                meas.origin.setY(new_meas.origin().y());
                meas.origin.setZ(new_meas.origin().z());

                meas.distance = new_meas.distance();

                ++idx;
            }

            // Measurement update
            size_t n = 0;
            for(const particle_t &particle: request.particles)
            {
                weights[n] = measurement_prob(partitions,
                                              request.mesh,
                                              particle,
                                              request.measurements,
                                              request.noise);
                //std::cout << weights[n] << std::endl;
                ++n;
            }

            // Normalization
            btScalar sum_weights = btScalar(0.0);
            for(const auto &w: weights)
                sum_weights += w;
            std::cout << "Sum(weights): " << sum_weights << std::endl;
            if(sum_weights > 0)
            {
                btScalar k = request.particles.size() / sum_weights;
                for(auto &w: weights)
                    w *= k;
            }

            // Resampling
            particle_vector_t p2(request.particles.size());
            particle_vector_t::size_type index =
                particle_vector_t::size_type(random_uniform(generator)
                                             * request.particles.size());
            btScalar beta = 0.0;
            const btScalar two_mw =
                btScalar(2.0) * (*std::max_element(weights.begin(), weights.end()));
            for(particle_vector_t::size_type i = 0; i < request.particles.size(); ++i)
            {
                beta += random_uniform(generator) * two_mw;
                while(beta > weights[index])
                {
                    beta -= weights[index];
                    index = (index + 1) % request.particles.size();
                }
                p2[i] = request.particles[index];
            }

            //for(const auto &p: p2) std::cout << p << std::endl;
            //std::cout << std::endl;

            particle_t est_pos;
            //get_position(request.particles, est_pos);
            get_position(p2, est_pos);
            std::cout << "** Estimated position: " << est_pos << std::endl;

            particle::vector4 *loc = response.mutable_location();
            loc->set_x(est_pos.x());
            loc->set_y(est_pos.y());
            loc->set_z(est_pos.z());
            loc->set_w(est_pos.w());

            //visualization(location, est_pos, step, particles, p2, weights)

            request.particles = p2;

            //std::cout << "======== " << step << " ========" << std::endl;

            // Motion update (prediction)
            for(auto &p: request.particles)
                move(p, request.motion, request.noise, p);

            location.setX(location.x() + 500);

            response.set_error(""); // No error
        }

        std::string buffer;
        ok = response.SerializeToString(&buffer);
        if(!ok)
        {
            std::cout << "Response serialization error" << std::endl;
            return;
        }

        // Search for client_id string in topic which is in format
        // /server_id/client_id/request
        // Answer should be sent to the topic
        // /server_id/client_id/response
        const std::string topic(message->topic);
        size_t first_slash = topic.rfind("/");
        size_t second_slash = topic.rfind("/", first_slash - 1);
        const std::string client_id = topic.substr(second_slash, first_slash - second_slash);
        const std::string publish_topic =
            std::string("/") + server_id + client_id
            + std::string("/response");
        std::cout << "Publish topic: " << publish_topic << std::endl;

        int mid = 0;
        int res = publish(&mid,
                          publish_topic.c_str(),
                          buffer.size(),
                          buffer.c_str());
        if(res)
            std::cerr << "Publish returned: " << res << " " << mosqpp::strerror(res) << std::endl;
        else
            std::cerr << "Publish message id: " << mid << std::endl;
    }

protected:
	request_t request;
    box_t bbox;
    btVector3 world_size;
    partition_vector_t partitions;
};

int main(int argc, char *argv[])
{
    // Verify that the version of the library that we linked against is
    // compatible with the version of the headers we compiled against.
    GOOGLE_PROTOBUF_VERIFY_VERSION;

	mosquitto_lib_init();

	ParticleServer server("server1");
    server.run();

	return 0;
}

<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

static void rename_in_module(RTLIL::Module *module, std::string from_name, std::string to_name)
{
	from_name = RTLIL::escape_id(from_name);
	to_name = RTLIL::escape_id(to_name);

	if (module->count_id(to_name))
		log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name.c_str(), module->name.c_str());

	for (auto &it : module->wires_)
		if (it.first == from_name) {
			Wire *w = it.second;
			log("Renaming wire %s to %s in module %s.\n", log_id(w), log_id(to_name), log_id(module));
			module->rename(w, to_name);
			if (w->port_id)
				module->fixup_ports();
			return;
		}

	for (auto &it : module->cells_)
		if (it.first == from_name) {
			log("Renaming cell %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module));
			module->rename(it.second, to_name);
			return;
		}

	log_cmd_error("Object `%s' not found!\n", from_name.c_str());
}

static std::string derive_name_from_src(const std::string &src, int counter)
{
	std::string src_base = src.substr(0, src.find('|'));
	if (src_base.empty())
		return stringf("$%d", counter);
	else
		return stringf("\\%s$%d", src_base.c_str(), counter);
}

static IdString derive_name_from_wire(const RTLIL::Cell &cell)
{
	// Find output
	const SigSpec *output = nullptr;
	int num_outputs = 0;
	for (auto &connection : cell.connections()) {
		if (cell.output(connection.first)) {
			output = &connection.second;
			num_outputs++;
		}
	}

	if (num_outputs != 1) // Skip cells thad drive multiple outputs
		return cell.name;

	std::string name = "";
	for (auto &chunk : output->chunks()) {
		// Skip cells that drive privately named wires
		if (!chunk.wire || chunk.wire->name.str()[0] == '$')
			return cell.name;

		if (name != "")
			name += "$";

		name += chunk.wire->name.str();
		if (chunk.wire->width != chunk.width) {
			name += "[";
			if (chunk.width != 1)
				name += std::to_string(chunk.offset + chunk.width) + ":";
			name += std::to_string(chunk.offset) + "]";
		}
	}

	return name + cell.type.str();
}

struct RenamePass : public Pass {
	RenamePass() : Pass("rename", "rename object in the design") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    rename old_name new_name\n");
		log("\n");
		log("Rename the specified object. Note that selection patterns are not supported\n");
		log("by this command.\n");
		log("\n");
		log("    rename -src [selection]\n");
		log("\n");
		log("Assign names auto-generated from the src attribute to all selected wires and\n");
		log("cells with private names.\n");
		log("\n");
		log("    rename -wire [selection]\n");
		log("Assign auto-generated names based on the wires they drive to all selected\n");
		log("cells with private names. Ignores cells driving privatly named wires.\n");
		log("\n");
		log("    rename -enumerate [-pattern <pattern>] [selection]\n");
		log("\n");
		log("Assign short auto-generated names to all selected wires and cells with private\n");
		log("names. The -pattern option can be used to set the pattern for the new names.\n");
		log("The character %% in the pattern is replaced with a integer number. The default\n");
		log("pattern is '_%%_'.\n");
		log("\n");
		log("    rename -hide [selection]\n");
		log("\n");
		log("Assign private names (the ones with $-prefix) to all selected wires and cells\n");
		log("with public names. This ignores all selected ports.\n");
		log("\n");
		log("    rename -top new_name\n");
		log("\n");
		log("Rename top module.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		std::string pattern_prefix = "_", pattern_suffix = "_";
		bool flag_src = false;
		bool flag_wire = false;
		bool flag_enumerate = false;
		bool flag_hide = false;
		bool flag_top = false;
		bool got_mode = false;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			std::string arg = args[argidx];
			if (arg == "-src" && !got_mode) {
				flag_src = true;
				got_mode = true;
				continue;
			}
			if (arg == "-wire" && !got_mode) {
				flag_wire = true;
				got_mode = true;
				continue;
			}
			if (arg == "-enumerate" && !got_mode) {
				flag_enumerate = true;
				got_mode = true;
				continue;
			}
			if (arg == "-hide" && !got_mode) {
				flag_hide = true;
				got_mode = true;
				continue;
			}
			if (arg == "-top" && !got_mode) {
				flag_top = true;
				got_mode = true;
				continue;
			}
			if (arg == "-pattern" && argidx+1 < args.size() && args[argidx+1].find('%') != std::string::npos) {
				int pos = args[++argidx].find('%');
				pattern_prefix = args[argidx].substr(0, pos);
				pattern_suffix = args[argidx].substr(pos+1);
				continue;
			}
			break;
		}

		if (flag_src)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				int counter = 0;

				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
				for (auto &it : module->wires_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						it.second->name = derive_name_from_src(it.second->get_src_attribute(), counter++);
					new_wires[it.second->name] = it.second;
				}
				module->wires_.swap(new_wires);
				module->fixup_ports();

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						it.second->name = derive_name_from_src(it.second->get_src_attribute(), counter++);
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_wire)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						it.second->name = derive_name_from_wire(*it.second);
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_enumerate)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				int counter = 0;

				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
				for (auto &it : module->wires_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
						while (module->count_id(it.second->name) > 0);
					new_wires[it.second->name] = it.second;
				}
				module->wires_.swap(new_wires);
				module->fixup_ports();

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
						while (module->count_id(it.second->name) > 0);
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_hide)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
				for (auto &it : module->wires_) {
					if (design->selected(module, it.second))
						if (it.first[0] == '\\' && it.second->port_id == 0)
							it.second->name = NEW_ID;
					new_wires[it.second->name] = it.second;
				}
				module->wires_.swap(new_wires);
				module->fixup_ports();

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (design->selected(module, it.second))
						if (it.first[0] == '\\')
							it.second->name = NEW_ID;
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_top)
		{
			if (argidx+1 != args.size())
				log_cmd_error("Invalid number of arguments!\n");

			IdString new_name = RTLIL::escape_id(args[argidx]);
			RTLIL::Module *module = design->top_module();

			if (module == NULL)
				log_cmd_error("No top module found!\n");

			log("Renaming module %s to %s.\n", log_id(module), log_id(new_name));
			design->rename(module, new_name);
		}
		else
		{
			if (argidx+2 != args.size())
				log_cmd_error("Invalid number of arguments!\n");

			std::string from_name = args[argidx++];
			std::string to_name = args[argidx++];

			if (!design->selected_active_module.empty())
			{
				if (design->modules_.count(design->selected_active_module) > 0)
					rename_in_module(design->modules_.at(design->selected_active_module), from_name, to_name);
			}
			else
			{
				for (auto &mod : design->modules_) {
					if (mod.first == from_name || RTLIL::unescape_id(mod.first) == from_name) {
						to_name = RTLIL::escape_id(to_name);
						log("Renaming module %s to %s.\n", mod.first.c_str(), to_name.c_str());
						RTLIL::Module *module = mod.second;
						design->modules_.erase(module->name);
						module->name = to_name;
						design->modules_[module->name] = module;
						goto rename_ok;
					}
				}

				log_cmd_error("Object `%s' not found!\n", from_name.c_str());
			rename_ok:;
			}
		}
	}
} RenamePass;

PRIVATE_NAMESPACE_END
<commit_msg>Improve "rename" help message<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

static void rename_in_module(RTLIL::Module *module, std::string from_name, std::string to_name)
{
	from_name = RTLIL::escape_id(from_name);
	to_name = RTLIL::escape_id(to_name);

	if (module->count_id(to_name))
		log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name.c_str(), module->name.c_str());

	for (auto &it : module->wires_)
		if (it.first == from_name) {
			Wire *w = it.second;
			log("Renaming wire %s to %s in module %s.\n", log_id(w), log_id(to_name), log_id(module));
			module->rename(w, to_name);
			if (w->port_id)
				module->fixup_ports();
			return;
		}

	for (auto &it : module->cells_)
		if (it.first == from_name) {
			log("Renaming cell %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module));
			module->rename(it.second, to_name);
			return;
		}

	log_cmd_error("Object `%s' not found!\n", from_name.c_str());
}

static std::string derive_name_from_src(const std::string &src, int counter)
{
	std::string src_base = src.substr(0, src.find('|'));
	if (src_base.empty())
		return stringf("$%d", counter);
	else
		return stringf("\\%s$%d", src_base.c_str(), counter);
}

static IdString derive_name_from_wire(const RTLIL::Cell &cell)
{
	// Find output
	const SigSpec *output = nullptr;
	int num_outputs = 0;
	for (auto &connection : cell.connections()) {
		if (cell.output(connection.first)) {
			output = &connection.second;
			num_outputs++;
		}
	}

	if (num_outputs != 1) // Skip cells thad drive multiple outputs
		return cell.name;

	std::string name = "";
	for (auto &chunk : output->chunks()) {
		// Skip cells that drive privately named wires
		if (!chunk.wire || chunk.wire->name.str()[0] == '$')
			return cell.name;

		if (name != "")
			name += "$";

		name += chunk.wire->name.str();
		if (chunk.wire->width != chunk.width) {
			name += "[";
			if (chunk.width != 1)
				name += std::to_string(chunk.offset + chunk.width) + ":";
			name += std::to_string(chunk.offset) + "]";
		}
	}

	return name + cell.type.str();
}

struct RenamePass : public Pass {
	RenamePass() : Pass("rename", "rename object in the design") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    rename old_name new_name\n");
		log("\n");
		log("Rename the specified object. Note that selection patterns are not supported\n");
		log("by this command.\n");
		log("\n");
		log("\n");
		log("    rename -src [selection]\n");
		log("\n");
		log("Assign names auto-generated from the src attribute to all selected wires and\n");
		log("cells with private names.\n");
		log("\n");
		log("\n");
		log("    rename -wire [selection]\n");
		log("\n");
		log("Assign auto-generated names based on the wires they drive to all selected\n");
		log("cells with private names. Ignores cells driving privatly named wires.\n");
		log("\n");
		log("\n");
		log("    rename -enumerate [-pattern <pattern>] [selection]\n");
		log("\n");
		log("Assign short auto-generated names to all selected wires and cells with private\n");
		log("names. The -pattern option can be used to set the pattern for the new names.\n");
		log("The character %% in the pattern is replaced with a integer number. The default\n");
		log("pattern is '_%%_'.\n");
		log("\n");
		log("\n");
		log("    rename -hide [selection]\n");
		log("\n");
		log("Assign private names (the ones with $-prefix) to all selected wires and cells\n");
		log("with public names. This ignores all selected ports.\n");
		log("\n");
		log("\n");
		log("    rename -top new_name\n");
		log("\n");
		log("Rename top module.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		std::string pattern_prefix = "_", pattern_suffix = "_";
		bool flag_src = false;
		bool flag_wire = false;
		bool flag_enumerate = false;
		bool flag_hide = false;
		bool flag_top = false;
		bool got_mode = false;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			std::string arg = args[argidx];
			if (arg == "-src" && !got_mode) {
				flag_src = true;
				got_mode = true;
				continue;
			}
			if (arg == "-wire" && !got_mode) {
				flag_wire = true;
				got_mode = true;
				continue;
			}
			if (arg == "-enumerate" && !got_mode) {
				flag_enumerate = true;
				got_mode = true;
				continue;
			}
			if (arg == "-hide" && !got_mode) {
				flag_hide = true;
				got_mode = true;
				continue;
			}
			if (arg == "-top" && !got_mode) {
				flag_top = true;
				got_mode = true;
				continue;
			}
			if (arg == "-pattern" && argidx+1 < args.size() && args[argidx+1].find('%') != std::string::npos) {
				int pos = args[++argidx].find('%');
				pattern_prefix = args[argidx].substr(0, pos);
				pattern_suffix = args[argidx].substr(pos+1);
				continue;
			}
			break;
		}

		if (flag_src)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				int counter = 0;

				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
				for (auto &it : module->wires_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						it.second->name = derive_name_from_src(it.second->get_src_attribute(), counter++);
					new_wires[it.second->name] = it.second;
				}
				module->wires_.swap(new_wires);
				module->fixup_ports();

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						it.second->name = derive_name_from_src(it.second->get_src_attribute(), counter++);
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_wire)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						it.second->name = derive_name_from_wire(*it.second);
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_enumerate)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				int counter = 0;

				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
				for (auto &it : module->wires_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
						while (module->count_id(it.second->name) > 0);
					new_wires[it.second->name] = it.second;
				}
				module->wires_.swap(new_wires);
				module->fixup_ports();

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (it.first[0] == '$' && design->selected(module, it.second))
						do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
						while (module->count_id(it.second->name) > 0);
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_hide)
		{
			extra_args(args, argidx, design);

			for (auto &mod : design->modules_)
			{
				RTLIL::Module *module = mod.second;
				if (!design->selected(module))
					continue;

				dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
				for (auto &it : module->wires_) {
					if (design->selected(module, it.second))
						if (it.first[0] == '\\' && it.second->port_id == 0)
							it.second->name = NEW_ID;
					new_wires[it.second->name] = it.second;
				}
				module->wires_.swap(new_wires);
				module->fixup_ports();

				dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
				for (auto &it : module->cells_) {
					if (design->selected(module, it.second))
						if (it.first[0] == '\\')
							it.second->name = NEW_ID;
					new_cells[it.second->name] = it.second;
				}
				module->cells_.swap(new_cells);
			}
		}
		else
		if (flag_top)
		{
			if (argidx+1 != args.size())
				log_cmd_error("Invalid number of arguments!\n");

			IdString new_name = RTLIL::escape_id(args[argidx]);
			RTLIL::Module *module = design->top_module();

			if (module == NULL)
				log_cmd_error("No top module found!\n");

			log("Renaming module %s to %s.\n", log_id(module), log_id(new_name));
			design->rename(module, new_name);
		}
		else
		{
			if (argidx+2 != args.size())
				log_cmd_error("Invalid number of arguments!\n");

			std::string from_name = args[argidx++];
			std::string to_name = args[argidx++];

			if (!design->selected_active_module.empty())
			{
				if (design->modules_.count(design->selected_active_module) > 0)
					rename_in_module(design->modules_.at(design->selected_active_module), from_name, to_name);
			}
			else
			{
				for (auto &mod : design->modules_) {
					if (mod.first == from_name || RTLIL::unescape_id(mod.first) == from_name) {
						to_name = RTLIL::escape_id(to_name);
						log("Renaming module %s to %s.\n", mod.first.c_str(), to_name.c_str());
						RTLIL::Module *module = mod.second;
						design->modules_.erase(module->name);
						module->name = to_name;
						design->modules_[module->name] = module;
						goto rename_ok;
					}
				}

				log_cmd_error("Object `%s' not found!\n", from_name.c_str());
			rename_ok:;
			}
		}
	}
} RenamePass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>#include <tiramisu/tiramisu.h>
#define SCHEDULE_CPU 1

using namespace tiramisu;

int main(int argc, char **argv)
{
    init("vgg_block");

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------
    function vgg_block("vgg_block_tiramisu");

    // parameters
    // N: parameters[0]
    // K: parameters[1]
    // FIn: parameters[2]
    // FOut: parameters[3]
    // BATCH_SIZE: parameters[4]
    var i("i", 0, 5);
    input parameters("parameters",{i}, p_int32);

    constant C_N0("C_N0", parameters(0)+parameters(1));
    constant C_N("C_N", parameters(0));
    constant C_N1("C_N1", parameters(0)-parameters(1));
    constant C_N2("C_N2", parameters(0)-parameters(1)-parameters(1));
    constant C_K("C_K", parameters(1)+expr(1));
    constant C_FIn("C_FIn", parameters(2));
    constant C_FOut("C_FOut", parameters(3));
    constant C_BATCH_SIZE("C_BATCH_SIZE", parameters(4));

    var z1("z1", 0, C_FOut), k_x("k_x",0,C_K), k_y("k_y",0,C_K), k_z("k_z",0,C_FIn); // filter variables
    var x("x", 0, C_N0 ), y("y", 0, C_N0),  z("z", 0, C_FOut), n("n", 0, C_BATCH_SIZE ); // input
    var x1("x1", 0, C_N), y1("y1", 0, C_N); // conv
    var x2("x2", 0, C_N1), y2("y2", 0, C_N1); // conv2
    var x3("x3", 0, C_N2), y3("y3", 0, C_N2); // maxpool

    // Input computations
    input c_input("c_input",{n, z, y, x} , p_float32);
    input bias("bias", {z1}, p_float32);
    input filter("filter", {z1, k_z , k_y, k_x}, p_float32);
    input bias2("bias2", {z1}, p_float32);
    input filter2("filter2", {z1, k_z, k_y, k_x}, p_float32);

    // First conv computations
    computation conv_init("conv_init",{n, z, y1, x1}, bias(z) );
    computation conv("conv",{n, z, y1, x1, k_z, k_y, k_x }, conv_init(n, z, y1, x1) + filter(z, k_z, k_y, k_x) * c_input(n, k_z, y1 + k_y, x1 + k_x));

    //first relu
    computation relu("relu",{n, z, y1, x1}, tiramisu::expr(tiramisu::o_max,conv(n, z, y1, x1, 0, 0, 0), expr((float) 0)  ));

    // Second conv computations
    computation conv2_init("conv2_init",{n, z, y2, x2}, bias2(z) );
    computation conv2("conv2",{n, z, y2, x2, k_z, k_y, k_x }, conv2_init(n, z, y2, x2) + filter(z, k_z, k_y, k_x) * relu(n, k_z, y2 + k_y, x2 + k_x));

    //second relu
    computation relu2("relu2",{n, z, y2, x2}, tiramisu::expr(tiramisu::o_max,conv2(n, z, y2, x2, 0, 0, 0), expr((float) 0) ));

    //maxpooling computation
    computation maxpool_init("maxpool_init",{n, z, y3, x3}, expr((float) -2147483647));
    computation maxpool("maxpool",{n, z, y3, x3,k_y, k_x }, expr(o_max, maxpool_init(n, z, y3, x3),relu2(n, z, y3 + k_y, x3 + k_x)));

    // Layer II

    int vec_len , y_block , o_block ;

    vec_len = 16;
    y_block = 8;
    o_block = 4;

    conv_init.tag_parallel_level(0);
    conv.after(conv_init, 2);

    // 0, 1,   2,   3,   4,   5,     6,
    // n, z,   y,   x, r_z, r_y,   r_x,
    conv.interchange(3, 4);
    // n, z,   y, (r_z,   x), r_y,   r_x,
    conv.interchange(3, 2);
    // n, z, (r_z,   y),   x, r_y,   r_x,

    conv.split(1, o_block);
    conv_init.split(1, o_block);
    // n, (z, z_t), r_z,   y,       x, r_y,   r_x,

    conv.split(3, y_block);
    conv.split(6, vec_len);
    conv.tag_vector_level(7, vec_len);

    // n,  z, z_t,  r_z,  (y, y_t), x, r_y,   r_x,
    conv_init.split(4, vec_len);
    conv_init.tag_vector_level(5, vec_len);

    // Order between the first and second convolutions
    relu.after(conv, tiramisu::computation::root_dimension);
    conv2_init.after(relu, tiramisu::computation::root_dimension);

    // Schedule of 2nd convolution
    conv2_init.tag_parallel_level(0);
    conv2.after(conv2_init, 2);
    relu2.after(conv2,2);

    // Schedule of maxpooling
    maxpool_init.after(relu2, tiramisu::computation::root_dimension);
    maxpool.after(maxpool_init, tiramisu::computation::root_dimension);

    // Layer III
    buffer parameters_buf("parameters_buf", {expr(5)}, p_int32, a_input);
    buffer input_buf("input_buf", {expr(C_BATCH_SIZE), expr(C_FIn), expr(C_N0), expr(C_N0)}, p_float32, a_input);
    buffer conv_buf("conv_buf", {expr(C_BATCH_SIZE), expr(C_FOut), expr(C_N), expr(C_N)}, p_float32, a_output);
    buffer filter_buf("filter_buf", {expr(C_FOut), expr(C_FIn), expr(C_K), expr(C_K)}, p_float32, a_input);
    buffer bias_buf("bias_buf", {expr(C_FOut)}, p_float32, a_input);
    buffer conv2_buf("conv2_buf", {expr(C_BATCH_SIZE), expr(C_FOut), expr(C_N1), expr(C_N1)}, p_float32, a_output);
    buffer bias2_buf("bias2_buf", {expr(C_FOut)}, p_float32, a_input);
    buffer filter2_buf("filter2_buf", {expr(C_FOut), expr(C_FIn), expr(C_K), expr(C_K)}, p_float32, a_input);
    buffer maxpool_buf("maxpool_buf", {expr(C_BATCH_SIZE), expr(C_FOut), expr(C_N2), expr(C_N2)}, p_float32, a_output);

    parameters.store_in(&parameters_buf);
    c_input.store_in(&input_buf);

    bias.store_in(&bias_buf);
    filter.store_in(&filter_buf);
    conv_init.store_in(&conv_buf);
    conv.store_in(&conv_buf,{n, z, y1, x1});
    relu.store_in(&conv_buf);

    bias2.store_in(&bias2_buf);
    filter2.store_in(&filter2_buf);
    conv2_init.store_in(&conv2_buf);
    conv2.store_in(&conv2_buf,{n, z, y2, x2});
    relu2.store_in(&conv2_buf);

    maxpool_init.store_in(&maxpool_buf);
    maxpool.store_in(&maxpool_buf,{n, z, y3, x3});

    tiramisu::codegen({&parameters_buf, &input_buf, &filter_buf, &bias_buf, &conv_buf, &filter2_buf, &bias2_buf, &conv2_buf,&maxpool_buf}, "generated_vgg_block.o");

    return 0;
}
<commit_msg>Update vgg_block_generator_tiramisu.cpp<commit_after>#include <tiramisu/tiramisu.h>
#define SCHEDULE_CPU 1

using namespace tiramisu;

int main(int argc, char **argv)
{
    init("vgg_block");

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------
    // parameters
    // N: parameters[0]
    // K: parameters[1]
    // FIn: parameters[2]
    // FOut: parameters[3]
    // BATCH_SIZE: parameters[4]
    var i("i", 0, 5);
    input parameters("parameters",{i}, p_int32);

    constant C_N0("C_N0", parameters(0)+parameters(1));
    constant C_N("C_N", parameters(0));
    constant C_N1("C_N1", parameters(0)-parameters(1));
    constant C_N2("C_N2", parameters(0)-parameters(1)-parameters(1));
    constant C_K("C_K", parameters(1)+expr(1));
    constant C_FIn("C_FIn", parameters(2));
    constant C_FOut("C_FOut", parameters(3));
    constant C_BATCH_SIZE("C_BATCH_SIZE", parameters(4));

    var z1("z1", 0, C_FOut), k_x("k_x",0,C_K), k_y("k_y",0,C_K), k_z("k_z",0,C_FIn); // filter variables
    var x("x", 0, C_N0 ), y("y", 0, C_N0),  z("z", 0, C_FOut), n("n", 0, C_BATCH_SIZE ); // input
    var x1("x1", 0, C_N), y1("y1", 0, C_N); // conv
    var x2("x2", 0, C_N1), y2("y2", 0, C_N1); // conv2
    var x3("x3", 0, C_N2), y3("y3", 0, C_N2); // maxpool

    // Input computations
    input c_input("c_input",{n, z, y, x} , p_float32);
    input bias("bias", {z1}, p_float32);
    input filter("filter", {z1, k_z , k_y, k_x}, p_float32);
    input bias2("bias2", {z1}, p_float32);
    input filter2("filter2", {z1, k_z, k_y, k_x}, p_float32);

    // First conv computations
    computation conv_init("conv_init",{n, z, y1, x1}, bias(z) );
    computation conv("conv",{n, z, y1, x1, k_z, k_y, k_x }, conv_init(n, z, y1, x1) + filter(z, k_z, k_y, k_x) * c_input(n, k_z, y1 + k_y, x1 + k_x));

    //first relu
    computation relu("relu",{n, z, y1, x1}, tiramisu::expr(tiramisu::o_max,conv(n, z, y1, x1, 0, 0, 0), expr((float) 0)  ));

    // Second conv computations
    computation conv2_init("conv2_init",{n, z, y2, x2}, bias2(z) );
    computation conv2("conv2",{n, z, y2, x2, k_z, k_y, k_x }, conv2_init(n, z, y2, x2) + filter(z, k_z, k_y, k_x) * relu(n, k_z, y2 + k_y, x2 + k_x));

    //second relu
    computation relu2("relu2",{n, z, y2, x2}, tiramisu::expr(tiramisu::o_max,conv2(n, z, y2, x2, 0, 0, 0), expr((float) 0) ));

    //maxpooling computation
    computation maxpool_init("maxpool_init",{n, z, y3, x3}, expr((float) -2147483647));
    computation maxpool("maxpool",{n, z, y3, x3,k_y, k_x }, expr(o_max, maxpool_init(n, z, y3, x3),relu2(n, z, y3 + k_y, x3 + k_x)));

    // Layer II

    int vec_len , y_block , o_block ;

    vec_len = 16;
    y_block = 8;
    o_block = 4;

    conv_init.tag_parallel_level(0);
    conv.after(conv_init, 2);

    // 0, 1,   2,   3,   4,   5,     6,
    // n, z,   y,   x, r_z, r_y,   r_x,
    conv.interchange(3, 4);
    // n, z,   y, (r_z,   x), r_y,   r_x,
    conv.interchange(3, 2);
    // n, z, (r_z,   y),   x, r_y,   r_x,

    conv.split(1, o_block);
    conv_init.split(1, o_block);
    // n, (z, z_t), r_z,   y,       x, r_y,   r_x,

    conv.split(3, y_block);
    conv.split(6, vec_len);
    conv.tag_vector_level(7, vec_len);

    // n,  z, z_t,  r_z,  (y, y_t), x, r_y,   r_x,
    conv_init.split(4, vec_len);
    conv_init.tag_vector_level(5, vec_len);

    // Order between the first and second convolutions
    relu.after(conv, tiramisu::computation::root_dimension);
    conv2_init.after(relu, tiramisu::computation::root_dimension);

    // Schedule of 2nd convolution
    conv2_init.tag_parallel_level(0);
    conv2.after(conv2_init, 2);
    relu2.after(conv2,2);

    // Schedule of maxpooling
    maxpool_init.after(relu2, tiramisu::computation::root_dimension);
    maxpool.after(maxpool_init, tiramisu::computation::root_dimension);

    // Layer III
    buffer parameters_buf("parameters_buf", {expr(5)}, p_int32, a_input);
    buffer input_buf("input_buf", {expr(C_BATCH_SIZE), expr(C_FIn), expr(C_N0), expr(C_N0)}, p_float32, a_input);
    buffer conv_buf("conv_buf", {expr(C_BATCH_SIZE), expr(C_FOut), expr(C_N), expr(C_N)}, p_float32, a_output);
    buffer filter_buf("filter_buf", {expr(C_FOut), expr(C_FIn), expr(C_K), expr(C_K)}, p_float32, a_input);
    buffer bias_buf("bias_buf", {expr(C_FOut)}, p_float32, a_input);
    buffer conv2_buf("conv2_buf", {expr(C_BATCH_SIZE), expr(C_FOut), expr(C_N1), expr(C_N1)}, p_float32, a_output);
    buffer bias2_buf("bias2_buf", {expr(C_FOut)}, p_float32, a_input);
    buffer filter2_buf("filter2_buf", {expr(C_FOut), expr(C_FIn), expr(C_K), expr(C_K)}, p_float32, a_input);
    buffer maxpool_buf("maxpool_buf", {expr(C_BATCH_SIZE), expr(C_FOut), expr(C_N2), expr(C_N2)}, p_float32, a_output);

    parameters.store_in(&parameters_buf);
    c_input.store_in(&input_buf);

    bias.store_in(&bias_buf);
    filter.store_in(&filter_buf);
    conv_init.store_in(&conv_buf);
    conv.store_in(&conv_buf,{n, z, y1, x1});
    relu.store_in(&conv_buf);

    bias2.store_in(&bias2_buf);
    filter2.store_in(&filter2_buf);
    conv2_init.store_in(&conv2_buf);
    conv2.store_in(&conv2_buf,{n, z, y2, x2});
    relu2.store_in(&conv2_buf);

    maxpool_init.store_in(&maxpool_buf);
    maxpool.store_in(&maxpool_buf,{n, z, y3, x3});

    tiramisu::codegen({&parameters_buf, &input_buf, &filter_buf, &bias_buf, &conv_buf, &filter2_buf, &bias2_buf, &conv2_buf,&maxpool_buf}, "generated_vgg_block.o");

    return 0;
}
<|endoftext|>


<commit_before>#ifndef _COCONUT_PULP_FILE_IO_SERIALISER_HPP_
#define _COCONUT_PULP_FILE_IO_SERIALISER_HPP_

#include <string>
#include <vector>
#include <cstddef>

namespace coconut {
namespace pulp {
namespace file_io {

class Serialiser {
public:

	struct Read {
	} constexpr read;

	struct Write {
	} constexpr write;

	template <class T>
	struct LabelledValue {

		LabelledValue(const std::string& label, const T& value) : // value to universal ref or boost::call_traits
			label(label),
			value(value)
		{
		}

		const std::string& label;

		const T& value;

	};

	virtual ~Serialiser() = default;

	template <class T>
	static LabelledValue<T> labelled(const std::string& label, const T& value) {
		return LabelledValue<T>(label, value);
	}

	template <class T>
	Serialiser& operator<<(const T& value) {
		writeObjectStart();
		serialise(*this, value);
		writeObjectEnd();
		return *this;
	}

	template <class T>
	Serialiser& operator<<(const LabelledValue<T>& labelledValue) {
		writeLabel(labelledValue.label);
		*this << labelledValue.value;
		return *this;
	}

	template <class T>
	Serialiser& operator<<(const std::vector<T>& vector) {
		// TODO: verify array not larger than max uint32_t
		writeArrayStart(static_cast<std::uint32_t>(vector.size()));
		for (const auto& element : vector) {
			*this << element;
		}
		writeArrayEnd();
		return *this;
	}

	Serialiser& operator<<(std::uint8_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int8_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::uint16_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int16_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::uint32_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int32_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::uint64_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int64_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(float f) {
		write(f);
		return *this;
	}

	Serialiser& operator<<(const char* s) {
		write(std::string(s));
		return *this;
	}

	Serialiser& operator<<(const std::string& s) {
		write(s);
		return *this;
	}

protected:

	Serialiser(Read) :
		writing_(false)
	{
	}

	Serialiser(Write) :
		writing_(true)
	{
	}

	virtual void writeObjectStart() = 0;

	virtual void writeObjectEnd() = 0;

	virtual void writeArrayStart(std::uint32_t elementCount) = 0;

	virtual void writeArrayEnd() = 0;

	virtual void writeLabel(const std::string& label) = 0;

	virtual void write(std::uint8_t i) = 0;

	virtual void write(std::int8_t i) = 0;

	virtual void write(std::uint16_t i) = 0;

	virtual void write(std::int16_t i) = 0;

	virtual void write(std::uint32_t i) = 0;

	virtual void write(std::int32_t i) = 0;

	virtual void write(std::uint64_t i) = 0;

	virtual void write(std::int64_t i) = 0;

	virtual void write(float f) = 0;

	virtual void write(const std::string& s) = 0;

private:

	Serialiser(const Serialiser&) = delete;

	void operator=(const Serialiser&) = delete;

	bool writing_;

};

} // namespace file_io
} // namespace pulp
} // namespace coconut

#endif /* _COCONUT_PULP_FILE_IO_SERIALISER_HPP_ */
<commit_msg>WIP - deserialising functions<commit_after>#ifndef _COCONUT_PULP_FILE_IO_SERIALISER_HPP_
#define _COCONUT_PULP_FILE_IO_SERIALISER_HPP_

#include <string>
#include <vector>
#include <cstddef>

namespace coconut {
namespace pulp {
namespace file_io {

class Serialiser {
public:

	struct Read {
	} constexpr read;

	struct Write {
	} constexpr write;

	template <class T>
	struct LabelledValue {

		LabelledValue(const std::string& label, const T& value) : // value to universal ref or boost::call_traits
			label(label),
			value(value)
		{
		}

		const std::string& label;

		const T& value;

	};

	virtual ~Serialiser() = default;

	template <class T>
	static LabelledValue<T> labelled(const std::string& label, const T& value) {
		return LabelledValue<T>(label, value);
	}

	template <class T>
	Serialiser& operator<<(const T& value) {
		writeObjectStart();
		serialise(*this, value);
		writeObjectEnd();
		return *this;
	}

	template <class T>
	Serialiser& operator<<(const LabelledValue<T>& labelledValue) {
		writeLabel(labelledValue.label);
		*this << labelledValue.value;
		return *this;
	}

	template <class T>
	Serialiser& operator<<(const std::vector<T>& vector) {
		// TODO: verify array not larger than max uint32_t
		writeArrayStart(static_cast<std::uint32_t>(vector.size()));
		for (const auto& element : vector) {
			*this << element;
		}
		writeArrayEnd();
		return *this;
	}

	Serialiser& operator<<(std::uint8_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int8_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::uint16_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int16_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::uint32_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int32_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::uint64_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(std::int64_t i) {
		write(i);
		return *this;
	}

	Serialiser& operator<<(float f) {
		write(f);
		return *this;
	}

	Serialiser& operator<<(const char* s) {
		write(std::string(s));
		return *this;
	}

	Serialiser& operator<<(const std::string& s) {
		write(s);
		return *this;
	}

	template <class T>
	Serialiser& operator>>(T& value) {
		readObjectStart();
		serialise(*this, value);
		readObjectEnd();
		return *this;
	}

	template <class T>
	Serialiser& operator>>(LabelledValue<T>& labelledValue) {
		readLabel(labelledValue.label);
		*this >> labelledValue.value;
		return *this;
	}

	template <class T>
	Serialiser& operator>>(std::vector<T>& vector) {
		// TODO: verify array not larger than max uint32_t
		readArrayStart(static_cast<std::uint32_t>(vector.size()));
		for (const auto& element : vector) {
			*this >> element;
		}
		readArrayEnd();
		return *this;
	}

	// TODO: make this a template accepting all integral types
	Serialiser& operator>>(std::uint8_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::int8_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::uint16_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::int16_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::uint32_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::int32_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::uint64_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(std::int64_t& i) {
		read(i);
		return *this;
	}

	Serialiser& operator>>(float& f) {
		read(f);
		return *this;
	}

	Serialiser& operator>>(std::string& s) {
		read(std::string(s));
		return *this;
	}

	template <class T>
	Serialiser& operator()(T& value) {
		if (writing_) {
			*this << value;
		}
		else {
			*this >> value;
		}

		return *this;
	}

protected:

	Serialiser(Read) :
		writing_(false)
	{
	}

	Serialiser(Write) :
		writing_(true)
	{
	}

	virtual void writeObjectStart() = 0;

	virtual void writeObjectEnd() = 0;

	virtual void writeArrayStart(std::uint32_t elementCount) = 0;

	virtual void writeArrayEnd() = 0;

	virtual void writeLabel(const std::string& label) = 0;

	virtual void write(std::uint8_t i) = 0;

	virtual void write(std::int8_t i) = 0;

	virtual void write(std::uint16_t i) = 0;

	virtual void write(std::int16_t i) = 0;

	virtual void write(std::uint32_t i) = 0;

	virtual void write(std::int32_t i) = 0;

	virtual void write(std::uint64_t i) = 0;

	virtual void write(std::int64_t i) = 0;

	virtual void write(float f) = 0;

	virtual void write(const std::string& s) = 0;

	virtual void readObjectStart() = 0;

	virtual void readObjectEnd() = 0;

	virtual void readArrayStart(std::uint32_t elementCount) = 0;

	virtual void readArrayEnd() = 0;

	virtual void readLabel(std::string& label) = 0;

	virtual void read(std::uint8_t& i) = 0;

	virtual void read(std::int8_t& i) = 0;

	virtual void read(std::uint16_t& i) = 0;

	virtual void read(std::int16_t& i) = 0;

	virtual void read(std::uint32_t& i) = 0;

	virtual void read(std::int32_t& i) = 0;

	virtual void read(std::uint64_t& i) = 0;

	virtual void read(std::int64_t& i) = 0;

	virtual void read(float& f) = 0;

	virtual void read(std::string& s) = 0;

private:

	Serialiser(const Serialiser&) = delete;

	void operator=(const Serialiser&) = delete;

	bool writing_;

};

} // namespace file_io
} // namespace pulp
} // namespace coconut

#endif /* _COCONUT_PULP_FILE_IO_SERIALISER_HPP_ */
<|endoftext|>


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

#include <optional>
#include <vector>

namespace principia {
namespace physics {
namespace internal_protector {

bool Protector::RunWhenUnprotected(Instant const& t, Callback callback) {
  {
    absl::MutexLock l(&lock_);
    if (!protection_start_times_.empty() &&
        *protection_start_times_.begin() < t) {
      callbacks_.emplace(t, std::move(callback));
      return false;
    }
  }
  callback();
  return true;
}

void Protector::Protect(Instant const& t_min) {
  absl::MutexLock l(&lock_);
  protection_start_times_.insert(t_min);
}

void Protector::Unprotect(Instant const& t_min) {
  std::vector<Callback> callbacks_to_run;
  {
    absl::MutexLock l(&lock_);
    CHECK_EQ(1, protection_start_times_.erase(t_min));

    // Find all the callbacks that are now unprotected and remove them from the
    // multimap.
    std::optional<Instant> const first_guard_start_time =
        protection_start_times_.empty()
            ? std::nullopt
            : std::make_optional(*protection_start_times_.begin());
    for (auto it = callbacks_.begin(); it != callbacks_.end();) {
      auto const& t = it->first;
      auto& callback = it->second;
      if (!first_guard_start_time || t <= *first_guard_start_time) {
        callbacks_to_run.emplace_back(std::move(callback));
        it = callbacks_.erase(it);
      } else {
        ++it;
      }
    }
  }

  // Run the callbacks without holding the lock.
  for (auto const& callback : callbacks_to_run) {
    callback();
  }
}

}  // namespace internal_protector
}  // namespace physics
}  // namespace principia
<commit_msg>Proper usage of the multiset container.<commit_after>
#include "physics/protector.hpp"

#include <optional>
#include <vector>

namespace principia {
namespace physics {
namespace internal_protector {

bool Protector::RunWhenUnprotected(Instant const& t, Callback callback) {
  {
    absl::MutexLock l(&lock_);
    if (!protection_start_times_.empty() &&
        *protection_start_times_.begin() < t) {
      callbacks_.emplace(t, std::move(callback));
      return false;
    }
  }
  callback();
  return true;
}

void Protector::Protect(Instant const& t_min) {
  absl::MutexLock l(&lock_);
  protection_start_times_.insert(t_min);
}

void Protector::Unprotect(Instant const& t_min) {
  std::vector<Callback> callbacks_to_run;
  {
    absl::MutexLock l(&lock_);
    auto const it = protection_start_times_.find(t_min);
    CHECK(it != protection_start_times_.end());
    protection_start_times_.erase(it);

    // Find all the callbacks that are now unprotected and remove them from the
    // multimap.
    std::optional<Instant> const first_guard_start_time =
        protection_start_times_.empty()
            ? std::nullopt
            : std::make_optional(*protection_start_times_.begin());
    for (auto it = callbacks_.begin(); it != callbacks_.end();) {
      auto const& t = it->first;
      auto& callback = it->second;
      if (!first_guard_start_time || t <= *first_guard_start_time) {
        callbacks_to_run.emplace_back(std::move(callback));
        it = callbacks_.erase(it);
      } else {
        ++it;
      }
    }
  }

  // Run the callbacks without holding the lock.
  for (auto const& callback : callbacks_to_run) {
    callback();
  }
}

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


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "MumbleLibrary.h"
#include "MumbleMainLoopThread.h"
#define BUILDING_DLL // for dll import/export declarations
#define CreateEvent  CreateEventW // for \boost\asio\detail\win_event.hpp and \boost\asio\detail\win_iocp_handle_service.hpp
#include <mumbleclient/client_lib.h>
#undef BUILDING_DLL // for dll import/export declarations

#include "MemoryLeakCheck.h"

namespace MumbleLib
{
    QString MumbleLibrary::reason_ = "";
    MumbleMainLoopThread* MumbleLibrary::mumble_main_loop_ = 0;

    void MumbleLibrary::Start()
    {
        StartMumbleThread();
        //emit Started();
    }

    void MumbleLibrary::Stop()
    {
        StopMumbleThread();
//        emit Stoped();
    }

    bool MumbleLibrary::IsRunning()
    {
        if (!mumble_main_loop_)
            return false;
        return mumble_main_loop_->isRunning();
    }

    QString MumbleLibrary::Reason()
    {
        return reason_;
    }

    void MumbleLibrary::StartMumbleThread()
    {
        if (!mumble_main_loop_)
        {
            mumble_main_loop_ = new MumbleMainLoopThread();
        }

        if (mumble_main_loop_->isRunning())
            return;

        //! @todo
        //connect(lib_mumble_thread_, SIGNAL(finished()), SLOT(MumbleThreadFinished()) );
        //connect(lib_mumble_thread_, SIGNAL(terminated()), SLOT(MumbleThreadFinished()) );

        mumble_main_loop_->start();
        mumble_main_loop_->setPriority(QThread::LowPriority);
    }

    void MumbleLibrary::StopMumbleThread()
    {
        if (!mumble_main_loop_)
            return;

        MumbleClient::MumbleClientLib* mumble_lib = MumbleClient::MumbleClientLib::instance();
        if (!mumble_lib)
            return;

        mumble_lib->Shutdown();
        mumble_main_loop_->wait();
        SAFE_DELETE(mumble_main_loop_);
    }

    QThread* MumbleLibrary::MainLoopThread()
    {
        return mumble_main_loop_;
    }

} // MumbleLib
<commit_msg>Changed libmumbleclient log level from LOG_INFO to LOG_WARNING.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "MumbleLibrary.h"
#include "MumbleMainLoopThread.h"
#define BUILDING_DLL // for dll import/export declarations
#define CreateEvent  CreateEventW // for \boost\asio\detail\win_event.hpp and \boost\asio\detail\win_iocp_handle_service.hpp
#include <mumbleclient/client_lib.h>
#include <mumbleclient/logging.h>
#undef BUILDING_DLL // for dll import/export declarations

#include "MemoryLeakCheck.h"

namespace MumbleLib
{
    QString MumbleLibrary::reason_ = "";
    MumbleMainLoopThread* MumbleLibrary::mumble_main_loop_ = 0;

    void MumbleLibrary::Start()
    {
        MumbleClient::logging::SetLogLevel(MumbleClient::logging::LOG_WARNING);
        StartMumbleThread();
        //emit Started();
    }

    void MumbleLibrary::Stop()
    {
        StopMumbleThread();
//        emit Stoped();
    }

    bool MumbleLibrary::IsRunning()
    {
        if (!mumble_main_loop_)
            return false;
        return mumble_main_loop_->isRunning();
    }

    QString MumbleLibrary::Reason()
    {
        return reason_;
    }

    void MumbleLibrary::StartMumbleThread()
    {

        if (!mumble_main_loop_)
        {
            mumble_main_loop_ = new MumbleMainLoopThread();
        }

        if (mumble_main_loop_->isRunning())
            return;

        //! @todo
        //connect(lib_mumble_thread_, SIGNAL(finished()), SLOT(MumbleThreadFinished()) );
        //connect(lib_mumble_thread_, SIGNAL(terminated()), SLOT(MumbleThreadFinished()) );

        mumble_main_loop_->start();
        mumble_main_loop_->setPriority(QThread::LowPriority);
    }

    void MumbleLibrary::StopMumbleThread()
    {
        if (!mumble_main_loop_)
            return;

        MumbleClient::MumbleClientLib* mumble_lib = MumbleClient::MumbleClientLib::instance();
        if (!mumble_lib)
            return;

        mumble_lib->Shutdown();
        mumble_main_loop_->wait();
        SAFE_DELETE(mumble_main_loop_);
    }

    QThread* MumbleLibrary::MainLoopThread()
    {
        return mumble_main_loop_;
    }

} // MumbleLib
<|endoftext|>


<commit_before>#include "Enemy.h"
#include "Map.h"
#include "ParticleEmitter.h"
#include "Common.h"

#include "Logger.h"

////////////////////////////////////////////////////////////////////////////////
// EnemyType static methods
////////////////////////////////////////////////////////////////////////////////

EnemyType* EnemyType::getById(int id) {
	if (!idInUse(id)) {
		CORE_WARN("getById: id not in use! (%d)", id);
		return getDefaultType();
	}
	return &_types[id];
}

bool EnemyType::idInUse(unsigned int id) {
	return id < _types.size();
}

int EnemyType::createEnemyType(int id, const std::string& name, int sides,
	Stats defStats, Stats levelDiff) {

	// If the id is already in use try to use the next one
	if (idInUse(id)) {
		CORE_WARN("CreateEnemyType: id %d is already in use!", id);
		CORE_WARN("Trying to use %d to create", id + 1);
		return createEnemyType(++id, name, sides, defStats, levelDiff);
	}

	_types.push_back(EnemyType(id, name, sides, defStats, levelDiff));

	return id;
}

EnemyType* EnemyType::getDefaultType() {
	return &_defaultType;
}

////////////////////////////////////////////////////////////////////////////////
// EnemyType static vars
////////////////////////////////////////////////////////////////////////////////

std::vector<EnemyType> EnemyType::_types;
EnemyType EnemyType::_defaultType(0, "DEFAULT", 4, Stats(), Stats());

///////////////////////////////////////////////////////////////////////////////
// Constuctor and deconstrctor
///////////////////////////////////////////////////////////////////////////////

EnemyType::EnemyType(int id, const std::string& name, int sides,
		Stats defStats, Stats levelDiff)
	: _id(id), _name(name), _sides(sides), _defaultStats(defStats),
		_levelDiff(levelDiff) {

}

///////////////////////////////////////////////////////////////////////////////
// Constuctor and deconstrctor
///////////////////////////////////////////////////////////////////////////////

Enemy::Enemy(Map* map, float x, float y, EnemyType type)
	: Unit(map, x, y, type.getDefaultStats(), type.getSides(), sf::Color::Red) {

	_shape.setRadius(20);
	_shape.setFillColor(sf::Color::Red);

	_hpBar.setFillColor(sf::Color::Green);

	loadLua();
	_lua.loadScript("./lua/enemy.lua");
}

Enemy::~Enemy() {}

///////////////////////////////////////////////////////////////////////////////
// Methods
///////////////////////////////////////////////////////////////////////////////

void Enemy::loadLua() {
	if (_lua.isLoaded()) {
		CORE_ERROR("[Enemy: %x] Setting up a loaded Lua at %x", this, &_lua);
	}
	Object::loadLua();

	_lua.lua.set("me", this);
}

void Enemy::draw(sf::RenderTarget& target, sf::RenderStates states) const {
	target.draw(_shape);
	target.draw(_hpBar);
}

//void Enemy::update(int diff) {
//	Object::update(diff);
//}
<commit_msg>Fix compilation error<commit_after>#include "Enemy.h"
#include "Map.h"
#include "ParticleEmitter.h"
#include "Common.h"

#include "Logger.h"

////////////////////////////////////////////////////////////////////////////////
// EnemyType static methods
////////////////////////////////////////////////////////////////////////////////

EnemyType* EnemyType::getById(int id) {
	if (!idInUse(id)) {
		CORE_WARN("getById: id not in use! (%d)", id);
		return getDefaultType();
	}
	return &_types[id];
}

bool EnemyType::idInUse(unsigned int id) {
	return id < _types.size();
}

int EnemyType::createEnemyType(int id, const std::string& name, int sides,
	Stats defStats, Stats levelDiff) {

	// If the id is already in use try to use the next one
	if (idInUse(id)) {
		CORE_WARN("CreateEnemyType: id %d is already in use!", id);
		CORE_WARN("Trying to use %d to create", id + 1);
		return createEnemyType(++id, name, sides, defStats, levelDiff);
	}

	_types.push_back(EnemyType(id, name, sides, defStats, levelDiff));

	return id;
}

EnemyType* EnemyType::getDefaultType() {
	return &_defaultType;
}

////////////////////////////////////////////////////////////////////////////////
// EnemyType static vars
////////////////////////////////////////////////////////////////////////////////

std::vector<EnemyType> EnemyType::_types;
EnemyType EnemyType::_defaultType(0, "DEFAULT", 4, Stats(), Stats());

///////////////////////////////////////////////////////////////////////////////
// Constuctor and deconstrctor
///////////////////////////////////////////////////////////////////////////////

EnemyType::EnemyType(int id, const std::string& name, int sides,
		Stats defStats, Stats levelDiff)
	: _id(id), _name(name), _sides(sides), _defaultStats(defStats),
		_levelDiff(levelDiff) {

}

///////////////////////////////////////////////////////////////////////////////
// Constuctor and deconstrctor
///////////////////////////////////////////////////////////////////////////////

Enemy::Enemy(Map* map, float x, float y, EnemyType type)
	: Unit(map, x, y, type.getDefaultStats(), type.getSides(), sf::Color::Red),
		_enemyType(type) {

	_shape.setRadius(20);
	_shape.setFillColor(sf::Color::Red);

	_hpBar.setFillColor(sf::Color::Green);

	loadLua();
	_lua.loadScript("./lua/enemy.lua");
}

Enemy::~Enemy() {}

///////////////////////////////////////////////////////////////////////////////
// Methods
///////////////////////////////////////////////////////////////////////////////

void Enemy::loadLua() {
	if (_lua.isLoaded()) {
		CORE_ERROR("[Enemy: %x] Setting up a loaded Lua at %x", this, &_lua);
	}
	Object::loadLua();

	_lua.lua.set("me", this);
}

void Enemy::draw(sf::RenderTarget& target, sf::RenderStates states) const {
	target.draw(_shape);
	target.draw(_hpBar);
}

//void Enemy::update(int diff) {
//	Object::update(diff);
//}
<|endoftext|>