<commit_before>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file AsyncIf.hxx
 *
 * Asynchronous NMRAnet interface.
 *
 * @author Balazs Racz
 * @date 3 Dec 2013
 */

#ifndef _NMRAnetAsyncIf_hxx_
#define _NMRAnetAsyncIf_hxx_

/// @todo(balazs.racz) remove this dep
#include <string>

#include "nmranet/NMRAnetAsyncNode.hxx"
#include "nmranet/NMRAnetIf.hxx"
#include "executor/Dispatcher.hxx"
#include "executor/Service.hxx"
#include "executor/Executor.hxx"
#include "utils/BufferQueue.hxx"
#include "utils/Map.hxx"

namespace NMRAnet
{

class AsyncNode;

/** Convenience function to render a 48-bit NMRAnet node ID into a new buffer.
 *
 * @param id is the 48-bit ID to render.
 * @returns a new buffer (from the main pool) with 6 bytes of used space, a
 * big-endian representation of the node ID.
 */
extern string node_id_to_buffer(NodeID id);

/** Converts a 6-byte-long buffer to a node ID.
 *
 * @param buf is a buffer that has to have exactly 6 bytes used, filled with a
 * big-endian node id.
 * @returns the node id (in host endian).
 */
extern NodeID buffer_to_node_id(const string& buf);

/** This class is used in the dispatching of incoming or outgoing NMRAnet
 * messages to the message handlers at the protocol-agnostic level (i.e. not
 * CAN or TCP-specific).
 *
 * TODO(balazs.racz) There shall be one instance of this class that will be
 * sent to all handlers that expressed interest in that MTI. When all those
 * handlers are done, the instance should be freed. Currently the instance is
 * copied by the dispatcher separately for each handler. */
struct NMRAnetMessage
{
    void reset(If::MTI mti, NodeID src, NodeHandle dst, const string &payload)
    {
        this->mti = mti;
        this->src = {src, 0};
        this->dst = dst;
        this->payload = payload;
    }

    void reset(If::MTI mti, NodeID src, const string &payload)
    {
        this->mti = mti;
        this->src = {src, 0};
        this->dst = {0, 0};
        this->payload = payload;
    }

    /// OpenLCB MTI of the incoming message.
    If::MTI mti;
    /// Source node.
    NodeHandle src;
    /// Destination node.
    NodeHandle dst;
    /// If the destination node is local, this value is non-NULL.
    AsyncNode *dstNode;
    /// Data content in the message body. Owned by the dispatcher.
    /// @todo(balazs.racz) figure out a better container.
    string payload;

    typedef uint32_t id_type;
    id_type id() const
    {
        return static_cast<uint32_t>(mti);
    }
};

typedef FlowInterface<Buffer<NMRAnetMessage>> MessageHandler;

#if 0
/** @todo(balazs.racz) delete this class */
class WriteFlow : public ControlFlow
{
public:
    WriteFlow(Executor *e, Notifiable *done) : ControlFlow(e, done)
    {
    }

    /** Initiates sending an addressed message onto the NMRAnet bus.
     *
     * Must only be called if *this is an addressed flow.
     *
     * @param mti of the message to send
     * @param src is the NodeID of the originating node
     * @param dst is the destination node (cannot be 0,0)
     * @param data is the message payload (may be null), takes ownership
     * @param done will be notified when the message is enqueued for sending.
     *  May be set to nullptr.
     */
    virtual void WriteAddressedMessage(If::MTI mti, NodeID src, NodeHandle dst,
                                       Buffer *data, Notifiable *done) = 0;

    /** Initiates sending an unaddressed (global) message onto the NMRAnet bus.
     *
     * Must only be called if *this is a global flow.
     *
     * @param mti of the message to send
     * @param src is the NodeID of the originating node
     * @param data is the message payload (may be null), takes ownership
     * @param done will be notified when the message is enqueued for sending.
     *  May be set to nullptr.
     */
    virtual void WriteGlobalMessage(If::MTI mti, NodeID src, Buffer *data,
                                    Notifiable *done) = 0;
};
#endif
class AsyncIf : public Service
{
public:
    /** Constructs an NMRAnet interface.
     * @param executor is the thread that will be used for all processing on
     * this interface.
     * @param local_nodes_count is the maximum number of virtual nodes that
     * this interface will support. */
    AsyncIf(ExecutorBase *executor, int local_nodes_count);

    /** Destructor */
    virtual ~AsyncIf()
    {
    }

    /** @return Flow to send global messages to the NMRAnet bus. */
    MessageHandler *global_message_write_flow()
    {
        HASSERT(globalWriteFlow_);
        return globalWriteFlow_;
    }
    /** @return Flow to send addressed messages to the NMRAnet bus. */
    MessageHandler *addressed_message_write_flow()
    {
        HASSERT(addressedWriteFlow_);
        return addressedWriteFlow_;
    }

    /** Type of the dispatcher of incoming NMRAnet messages. */
    typedef DispatchFlow<Buffer<NMRAnetMessage>, 4> MessageDispatchFlow;

    /** @return Dispatcher of incoming NMRAnet messages. */
    MessageDispatchFlow *dispatcher()
    {
        return &dispatcher_;
    }

    /** Transfers ownership of a module to the interface. It will be brought
     * down in the destructor. The destruction order is guaranteed such that
     * all supporting structures are still available when the flow is destryed,
     * but incoming messages can not come in anymore.
     *
     * @todo(balazs.racz) revise whether this needs to be virtual. */
    virtual void add_owned_flow(Executable *e) = 0;

    /** Registers a new local node on this interface. This function must be
     * called from the interface's executor.
     *
     * @param node is the node to register.
     */
    void add_local_node(AsyncNode *node)
    {
        NodeID id = node->node_id();
        HASSERT(localNodes_.find(id) == localNodes_.end());
        localNodes_[id] = node;
    }

    /** Removes a local node from this interface. This function must be called
     * from the interface's executor.
     *
     * @param node is the node to delete.
     */
    void delete_local_node(AsyncNode *node)
    {
        HASSERT(0);
        /*
        auto it = localNodes_.find(node->node_id());
        HASSERT(it != localNodes_.end());
        localNodes_.erase(it);*/
    }

    /** Looks up a node ID in the local nodes' registry. This function must be
     * called from the interface's executor.
     *
     * @param id is the 48-bit NMRAnet node ID to look up.
     * @returns the node pointer or NULL if the node is not registered.
     */
    AsyncNode *lookup_local_node(NodeID id)
    {
        auto it = localNodes_.find(id);
        if (it == localNodes_.end())
        {
            return nullptr;
        }
        return it->second;
    }

protected:
    /// Allocator containing the global write flows.
    MessageHandler *globalWriteFlow_;
    /// Allocator containing the addressed write flows.
    MessageHandler *addressedWriteFlow_;

private:
    /// Flow responsible for routing incoming messages to handlers.
    MessageDispatchFlow dispatcher_;

    typedef Map<NodeID, AsyncNode *> VNodeMap;

    /// Local virtual nodes registered on this interface.
    VNodeMap localNodes_;

    friend class VerifyNodeIdHandler;

    DISALLOW_COPY_AND_ASSIGN(AsyncIf);
};

/** Base class for incoming message handler flows. */
class IncomingMessageStateFlow
    : public StateFlow<Buffer<NMRAnetMessage>, QList<4>>
{
public:
    IncomingMessageStateFlow(AsyncIf *interface)
        : StateFlow<Buffer<NMRAnetMessage>, QList<4>>(interface)
    {
    }

    AsyncIf *interface()
    {
        return static_cast<AsyncIf *>(service());
    }
};

} // namespace NMRAnet

#endif // _NMRAnetAsyncIf_hxx_
<commit_msg>Initializes dstNode with nullptr as well.<commit_after>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file AsyncIf.hxx
 *
 * Asynchronous NMRAnet interface.
 *
 * @author Balazs Racz
 * @date 3 Dec 2013
 */

#ifndef _NMRAnetAsyncIf_hxx_
#define _NMRAnetAsyncIf_hxx_

/// @todo(balazs.racz) remove this dep
#include <string>

#include "nmranet/NMRAnetAsyncNode.hxx"
#include "nmranet/NMRAnetIf.hxx"
#include "executor/Dispatcher.hxx"
#include "executor/Service.hxx"
#include "executor/Executor.hxx"
#include "utils/BufferQueue.hxx"
#include "utils/Map.hxx"

namespace NMRAnet
{

class AsyncNode;

/** Convenience function to render a 48-bit NMRAnet node ID into a new buffer.
 *
 * @param id is the 48-bit ID to render.
 * @returns a new buffer (from the main pool) with 6 bytes of used space, a
 * big-endian representation of the node ID.
 */
extern string node_id_to_buffer(NodeID id);

/** Converts a 6-byte-long buffer to a node ID.
 *
 * @param buf is a buffer that has to have exactly 6 bytes used, filled with a
 * big-endian node id.
 * @returns the node id (in host endian).
 */
extern NodeID buffer_to_node_id(const string& buf);

/** This class is used in the dispatching of incoming or outgoing NMRAnet
 * messages to the message handlers at the protocol-agnostic level (i.e. not
 * CAN or TCP-specific).
 *
 * TODO(balazs.racz) There shall be one instance of this class that will be
 * sent to all handlers that expressed interest in that MTI. When all those
 * handlers are done, the instance should be freed. Currently the instance is
 * copied by the dispatcher separately for each handler. */
struct NMRAnetMessage
{
    void reset(If::MTI mti, NodeID src, NodeHandle dst, const string &payload)
    {
        this->mti = mti;
        this->src = {src, 0};
        this->dst = dst;
        this->payload = payload;
        this->dstNode = nullptr;
    }

    void reset(If::MTI mti, NodeID src, const string &payload)
    {
        this->mti = mti;
        this->src = {src, 0};
        this->dst = {0, 0};
        this->payload = payload;
        this->dstNode = nullptr;
    }

    /// OpenLCB MTI of the incoming message.
    If::MTI mti;
    /// Source node.
    NodeHandle src;
    /// Destination node.
    NodeHandle dst;
    /// If the destination node is local, this value is non-NULL.
    AsyncNode *dstNode;
    /// Data content in the message body. Owned by the dispatcher.
    /// @todo(balazs.racz) figure out a better container.
    string payload;

    typedef uint32_t id_type;
    id_type id() const
    {
        return static_cast<uint32_t>(mti);
    }
};

typedef FlowInterface<Buffer<NMRAnetMessage>> MessageHandler;

#if 0
/** @todo(balazs.racz) delete this class */
class WriteFlow : public ControlFlow
{
public:
    WriteFlow(Executor *e, Notifiable *done) : ControlFlow(e, done)
    {
    }

    /** Initiates sending an addressed message onto the NMRAnet bus.
     *
     * Must only be called if *this is an addressed flow.
     *
     * @param mti of the message to send
     * @param src is the NodeID of the originating node
     * @param dst is the destination node (cannot be 0,0)
     * @param data is the message payload (may be null), takes ownership
     * @param done will be notified when the message is enqueued for sending.
     *  May be set to nullptr.
     */
    virtual void WriteAddressedMessage(If::MTI mti, NodeID src, NodeHandle dst,
                                       Buffer *data, Notifiable *done) = 0;

    /** Initiates sending an unaddressed (global) message onto the NMRAnet bus.
     *
     * Must only be called if *this is a global flow.
     *
     * @param mti of the message to send
     * @param src is the NodeID of the originating node
     * @param data is the message payload (may be null), takes ownership
     * @param done will be notified when the message is enqueued for sending.
     *  May be set to nullptr.
     */
    virtual void WriteGlobalMessage(If::MTI mti, NodeID src, Buffer *data,
                                    Notifiable *done) = 0;
};
#endif
class AsyncIf : public Service
{
public:
    /** Constructs an NMRAnet interface.
     * @param executor is the thread that will be used for all processing on
     * this interface.
     * @param local_nodes_count is the maximum number of virtual nodes that
     * this interface will support. */
    AsyncIf(ExecutorBase *executor, int local_nodes_count);

    /** Destructor */
    virtual ~AsyncIf()
    {
    }

    /** @return Flow to send global messages to the NMRAnet bus. */
    MessageHandler *global_message_write_flow()
    {
        HASSERT(globalWriteFlow_);
        return globalWriteFlow_;
    }
    /** @return Flow to send addressed messages to the NMRAnet bus. */
    MessageHandler *addressed_message_write_flow()
    {
        HASSERT(addressedWriteFlow_);
        return addressedWriteFlow_;
    }

    /** Type of the dispatcher of incoming NMRAnet messages. */
    typedef DispatchFlow<Buffer<NMRAnetMessage>, 4> MessageDispatchFlow;

    /** @return Dispatcher of incoming NMRAnet messages. */
    MessageDispatchFlow *dispatcher()
    {
        return &dispatcher_;
    }

    /** Transfers ownership of a module to the interface. It will be brought
     * down in the destructor. The destruction order is guaranteed such that
     * all supporting structures are still available when the flow is destryed,
     * but incoming messages can not come in anymore.
     *
     * @todo(balazs.racz) revise whether this needs to be virtual. */
    virtual void add_owned_flow(Executable *e) = 0;

    /** Registers a new local node on this interface. This function must be
     * called from the interface's executor.
     *
     * @param node is the node to register.
     */
    void add_local_node(AsyncNode *node)
    {
        NodeID id = node->node_id();
        HASSERT(localNodes_.find(id) == localNodes_.end());
        localNodes_[id] = node;
    }

    /** Removes a local node from this interface. This function must be called
     * from the interface's executor.
     *
     * @param node is the node to delete.
     */
    void delete_local_node(AsyncNode *node)
    {
        HASSERT(0);
        /*
        auto it = localNodes_.find(node->node_id());
        HASSERT(it != localNodes_.end());
        localNodes_.erase(it);*/
    }

    /** Looks up a node ID in the local nodes' registry. This function must be
     * called from the interface's executor.
     *
     * @param id is the 48-bit NMRAnet node ID to look up.
     * @returns the node pointer or NULL if the node is not registered.
     */
    AsyncNode *lookup_local_node(NodeID id)
    {
        auto it = localNodes_.find(id);
        if (it == localNodes_.end())
        {
            return nullptr;
        }
        return it->second;
    }

protected:
    /// Allocator containing the global write flows.
    MessageHandler *globalWriteFlow_;
    /// Allocator containing the addressed write flows.
    MessageHandler *addressedWriteFlow_;

private:
    /// Flow responsible for routing incoming messages to handlers.
    MessageDispatchFlow dispatcher_;

    typedef Map<NodeID, AsyncNode *> VNodeMap;

    /// Local virtual nodes registered on this interface.
    VNodeMap localNodes_;

    friend class VerifyNodeIdHandler;

    DISALLOW_COPY_AND_ASSIGN(AsyncIf);
};

/** Base class for incoming message handler flows. */
class IncomingMessageStateFlow
    : public StateFlow<Buffer<NMRAnetMessage>, QList<4>>
{
public:
    IncomingMessageStateFlow(AsyncIf *interface)
        : StateFlow<Buffer<NMRAnetMessage>, QList<4>>(interface)
    {
    }

    AsyncIf *interface()
    {
        return static_cast<AsyncIf *>(service());
    }

    /// Returns the NMRAnet message we received.
    NMRAnetMessage *nmsg()
    {
        return message()->data();
    }
};

} // namespace NMRAnet

#endif // _NMRAnetAsyncIf_hxx_
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2015, The University of Oxford
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the University of Oxford nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <apps/lib/oskar_OptionParser.h>

#include <oskar_log.h>
#include <oskar_get_error_string.h>
#include <oskar_vis.h>
#include <oskar_version_string.h>

#include <string>
#include <vector>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cfloat>

using namespace std;

//------------------------------------------------------------------------------
void set_options(oskar_OptionParser& opt);
bool check_options(oskar_OptionParser& opt, int argc, char** argv);
void check_error(int status);
//------------------------------------------------------------------------------

int main(int argc, char** argv)
{
    int status = OSKAR_SUCCESS;

    // Register options.
    oskar_OptionParser opt("oskar_vis_stats", oskar_version_string());
    set_options(opt);
    if (!check_options(opt, argc, argv))
        return OSKAR_FAIL;

    // Retrieve options.
    vector<string> vis_filename = opt.getArgs();
    bool verbose = opt.isSet("-v") ? true : false;
    int num_files = (int)vis_filename.size();
    int disp_width = (num_files == 1) ? 1 : (int)log10(num_files)+1;

    oskar_Log* log = 0;
    oskar_log_section(log, 'M', "OSKAR-%s starting at %s.", OSKAR_VERSION_STR,
            oskar_log_system_clock_string(0));

    for (int i = 0; i < num_files; ++i)
    {
        oskar_Binary* h = oskar_binary_create(vis_filename[i].c_str(), 'r',
                &status);
        oskar_Vis* vis = oskar_vis_read(h, &status);
        oskar_binary_free(h);
        check_error(status);
        int vis_type = oskar_mem_type(oskar_vis_amplitude(vis));
        int num_vis = (int)oskar_mem_length(oskar_vis_amplitude(vis));

        double abs_min = DBL_MAX;
        double abs_max = -DBL_MAX;
        double2 min;
        min.x = DBL_MAX;
        min.y = DBL_MAX;
        double2 max;
        max.x = -DBL_MAX;
        max.y = -DBL_MAX;
        double2 sum;
        sum.x = 0.0;
        sum.y = 0.0;
        double sumsq = 0.0;
        size_t num_zero = 0;
        double rms = 0.0;
        double2 mean;
        mean.x = 0.0;
        mean.y = 0.0;

        if (vis_type == OSKAR_SINGLE_COMPLEX_MATRIX)
        {
            float4c* amp = oskar_mem_float4c(oskar_vis_amplitude(vis), &status);
            for (int i = 0; i < num_vis; ++i)
            {
                double2 I; // I = 0.5 (XX + YY)
                I.x = 0.5 * (amp[i].a.x + amp[i].d.x);
                I.y = 0.5 * (amp[i].a.y + amp[i].d.y);
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else if (vis_type == OSKAR_DOUBLE_COMPLEX_MATRIX)
        {
            double4c* amp = oskar_mem_double4c(oskar_vis_amplitude(vis), &status);

            for (int i = 0; i < num_vis; ++i)
            {
                double2 I; // I = 0.5 (XX + YY)
                I.x = 0.5 * (amp[i].a.x + amp[i].d.x);
                I.y = 0.5 * (amp[i].a.y + amp[i].d.y);
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else if (vis_type == OSKAR_SINGLE_COMPLEX)
        {
            float2* amp = oskar_mem_float2(oskar_vis_amplitude(vis), &status);

            for (int i = 0; i < num_vis; ++i)
            {
                double2 I;
                I.x = amp[i].x;
                I.y = amp[i].y;
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else if (vis_type == OSKAR_DOUBLE_COMPLEX)
        {
            double2* amp = oskar_mem_double2(oskar_vis_amplitude(vis), &status);
            for (int i = 0; i < num_vis; ++i)
            {
                double2 I;
                I.x = amp[i].x;
                I.y = amp[i].y;
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else
        {
            oskar_log_error(log, "Incompatible or invalid visibility data type.");
            return OSKAR_ERR_BAD_DATA_TYPE;
        }
        oskar_log_message(log, 'M', 0, "%s [%0*i/%i]", vis_filename[i].c_str(),
                disp_width, i+1, num_files);
        if (verbose)
        {
            oskar_log_message(log, 'S', 1, "No. baselines : %i",
                    oskar_vis_num_baselines(vis));
            oskar_log_message(log, 'S', 1, "No. times     : %i",
                    oskar_vis_num_times(vis));
            oskar_log_message(log, 'S', 1, "No. channels  : %i",
                    oskar_vis_num_channels(vis));
        }

        oskar_log_message(log, 'M', 1, "Stokes-I:");
        oskar_log_message(log, 'M', 2, "Minimum     : % 6.3e % +6.3ej Jy",
                min.x,  min.y);
        oskar_log_message(log, 'M', 2, "Maximum     : % 6.3e % +6.3ej Jy",
                max.x, max.y);
        oskar_log_message(log, 'M', 2, "Mean        : % 6.3e % +6.3ej Jy",
                mean.x, mean.y);
        oskar_log_message(log, 'M', 2, "RMS         : % 6.3e Jy", rms);
        oskar_log_message(log, 'M', 2, "Zeros       :  %i/%i (%.1f%%)",
                num_zero, num_vis, (double)(num_zero/num_vis)*100.0);

        // Free visibility data.
        oskar_vis_free(vis, &status);
    } // end of loop over visibility files

    oskar_log_section(log, 'M', "OSKAR-%s starting at %s.", OSKAR_VERSION_STR,
            oskar_log_system_clock_string(0));

    return status;
}

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

void set_options(oskar_OptionParser& opt)
{
    opt.setDescription("Application to generate some stats from an OSKAR visibility file.");
    opt.addRequired("OSKAR visibility file(s)...");
    opt.addFlag("-v", "Verbose");
}

bool check_options(oskar_OptionParser& opt, int argc, char** argv)
{
    if (!opt.check_options(argc, argv))
        return false;
    return true;
}

void check_error(int status)
{
    if (status != OSKAR_SUCCESS) {
        cout << "ERROR: code[" << status << "] ";
        cout << oskar_get_error_string(status) << endl;
        exit(status);
    }
}

<commit_msg>fixed integer div bug in vis stats printing<commit_after>/*
 * Copyright (c) 2013-2015, The University of Oxford
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the University of Oxford nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <apps/lib/oskar_OptionParser.h>

#include <oskar_log.h>
#include <oskar_get_error_string.h>
#include <oskar_vis.h>
#include <oskar_version_string.h>

#include <string>
#include <vector>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cfloat>

using namespace std;

//------------------------------------------------------------------------------
void set_options(oskar_OptionParser& opt);
bool check_options(oskar_OptionParser& opt, int argc, char** argv);
void check_error(int status);
//------------------------------------------------------------------------------

int main(int argc, char** argv)
{
    int status = OSKAR_SUCCESS;

    // Register options.
    oskar_OptionParser opt("oskar_vis_stats", oskar_version_string());
    set_options(opt);
    if (!check_options(opt, argc, argv))
        return OSKAR_FAIL;

    // Retrieve options.
    vector<string> vis_filename = opt.getArgs();
    bool verbose = opt.isSet("-v") ? true : false;
    int num_files = (int)vis_filename.size();
    int disp_width = (num_files == 1) ? 1 : (int)log10(num_files)+1;

    oskar_Log* log = 0;
    oskar_log_section(log, 'M', "OSKAR-%s starting at %s.", OSKAR_VERSION_STR,
            oskar_log_system_clock_string(0));

    for (int i = 0; i < num_files; ++i)
    {
        oskar_Binary* h = oskar_binary_create(vis_filename[i].c_str(), 'r',
                &status);
        oskar_Vis* vis = oskar_vis_read(h, &status);
        oskar_binary_free(h);
        check_error(status);
        int vis_type = oskar_mem_type(oskar_vis_amplitude(vis));
        int num_vis = (int)oskar_mem_length(oskar_vis_amplitude(vis));

        double abs_min = DBL_MAX;
        double abs_max = -DBL_MAX;
        double2 min;
        min.x = DBL_MAX;
        min.y = DBL_MAX;
        double2 max;
        max.x = -DBL_MAX;
        max.y = -DBL_MAX;
        double2 sum;
        sum.x = 0.0;
        sum.y = 0.0;
        double sumsq = 0.0;
        size_t num_zero = 0;
        double rms = 0.0;
        double2 mean;
        mean.x = 0.0;
        mean.y = 0.0;

        if (vis_type == OSKAR_SINGLE_COMPLEX_MATRIX)
        {
            float4c* amp = oskar_mem_float4c(oskar_vis_amplitude(vis), &status);
            for (int i = 0; i < num_vis; ++i)
            {
                double2 I; // I = 0.5 (XX + YY)
                I.x = 0.5 * (amp[i].a.x + amp[i].d.x);
                I.y = 0.5 * (amp[i].a.y + amp[i].d.y);
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else if (vis_type == OSKAR_DOUBLE_COMPLEX_MATRIX)
        {
            double4c* amp = oskar_mem_double4c(oskar_vis_amplitude(vis), &status);

            for (int i = 0; i < num_vis; ++i)
            {
                double2 I; // I = 0.5 (XX + YY)
                I.x = 0.5 * (amp[i].a.x + amp[i].d.x);
                I.y = 0.5 * (amp[i].a.y + amp[i].d.y);
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else if (vis_type == OSKAR_SINGLE_COMPLEX)
        {
            float2* amp = oskar_mem_float2(oskar_vis_amplitude(vis), &status);

            for (int i = 0; i < num_vis; ++i)
            {
                double2 I;
                I.x = amp[i].x;
                I.y = amp[i].y;
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else if (vis_type == OSKAR_DOUBLE_COMPLEX)
        {
            double2* amp = oskar_mem_double2(oskar_vis_amplitude(vis), &status);
            for (int i = 0; i < num_vis; ++i)
            {
                double2 I;
                I.x = amp[i].x;
                I.y = amp[i].y;
                sum.x += I.x;
                sum.y += I.y;
                double absI = sqrt(I.x*I.x + I.y*I.y);
                if (absI < DBL_MIN) num_zero++;
                if (absI > abs_max) {
                    abs_max = absI;
                    max.x = I.x;
                    max.y = I.y;
                }
                if (absI < abs_min) {
                    abs_min = absI;
                    min.x = I.x;
                    min.y = I.y;
                }
                sumsq += absI * absI;
            }
            mean.x = sum.x / num_vis;
            mean.y = sum.y / num_vis;
            rms = sqrt(sumsq / num_vis);
        }

        else
        {
            oskar_log_error(log, "Incompatible or invalid visibility data type.");
            return OSKAR_ERR_BAD_DATA_TYPE;
        }
        oskar_log_message(log, 'M', 0, "%s [%0*i/%i]", vis_filename[i].c_str(),
                disp_width, i+1, num_files);
        if (verbose)
        {
            oskar_log_message(log, 'S', 1, "No. baselines : %i",
                    oskar_vis_num_baselines(vis));
            oskar_log_message(log, 'S', 1, "No. times     : %i",
                    oskar_vis_num_times(vis));
            oskar_log_message(log, 'S', 1, "No. channels  : %i",
                    oskar_vis_num_channels(vis));
        }

        oskar_log_message(log, 'M', 1, "Stokes-I:");
        oskar_log_message(log, 'M', 2, "Minimum     : % 6.3e % +6.3ej Jy",
                min.x,  min.y);
        oskar_log_message(log, 'M', 2, "Maximum     : % 6.3e % +6.3ej Jy",
                max.x, max.y);
        oskar_log_message(log, 'M', 2, "Mean        : % 6.3e % +6.3ej Jy",
                mean.x, mean.y);
        oskar_log_message(log, 'M', 2, "RMS         : % 6.3e Jy", rms);
        oskar_log_message(log, 'M', 2, "Zeros       :  %i/%i (%.1f%%)",
                num_zero, num_vis, ((double)num_zero/num_vis)*100.0);

        // Free visibility data.
        oskar_vis_free(vis, &status);
    } // end of loop over visibility files

    oskar_log_section(log, 'M', "OSKAR-%s starting at %s.", OSKAR_VERSION_STR,
            oskar_log_system_clock_string(0));

    return status;
}

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

void set_options(oskar_OptionParser& opt)
{
    opt.setDescription("Application to generate some stats from an OSKAR visibility file.");
    opt.addRequired("OSKAR visibility file(s)...");
    opt.addFlag("-v", "Verbose");
}

bool check_options(oskar_OptionParser& opt, int argc, char** argv)
{
    if (!opt.check_options(argc, argv))
        return false;
    return true;
}

void check_error(int status)
{
    if (status != OSKAR_SUCCESS) {
        cout << "ERROR: code[" << status << "] ";
        cout << oskar_get_error_string(status) << endl;
        exit(status);
    }
}

<|endoftext|>


<commit_before>/**
 * @file   ProcessTest.cpp
 * @brief  Process & PipeProcess class tester.
 * @author zer0
 * @date   2016-05-19
 */

#include <gtest/gtest.h>
#include <libtbag/process/Process.hpp>
#include <libtbag/process/PipeProcess.hpp>
#include <libtbag/filesystem/Path.hpp>
#include <libtbag/predef.hpp>

#include <fstream>

constexpr char const * const getProcessTestFileName() noexcept
{
#if __OS_WINDOWS__
    return "process_test.exe";
#else
    return "process_test";
#endif
}

using namespace libtbag;
using namespace libtbag::filesystem;
using namespace libtbag::process;

static bool runTestProgram(Process           * process
                         , std::string const & arg1
                         , std::string const & arg2)
{
    Path exe_dir      = Path(common::getExeDir());
    Path test_program = exe_dir / getProcessTestFileName();

    std::vector<std::string> args;
    args.push_back(arg1);
    if (arg2.empty() == false) {
        args.push_back(arg2);
    }

    process->setExecuteFile(test_program);
    process->setArguments(args);
    process->setWorkingDirectory(exe_dir);
    process->setFlags(0);

    return process->exe();
}

TEST(PipeProcessTest, StandardOutput)
{
    std::string const  TEST_STRING = "TEST_OUTPUT_MESSAGE";
    std::string const EMPTY_STRING = "";

    PipeProcess process;
    ASSERT_TRUE(runTestProgram(&process, "out", TEST_STRING));

    ASSERT_EQ(process.getExitStatus(), 0);
    ASSERT_EQ(process.getTerminateSignal(), 0);
    ASSERT_EQ(process.getStandardOutput(), TEST_STRING);
    ASSERT_EQ(process.getStandardError(), EMPTY_STRING);
}

TEST(PipeProcessTest, StandardInput)
{
    std::string const  TEST_STRING = "TEST_INPUT";
    std::string const INPUT_STRING = TEST_STRING + "\n";
    std::string const EMPTY_STRING = "";

    PipeProcess process;
    process.setStandardInput(INPUT_STRING);
    ASSERT_TRUE(runTestProgram(&process, "out", EMPTY_STRING));

    ASSERT_EQ(process.getExitStatus(), 0);
    ASSERT_EQ(process.getTerminateSignal(), 0);
    ASSERT_EQ(process.getStandardOutput(), TEST_STRING);
    ASSERT_EQ(process.getStandardError(), EMPTY_STRING);
}

TEST(PipeProcessTest, StandardError)
{
    std::string const  TEST_STRING = "TEST_ERROR_MESSAGE";
    std::string const EMPTY_STRING = "";

    PipeProcess process;
    ASSERT_TRUE(runTestProgram(&process, "err", TEST_STRING));

    ASSERT_EQ(process.getExitStatus(), 0);
    ASSERT_EQ(process.getTerminateSignal(), 0);
    ASSERT_EQ(process.getStandardOutput(), EMPTY_STRING);
    ASSERT_EQ(process.getStandardError(),   TEST_STRING);
}

TEST(PipeProcessTest, FileOutput)
{
    filesystem::Path const TEST_FILE("__process_test_file.txt");
    if (filesystem::common::existsFile(TEST_FILE)) {
        filesystem::common::remove(TEST_FILE);
    }
    ASSERT_FALSE(filesystem::common::existsFile(TEST_FILE));

    std::string const  TEST_STRING = "TEST";
    std::string const EMPTY_STRING = "";

    PipeProcess process;
    ASSERT_TRUE(runTestProgram(&process, "file", TEST_STRING));

    ASSERT_EQ(process.getExitStatus(), 0);
    ASSERT_EQ(process.getTerminateSignal(), 0);
    ASSERT_EQ(process.getStandardOutput(), EMPTY_STRING);
    ASSERT_EQ(process.getStandardError(),  EMPTY_STRING);

    ASSERT_TRUE(filesystem::common::existsFile(TEST_FILE));
    ASSERT_TRUE(filesystem::common::isRegularFile(TEST_FILE));

    std::ifstream file(TEST_FILE.getString());
    std::string   file_body;
    file >> file_body;
    file.close();

    ASSERT_EQ(file_body, TEST_STRING);
}

TEST(ProcessTest, exit_code_failure)
{
    Process process;
    ASSERT_TRUE(runTestProgram(&process, "unknown", "unknown"));

    ASSERT_EQ(process.getExitStatus(), 1);
    ASSERT_EQ(process.getTerminateSignal(), 0);
}

<commit_msg>Set comment to ProcessTest.<commit_after>/**
 * @file   ProcessTest.cpp
 * @brief  Process & PipeProcess class tester.
 * @author zer0
 * @date   2016-05-19
 */

#include <gtest/gtest.h>
//#include <libtbag/process/Process.hpp>
//#include <libtbag/process/PipeProcess.hpp>
//#include <libtbag/filesystem/Path.hpp>
//#include <libtbag/predef.hpp>
//
//#include <fstream>
//
//constexpr char const * const getProcessTestFileName() noexcept
//{
//#if __OS_WINDOWS__
//    return "process_test.exe";
//#else
//    return "process_test";
//#endif
//}
//
//using namespace libtbag;
//using namespace libtbag::filesystem;
//using namespace libtbag::process;
//
//static bool runTestProgram(Process           * process
//                         , std::string const & arg1
//                         , std::string const & arg2)
//{
//    Path exe_dir      = Path(common::getExeDir());
//    Path test_program = exe_dir / getProcessTestFileName();
//
//    std::vector<std::string> args;
//    args.push_back(arg1);
//    if (arg2.empty() == false) {
//        args.push_back(arg2);
//    }
//
//    process->setExecuteFile(test_program);
//    process->setArguments(args);
//    process->setWorkingDirectory(exe_dir);
//    process->setFlags(0);
//
//    return process->exe();
//}
//
//TEST(PipeProcessTest, StandardOutput)
//{
//    std::string const  TEST_STRING = "TEST_OUTPUT_MESSAGE";
//    std::string const EMPTY_STRING = "";
//
//    PipeProcess process;
//    ASSERT_TRUE(runTestProgram(&process, "out", TEST_STRING));
//
//    ASSERT_EQ(process.getExitStatus(), 0);
//    ASSERT_EQ(process.getTerminateSignal(), 0);
//    ASSERT_EQ(process.getStandardOutput(), TEST_STRING);
//    ASSERT_EQ(process.getStandardError(), EMPTY_STRING);
//}
//
//TEST(PipeProcessTest, StandardInput)
//{
//    std::string const  TEST_STRING = "TEST_INPUT";
//    std::string const INPUT_STRING = TEST_STRING + "\n";
//    std::string const EMPTY_STRING = "";
//
//    PipeProcess process;
//    process.setStandardInput(INPUT_STRING);
//    ASSERT_TRUE(runTestProgram(&process, "out", EMPTY_STRING));
//
//    ASSERT_EQ(process.getExitStatus(), 0);
//    ASSERT_EQ(process.getTerminateSignal(), 0);
//    ASSERT_EQ(process.getStandardOutput(), TEST_STRING);
//    ASSERT_EQ(process.getStandardError(), EMPTY_STRING);
//}
//
//TEST(PipeProcessTest, StandardError)
//{
//    std::string const  TEST_STRING = "TEST_ERROR_MESSAGE";
//    std::string const EMPTY_STRING = "";
//
//    PipeProcess process;
//    ASSERT_TRUE(runTestProgram(&process, "err", TEST_STRING));
//
//    ASSERT_EQ(process.getExitStatus(), 0);
//    ASSERT_EQ(process.getTerminateSignal(), 0);
//    ASSERT_EQ(process.getStandardOutput(), EMPTY_STRING);
//    ASSERT_EQ(process.getStandardError(),   TEST_STRING);
//}
//
//TEST(PipeProcessTest, FileOutput)
//{
//    filesystem::Path const TEST_FILE("__process_test_file.txt");
//    if (filesystem::common::existsFile(TEST_FILE)) {
//        filesystem::common::remove(TEST_FILE);
//    }
//    ASSERT_FALSE(filesystem::common::existsFile(TEST_FILE));
//
//    std::string const  TEST_STRING = "TEST";
//    std::string const EMPTY_STRING = "";
//
//    PipeProcess process;
//    ASSERT_TRUE(runTestProgram(&process, "file", TEST_STRING));
//
//    ASSERT_EQ(process.getExitStatus(), 0);
//    ASSERT_EQ(process.getTerminateSignal(), 0);
//    ASSERT_EQ(process.getStandardOutput(), EMPTY_STRING);
//    ASSERT_EQ(process.getStandardError(),  EMPTY_STRING);
//
//    ASSERT_TRUE(filesystem::common::existsFile(TEST_FILE));
//    ASSERT_TRUE(filesystem::common::isRegularFile(TEST_FILE));
//
//    std::ifstream file(TEST_FILE.getString());
//    std::string   file_body;
//    file >> file_body;
//    file.close();
//
//    ASSERT_EQ(file_body, TEST_STRING);
//}
//
//TEST(ProcessTest, exit_code_failure)
//{
//    Process process;
//    ASSERT_TRUE(runTestProgram(&process, "unknown", "unknown"));
//
//    ASSERT_EQ(process.getExitStatus(), 1);
//    ASSERT_EQ(process.getTerminateSignal(), 0);
//}

<|endoftext|>


<commit_before>#ifndef Cropping
#define Cropping
#define _CRT_SECURE_NO_DEPRECATE
#include "croppingTool.h"
#include "ClassifierTraining.h"

#include "opencv2/objdetect.hpp"
//#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);
void cropImageAndSave(Mat frame);

CascadeClassifier car_cascade;
String window_name = "Capture - detection";
//String car_cascade_name = "../data/xml/cascade-bee.xml";
int counter;
int posCount;
int negCount;

void nms(const vector<Rect>& srcRects,vector<cv::Rect>& resRects,float thresh)
{
	resRects.clear();

	const size_t size = srcRects.size();
	if (!size)
	{
		return;
	}

	// Sort the bounding boxes by the bottom - right y - coordinate of the bounding box
	std::multimap<int, size_t> idxs;
	for (size_t i = 0; i < size; ++i)
	{
		idxs.insert(std::pair<int, size_t>(srcRects[i].br().y, i));
	}

	// keep looping while some indexes still remain in the indexes list
	while (idxs.size() > 0)
	{
		// grab the last rectangle
		auto lastElem = --std::end(idxs);
		const cv::Rect& rect1 = srcRects[lastElem->second];

		resRects.push_back(rect1);

		idxs.erase(lastElem);

		for (auto pos = std::begin(idxs); pos != std::end(idxs); )
		{
			// grab the current rectangle
			const cv::Rect& rect2 = srcRects[pos->second];

			float intArea = (rect1 & rect2).area();
			float unionArea = rect1.area() + rect2.area() - intArea;
			float overlap = intArea / unionArea;

			// if there is sufficient overlap, suppress the current bounding box
			if (overlap > thresh)
			{
				pos = idxs.erase(pos);
			}
			else
			{
				++pos;
			}
		}
	}
}

void cropImageAndSave(Mat frame) {
	Mat cleanFrame = frame.clone();
	Mat croppedImage;
	String cropped_window = "Cropped image";
	String filename = "pos/image-";
	string input = ""; // std string for input
	Rect slidingWindow = Rect(0, 0, 300, 300);
	bool saved = false;
	bool forceQuit = false;

	// how much to much the windows (x and y)
	int shiftXBy = slidingWindow.width/10; int shiftYBy = slidingWindow.height/10;

	for (int row = 0; slidingWindow.y + slidingWindow.height <= frame.size().height && !forceQuit; row++)
	{
		cout << "row" << endl;
		for (int col = 0; slidingWindow.x + slidingWindow.width <= frame.size().width && !forceQuit; col++)
		{
			cout << slidingWindow << endl;

			// get smaller image from original frame "clean" version (no rectangle)
			croppedImage = cleanFrame(slidingWindow);

			// show for user to confirm and label
			imshow(cropped_window, croppedImage);

			// show rectangles on image
			if (col % 2 == row % 2) {
				rectangle(frame, slidingWindow, Scalar(255, 0, 0), 1, 8, 0);
			}
			else {
				rectangle(frame, slidingWindow, Scalar(0, 255, 0), 1, 8, 0);
			}

			imshow(window_name, frame);

			char c = (char)waitKey(0);
			if (c == 27) { forceQuit = true; break; } // escape

			while (!saved) {
				if (c == 'q') {
					saved = true;
					forceQuit = true;
				}
				else if (c == 'g') {
					cout << "positive" << endl;
					imwrite("images/pos/pos-img" + std::to_string(posCount) + ".jpg", croppedImage);
					posCount++;
					saved = true;
				}
				else if (c == 'f') {
					cout << "negative" << endl;
					imwrite("images/neg/neg-img" + std::to_string(negCount) + ".jpg", croppedImage);
					negCount++;
					saved = true;
				}
				else if (c == 's') {
					cout << "skipping" << endl;
					saved = true;
				}
				else
				{
					c = (char)waitKey(0);
					if (c == 27) { forceQuit = true; break; }
				}
			}

			// move sliding window  to the right
			slidingWindow.x += shiftXBy;

			// new cropped image to save
			saved = false;
		}
		// reset x for new row
		slidingWindow.x = 0;
		// move sliding window  to the right
		slidingWindow.y += shiftYBy;

	}
}

void detectAndDisplay(Mat frame)
{
	Mat frame_gray;
	Mat resized_frame;
	Mat resized_frame_gray;

	std::vector<Rect> beesFound;

	// useScaling == detect on small image and draw on bigger one
	bool useScaling = true; // for detecting
	bool drawOnOriginal = true; // for drawing
	const int scale = 4;

	// ==========================================================
	// scale down image and find objects ========================
	if (useScaling) {
		// scale down the image by factor of variable "scale"
		resized_frame = Mat(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_8UC1);
		resize(frame, resized_frame, resized_frame.size());

		// turn to grayscale
		cvtColor(resized_frame, resized_frame_gray, COLOR_BGR2GRAY);
		equalizeHist(resized_frame_gray, resized_frame_gray);

		//-- Detect beesFound on scaled image
		car_cascade.detectMultiScale(resized_frame_gray, beesFound, 1.5, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
	}
	else {
		// turn to grayscale
		cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
		equalizeHist(frame_gray, frame_gray);

		// no scaling
		car_cascade.detectMultiScale(frame_gray, beesFound, 1.5, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

		// original values
		//face_cascade.detectMultiScale(frame_gray, beesFound, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
	}

	// ==========================================================
	// draw on the image to show the items ======================

	for (size_t i = 0; i < beesFound.size(); i++)
	{
		// print values for objects found
		cout << "x : " << beesFound[i].x << " | y : " << beesFound[i].y << " | width : " << beesFound[i].width << " | height : " << beesFound[i].height << endl;

		// draw on non-scaled image
		if (drawOnOriginal) {
			// draw rectangle
			rectangle(frame, Rect((beesFound[i].x*scale), (beesFound[i].y*scale), (beesFound[i].width*scale), (beesFound[i].height*scale)), Scalar(0, 245, 0), 1 * scale, 8, 0);
		}
		else {
			// draw rectangle
			rectangle(resized_frame, Rect(beesFound[i].x, beesFound[i].y, beesFound[i].width, beesFound[i].height), Scalar(0, 245, 0), 1, 8, 0);
		}
	}

	//-- Show what you got
	if (drawOnOriginal)
		cv::imshow(window_name, frame);
	else
		cv::imshow(window_name, resized_frame);
}

Mat DetectInFrame(Mat frame)
{
	vector<cv::Rect> srcRects;
	Size size(0, 0);
	vector<cv::Rect> resRects;

	int scale = 3;

	int slidefactor = 4;
	Mat cleanFrame = frame.clone();
	Mat croppedImage;

	char c;
	//String cropped_window = "Cropped image";
	//String filename = "pos/image-";
	//string input = ""; // std string for input
	//bool saved = false;
	//bool forceQuit = false;

	/*imshow("clean frame", cleanFrame);
	c = waitKey(0);*/

	Mat resized_frame(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_32FC1);
	resize(frame, resized_frame, resized_frame.size());

	cleanFrame = resized_frame.clone();

	Rect slidingWindow = Rect(0, 0, getImageHeight(), getImageHeight());

	int box_counter = 0;
	// how much to much the windows (x and y)
	int shiftXBy = slidingWindow.width / slidefactor; int shiftYBy = slidingWindow.height / slidefactor;

	for (int row = 0; slidingWindow.y + slidingWindow.height <= resized_frame.size().height; row++)
	{
		//cout << "row" << endl;
		for (int col = 0; slidingWindow.x + slidingWindow.width <= resized_frame.size().width; col++)
		{
			//cout << slidingWindow << endl;

			// get smaller image from original frame "clean" version (no rectangle)

			croppedImage = cleanFrame(slidingWindow);

			/*imshow("cropped", croppedImage);
			c = waitKey(0);*/

			// move sliding window  to the right
			if (isBee(croppedImage))
			{
				Rect scaled_sliding = Rect(slidingWindow.x * scale, slidingWindow.y * scale, slidingWindow.width * scale, slidingWindow.height * scale);

				srcRects.push_back(scaled_sliding);

				//rectangle(frame, scaled_sliding, Scalar(255, 0, 0), 1, 8, 0);
				//box_counter++;
			}
			slidingWindow.x += shiftXBy;
		}

		// reset x for new row
		slidingWindow.x = 0;
		// move sliding window  to the right
		slidingWindow.y += shiftYBy;
	}

	nms(srcRects, resRects, 0.1f);

	for (auto r : resRects)
	{
		rectangle(frame, r, Scalar(0, 255, 0), 2);
		box_counter++;
	}

	putText(frame, to_string(box_counter), cvPoint(30, 150), FONT_HERSHEY_COMPLEX_SMALL, 10, cvScalar(0, 255, 0), 1, CV_AA);
	//cout << box_counter << endl;
	return frame;
}

#endif<commit_msg>start of using parallel_for loop in croppingTool<commit_after>#ifndef Cropping
#define Cropping
#define _CRT_SECURE_NO_DEPRECATE
#include "croppingTool.h"
#include "ClassifierTraining.h"

#include "opencv2/objdetect.hpp"
//#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);
void cropImageAndSave(Mat frame);

CascadeClassifier car_cascade;
String window_name = "Capture - detection";
//String car_cascade_name = "../data/xml/cascade-bee.xml";
int counter;
int posCount;
int negCount;

class Scanloop : public ParallelLoopBody
{
public:
	Scanloop(Rect slidingWindow, Mat &croppedImage, Mat &cleanFrame, int scale, Mat &resized_frame, int shiftXBy, vector<Rect>& srcRects)
		: slidingWindow_l(slidingWindow_l), croppedImage_l(croppedImage), cleanFrame_l(cleanFrame), scale_l(scale), resized_frame_l(resized_frame), shiftXBy_l(shiftXBy), srcRects_l(srcRects)
	{
	}

	void operator()(const Range& range) const override
	{
		Mat croppedclone = croppedImage_l.clone();
		Rect slidingwindowclone = slidingWindow_l;
		for (int col = 0; slidingWindow_l.x + slidingWindow_l.width <= resized_frame_l.size().width; col++)
		{
			//cout << slidingWindow << endl;

			// get smaller image from original frame "clean" version (no rectangle)
			croppedclone = cleanFrame_l(slidingWindow_l);

			/*imshow("cropped", croppedImage);
			c = waitKey(0);*/

			// check if there is a bee in the cropped area
			if (isBee(croppedImage_l))
			{
				// move sliding window  to the right
				Rect scaled_sliding = Rect(slidingWindow_l.x * scale_l, slidingWindow_l.y * scale_l, slidingWindow_l.width * scale_l, slidingWindow_l.height * scale_l);

				// save the rectangles
				srcRects_l .push_back(scaled_sliding);

				//rectangle(frame, scaled_sliding, Scalar(255, 0, 0), 1, 8, 0);
				//box_counter++;
			}
			slidingwindowclone.x += shiftXBy_l;
		}
	}

private:
	Rect slidingWindow_l;
	Mat croppedImage_l;
	Mat cleanFrame_l;
	int scale_l;
	Mat resized_frame_l;
	int shiftXBy_l;
	vector<Rect>& srcRects_l;
};

void nms(const vector<Rect>& srcRects,vector<cv::Rect>& resRects,float thresh)
{
	resRects.clear();

	const size_t size = srcRects.size();
	if (!size)
	{
		return;
	}

	// Sort the bounding boxes by the bottom - right y - coordinate of the bounding box
	std::multimap<int, size_t> idxs;
	for (size_t i = 0; i < size; ++i)
	{
		idxs.insert(std::pair<int, size_t>(srcRects[i].br().y, i));
	}

	// keep looping while some indexes still remain in the indexes list
	while (idxs.size() > 0)
	{
		// grab the last rectangle
		auto lastElem = --std::end(idxs);
		const cv::Rect& rect1 = srcRects[lastElem->second];

		resRects.push_back(rect1);

		idxs.erase(lastElem);

		for (auto pos = std::begin(idxs); pos != std::end(idxs); )
		{
			// grab the current rectangle
			const cv::Rect& rect2 = srcRects[pos->second];

			float intArea = (rect1 & rect2).area();
			float unionArea = rect1.area() + rect2.area() - intArea;
			float overlap = intArea / unionArea;

			// if there is sufficient overlap, suppress the current bounding box
			if (overlap > thresh)
			{
				pos = idxs.erase(pos);
			}
			else
			{
				++pos;
			}
		}
	}
}

void cropImageAndSave(Mat frame) {
	Mat cleanFrame = frame.clone();
	Mat croppedImage;
	String cropped_window = "Cropped image";
	String filename = "pos/image-";
	string input = ""; // std string for input
	Rect slidingWindow = Rect(0, 0, 300, 300);
	bool saved = false;
	bool forceQuit = false;

	// how much to much the windows (x and y)
	int shiftXBy = slidingWindow.width/10; int shiftYBy = slidingWindow.height/10;

	for (int row = 0; slidingWindow.y + slidingWindow.height <= frame.size().height && !forceQuit; row++)
	{
		cout << "row" << endl;
		for (int col = 0; slidingWindow.x + slidingWindow.width <= frame.size().width && !forceQuit; col++)
		{
			cout << slidingWindow << endl;

			// get smaller image from original frame "clean" version (no rectangle)
			croppedImage = cleanFrame(slidingWindow);

			// show for user to confirm and label
			imshow(cropped_window, croppedImage);

			// show rectangles on image
			if (col % 2 == row % 2) {
				rectangle(frame, slidingWindow, Scalar(255, 0, 0), 1, 8, 0);
			}
			else {
				rectangle(frame, slidingWindow, Scalar(0, 255, 0), 1, 8, 0);
			}

			imshow(window_name, frame);

			char c = (char)waitKey(0);
			if (c == 27) { forceQuit = true; break; } // escape

			while (!saved) {
				if (c == 'q') {
					saved = true;
					forceQuit = true;
				}
				else if (c == 'g') {
					cout << "positive" << endl;
					imwrite("images/pos/pos-img" + std::to_string(posCount) + ".jpg", croppedImage);
					posCount++;
					saved = true;
				}
				else if (c == 'f') {
					cout << "negative" << endl;
					imwrite("images/neg/neg-img" + std::to_string(negCount) + ".jpg", croppedImage);
					negCount++;
					saved = true;
				}
				else if (c == 's') {
					cout << "skipping" << endl;
					saved = true;
				}
				else
				{
					c = (char)waitKey(0);
					if (c == 27) { forceQuit = true; break; }
				}
			}

			// move sliding window  to the right
			slidingWindow.x += shiftXBy;

			// new cropped image to save
			saved = false;
		}
		// reset x for new row
		slidingWindow.x = 0;
		// move sliding window  to the right
		slidingWindow.y += shiftYBy;

	}
}

void detectAndDisplay(Mat frame)
{
	Mat frame_gray;
	Mat resized_frame;
	Mat resized_frame_gray;

	std::vector<Rect> beesFound;

	// useScaling == detect on small image and draw on bigger one
	bool useScaling = true; // for detecting
	bool drawOnOriginal = true; // for drawing
	const int scale = 4;

	// ==========================================================
	// scale down image and find objects ========================
	if (useScaling) {
		// scale down the image by factor of variable "scale"
		resized_frame = Mat(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_8UC1);
		resize(frame, resized_frame, resized_frame.size());

		// turn to grayscale
		cvtColor(resized_frame, resized_frame_gray, COLOR_BGR2GRAY);
		equalizeHist(resized_frame_gray, resized_frame_gray);

		//-- Detect beesFound on scaled image
		car_cascade.detectMultiScale(resized_frame_gray, beesFound, 1.5, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
	}
	else {
		// turn to grayscale
		cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
		equalizeHist(frame_gray, frame_gray);

		// no scaling
		car_cascade.detectMultiScale(frame_gray, beesFound, 1.5, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

		// original values
		//face_cascade.detectMultiScale(frame_gray, beesFound, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
	}

	// ==========================================================
	// draw on the image to show the items ======================

	for (size_t i = 0; i < beesFound.size(); i++)
	{
		// print values for objects found
		cout << "x : " << beesFound[i].x << " | y : " << beesFound[i].y << " | width : " << beesFound[i].width << " | height : " << beesFound[i].height << endl;

		// draw on non-scaled image
		if (drawOnOriginal) {
			// draw rectangle
			rectangle(frame, Rect((beesFound[i].x*scale), (beesFound[i].y*scale), (beesFound[i].width*scale), (beesFound[i].height*scale)), Scalar(0, 245, 0), 1 * scale, 8, 0);
		}
		else {
			// draw rectangle
			rectangle(resized_frame, Rect(beesFound[i].x, beesFound[i].y, beesFound[i].width, beesFound[i].height), Scalar(0, 245, 0), 1, 8, 0);
		}
	}

	//-- Show what you got
	if (drawOnOriginal)
		cv::imshow(window_name, frame);
	else
		cv::imshow(window_name, resized_frame);
}

Mat DetectInFrame(Mat frame)
{
	vector<cv::Rect> srcRects;
	Size size(0, 0);
	vector<cv::Rect> resRects;

	int scale = 3;

	int slidefactor = 4;
	Mat cleanFrame = frame.clone();
	Mat croppedImage;

	char c;
	//String cropped_window = "Cropped image";
	//String filename = "pos/image-";
	//string input = ""; // std string for input
	//bool saved = false;
	//bool forceQuit = false;

	/*imshow("clean frame", cleanFrame);
	c = waitKey(0);*/

	Mat resized_frame(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_32FC1);
	resize(frame, resized_frame, resized_frame.size());

	cleanFrame = resized_frame.clone();

	Rect slidingWindow = Rect(0, 0, getImageHeight(), getImageHeight());

	int box_counter = 0;
	// how much to much the windows (x and y)
	int shiftXBy = slidingWindow.width / slidefactor; int shiftYBy = slidingWindow.height / slidefactor;

	for (int row = 0; slidingWindow.y + slidingWindow.height <= resized_frame.size().height; row++)
	{
		///attempt at parallizing
		/*Scanloop parallelScan(slidingWindow,croppedImage, cleanFrame, scale, resized_frame, shiftXBy, srcRects);
		parallel_for_(Range{ slidingWindow.x + slidingWindow.width,resized_frame.size().width }, parallelScan);*/

		//cout << "row" << endl;
		for (int col = 0; slidingWindow.x + slidingWindow.width <= resized_frame.size().width; col++)
		{
			//cout << slidingWindow << endl;

			// get smaller image from original frame "clean" version (no rectangle)
			croppedImage = cleanFrame(slidingWindow);

			/*imshow("cropped", croppedImage);
			c = waitKey(0);*/

			// check if there is a bee in the cropped area
			if (isBee(croppedImage))
			{
				// move sliding window  to the right
				Rect scaled_sliding = Rect(slidingWindow.x * scale, slidingWindow.y * scale, slidingWindow.width * scale, slidingWindow.height * scale);

				// save the rectangles
				srcRects.push_back(scaled_sliding);

				//rectangle(frame, scaled_sliding, Scalar(255, 0, 0), 1, 8, 0);
				//box_counter++;
			}
			slidingWindow.x += shiftXBy;
		}

		// reset x for new row
		slidingWindow.x = 0;
		// move sliding window  to the right
		slidingWindow.y += shiftYBy;
	}

	// perform non-maximum suppression (reduce rect)
	nms(srcRects, resRects, 0.1f);

	// draw the rectangles
	for (auto r : resRects)
	{
		rectangle(frame, r, Scalar(0, 255, 0), 2);
		box_counter++;
	}

	// display rect number
	putText(frame, to_string(box_counter), cvPoint(30, 150), FONT_HERSHEY_COMPLEX_SMALL, 10, cvScalar(0, 255, 0), 1, CV_AA);
	//cout << box_counter << endl;
	return frame;
}

#endif<|endoftext|>


<commit_before>#ifndef __EVENT_HXX
#define __EVENT_HXX

#include <sal/types.h>

#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/implbase3.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/xml/dom/events/XEventTarget.hpp>
#include <com/sun/star/util/Time.hpp>

#include "../dom/node.hxx"

#include <libxml/tree.h>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::dom::events;

namespace DOM {namespace events
{
class CEvent : public cppu::WeakImplHelper1< XEvent >
{
friend class CEventDispatcher;
friend class CNode;
friend class CDocument;
friend class CElement;
friend class CText;
friend class CCharacterData;
friend class CAttr;

private:
    sal_Bool m_canceled;

protected:
    OUString m_eventType;
    Reference< XEventTarget > m_target;
    Reference< XEventTarget > m_currentTarget;
    //xmlNodePtr m_target;
    //xmlNodePtr m_currentTarget;
    PhaseType m_phase;
    sal_Bool m_bubbles;
    sal_Bool m_cancelable;
    com::sun::star::util::Time m_time;

public:

    CEvent() : m_canceled(sal_False){}

    virtual ~CEvent();
    virtual OUString SAL_CALL getType() throw (RuntimeException);
    virtual Reference< XEventTarget > SAL_CALL getTarget() throw (RuntimeException);
    virtual Reference< XEventTarget > SAL_CALL getCurrentTarget() throw (RuntimeException);
    virtual PhaseType SAL_CALL getEventPhase() throw (RuntimeException);
    virtual sal_Bool SAL_CALL getBubbles() throw (RuntimeException);
    virtual sal_Bool SAL_CALL getCancelable() throw (RuntimeException);
    virtual com::sun::star::util::Time SAL_CALL getTimeStamp() throw (RuntimeException);
    virtual void SAL_CALL stopPropagation() throw (RuntimeException);
    virtual void SAL_CALL preventDefault() throw (RuntimeException);
    virtual void SAL_CALL initEvent(
        const OUString& eventTypeArg,
        sal_Bool canBubbleArg,
        sal_Bool cancelableArg)  throw (RuntimeException);
};
}}
#endif
<commit_msg>INTEGRATION: CWS updchk10 (1.3.70); FILE MERGED 2007/09/14 16:19:52 lo 1.3.70.1: #i81589# xml serialization<commit_after>#ifndef __EVENT_HXX
#define __EVENT_HXX

#include <sal/types.h>

#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/implbase3.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/xml/dom/events/XEventTarget.hpp>
#include <com/sun/star/util/Time.hpp>

#include "../dom/node.hxx"

#include <libxml/tree.h>

using namespace com::sun::star::uno;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::dom::events;

namespace DOM {namespace events
{
class CEvent : public cppu::WeakImplHelper1< XEvent >
{
friend class CEventDispatcher;
friend class CNode;
friend class CDocument;
friend class CElement;
friend class CText;
friend class CCharacterData;
friend class CAttr;

private:
    sal_Bool m_canceled;

protected:
    OUString m_eventType;
    Reference< XEventTarget > m_target;
    Reference< XEventTarget > m_currentTarget;
    //xmlNodePtr m_target;
    //xmlNodePtr m_currentTarget;
    PhaseType m_phase;
    sal_Bool m_bubbles;
    sal_Bool m_cancelable;
    com::sun::star::util::Time m_time;

public:

    CEvent() : m_canceled(sal_False){}

    virtual ~CEvent();
    virtual OUString SAL_CALL getType() throw (RuntimeException);
    virtual Reference< XEventTarget > SAL_CALL getTarget() throw (RuntimeException);
    virtual Reference< XEventTarget > SAL_CALL getCurrentTarget() throw (RuntimeException);
    virtual PhaseType SAL_CALL getEventPhase() throw (RuntimeException);
    virtual sal_Bool SAL_CALL getBubbles() throw (RuntimeException);
    virtual sal_Bool SAL_CALL getCancelable() throw (RuntimeException);
    virtual com::sun::star::util::Time SAL_CALL getTimeStamp() throw (RuntimeException);
    virtual void SAL_CALL stopPropagation() throw (RuntimeException);
    virtual void SAL_CALL preventDefault() throw (RuntimeException);
    virtual void SAL_CALL initEvent(
        const OUString& eventTypeArg,
        sal_Bool canBubbleArg,
        sal_Bool cancelableArg)  throw (RuntimeException);
};
}}
#endif
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////////
// Original authors: SangGi Do(sanggido@unist.ac.kr), Mingyu Woo(mwoo@eng.ucsd.edu)
//          (respective Ph.D. advisors: Seokhyeong Kang, Andrew B. Kahng)
// Rewrite by James Cherry, Parallax Software, Inc.

// BSD 3-Clause License
//
// Copyright (c) 2019, James Cherry, Parallax Software, Inc.
// Copyright (c) 2018, SangGi Do and Mingyu Woo
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
///////////////////////////////////////////////////////////////////////////////

#include <cmath>
#include <limits>
#include "openroad/Error.hh"
#include "opendp/Opendp.h"

namespace opendp {

using std::cerr;
using std::cout;
using std::endl;
using std::max;
using std::min;
using std::abs;
using std::round;
using std::numeric_limits;

using ord::error;

void Opendp::initGrid() {
  // Make pixel grid
  grid_ = makeGrid();

  // Fragmented Row Handling
  for(auto db_row : block_->getRows()) {
    int orig_x, orig_y;
    db_row->getOrigin(orig_x, orig_y);

    int x_start = (orig_x - core_.xMin()) / site_width_;
    int y_start = (orig_y - core_.yMin()) / row_height_;

    int x_end = x_start + db_row->getSiteCount();
    int y_end = y_start + 1;

    for(int i = x_start; i < x_end; i++) {
      for(int j = y_start; j < y_end; j++) {
        grid_[j][i].is_valid = true;
      }
    }
  }

  // fixed cell marking
  fixed_cell_assign();
  // group mapping & x_axis dummycell insertion
  group_pixel_assign2();
  // y axis dummycell insertion
  group_pixel_assign();
}

Grid *
Opendp::makeGrid()
{
  Grid *grid = new Pixel*[row_count_];
  for(int i = 0; i < row_count_; i++) {
    grid[i] = new Pixel[row_site_count_];

    for(int j = 0; j < row_site_count_; j++) {
      Pixel &pixel = grid[i][j];
      pixel.grid_y_ = i;
      pixel.grid_x_ = j;
      pixel.cell = nullptr;
      pixel.group_ = nullptr;
      pixel.util = 0.0;
      pixel.is_valid = false;
    }
  }
  return grid;
}

void
Opendp::deleteGrid(Grid *grid)
{
  if (grid) {
    for(int i = 0; i < row_count_; i++) {
      delete [] grid[i];
    }
    delete grid;
  }
}

////////////////////////////////////////////////////////////////

void Opendp::fixed_cell_assign() {
  for(Cell &cell : cells_) {
    if(isFixed(&cell)) {
      int y_start = gridY(&cell);
      int y_end = gridEndY(&cell);
      int x_start = gridPaddedX(&cell);
      int x_end = gridPaddedEndX(&cell);

      int y_start_rf = 0;
      int y_end_rf = gridEndY();
      int x_start_rf = 0;
      int x_end_rf = gridEndX();

      y_start = max(y_start, y_start_rf);
      y_end = min(y_end, y_end_rf);
      x_start = max(x_start, x_start_rf);
      x_end = min(x_end, x_end_rf);

#ifdef ODP_DEBUG
      cout << "FixedCellAssign: cell_name : "
           << cell.name() << endl;
      cout << "FixedCellAssign: y_start : " << y_start << endl;
      cout << "FixedCellAssign: y_end   : " << y_end << endl;
      cout << "FixedCellAssign: x_start : " << x_start << endl;
      cout << "FixedCellAssign: x_end   : " << x_end << endl;
#endif
      for(int j = y_start; j < y_end; j++) {
        for(int k = x_start; k < x_end; k++) {
	  Pixel &pixel = grid_[j][k];
          pixel.cell = &cell;
          pixel.util = 1.0;
        }
      }
    }
  }
}

void Opendp::group_cell_region_assign() {
  for(Group& group : groups_) {
    int64_t site_count = 0;
    for(int j = 0; j < row_count_; j++) {
      for(int k = 0; k < row_site_count_; k++) {
	Pixel &pixel = grid_[j][k];
	if(pixel.is_valid
	   && pixel.group_ == &group)
	  site_count++;
      }
    }
    int64_t area = site_count * site_width_ * row_height_;

    int64_t cell_area = 0;
    for(Cell* cell : group.cells_) {
      cell_area += cell->area();

      for(Rect &rect : group.regions) {
	if (check_inside(cell, &rect))
	  cell->region_ = ▭
      }
      if(cell->region_ == nullptr)
	cell->region_ = &group.regions[0];
    }
    group.util = static_cast<double>(cell_area) / area;
  }
}

void Opendp::group_pixel_assign2() {
  for(int i = 0; i < row_count_; i++) {
    for(int j = 0; j < row_site_count_; j++) {
      Rect sub;
      sub.init(j * site_width_, i * row_height_,
	       (j + 1) * site_width_, (i + 1) * row_height_);
      for(Group& group : groups_) {
        for(Rect &rect : group.regions) {
	  if(!check_inside(sub, rect) &&
             check_overlap(sub, rect)) {
            Pixel &pixel = grid_[i][j];
	    pixel.util = 0.0;
            pixel.cell = &dummy_cell_;
            pixel.is_valid = false;
          }
        }
      }
    }
  }
}

void Opendp::group_pixel_assign() {
  for(int i = 0; i < row_count_; i++) {
    for(int j = 0; j < row_site_count_; j++) {
      grid_[i][j].util = 0.0;
    }
  }

  for(Group& group : groups_) {
    for(Rect &rect : group.regions) {
      int row_start = divCeil(rect.yMin(), row_height_);
      int row_end = divFloor(rect.yMax(), row_height_);

      for(int k = row_start; k < row_end; k++) {
        int col_start = divCeil(rect.xMin(), site_width_);
        int col_end = divFloor(rect.xMax(), site_width_);

        for(int l = col_start; l < col_end; l++) {
          grid_[k][l].util += 1.0;
        }
        if(rect.xMin() % site_width_ != 0) {
          grid_[k][col_start].util -=
	    (rect.xMin() % site_width_) / static_cast<double>(site_width_);
        }
        if(rect.xMax() % site_width_ != 0) {
          grid_[k][col_end - 1].util -=
	    ((site_width_ - rect.xMax()) % site_width_) / static_cast<double>(site_width_);
        }
      }
    }
    for(Rect& rect : group.regions) {
      int row_start = divCeil(rect.yMin(), row_height_);
      int row_end = divFloor(rect.yMax(), row_height_);

      for(int k = row_start; k < row_end; k++) {
        int col_start = divCeil(rect.xMin(), site_width_);
        int col_end = divFloor(rect.xMax(), site_width_);

        // Assign group to each pixel.
        for(int l = col_start; l < col_end; l++) {
	  Pixel &pixel = grid_[k][l];
          if(pixel.util == 1.0) {
            pixel.group_ = &group;
	    pixel.is_valid = true;
            pixel.util = 1.0;
	  }
          else if(pixel.util > 0.0 && pixel.util < 1.0) {
            pixel.cell = &dummy_cell_;
            pixel.util = 0.0;
            pixel.is_valid = false;
          }
        }
      }
    }
  }
}

void Opendp::erase_pixel(Cell* cell) {
  if(!(isFixed(cell) || !cell->is_placed_)) {
    int x_step = gridPaddedWidth(cell);
    int y_step = gridHeight(cell);
    for(int i = gridY(cell); i < gridY(cell) + y_step; i++) {
      for(int j = gridPaddedX(cell); j < gridPaddedX(cell) + x_step; j++) {
	Pixel &pixel = grid_[i][j];
	pixel.cell = nullptr;
	pixel.util = 0;
      }
    }
    cell->x_ = 0;
    cell->y_ = 0;
    cell->is_placed_ = false;
    cell->hold_ = false;
  }
}

void Opendp::paint_pixel(Cell* cell, int grid_x, int grid_y) {
  assert(!cell->is_placed_);
  int x_step = gridPaddedWidth(cell);
  int y_step = gridHeight(cell);

  setGridPaddedLoc(cell, grid_x, grid_y);
  cell->is_placed_ = true;

#ifdef ODP_DEBUG
  cout << "paint cell : " << cell->name() << endl;
  cout << "x_ - y_ : " << cell->x_ << " - "
       << cell->y_ << endl;
  cout << "x_step - y_step : " << x_step << " - " << y_step << endl;
  cout << "grid_x - grid_y : " << grid_x << " - " << grid_y << endl;
#endif

  for(int i = grid_y; i < grid_y + y_step; i++) {
    for(int j = grid_x; j < grid_x + x_step; j++) {
      Pixel &pixel = grid_[i][j];
      if(pixel.cell != nullptr) {
        error("Cannot paint grid because it is already occupied.");
      }
      else {
        pixel.cell = cell;
        pixel.util = 1.0;
      }
    }
  }
  if(max_cell_height_ > 1) {
    if(y_step % 2 == 1) {
      if(rowTopPower(grid_y) != topPower(cell))
        cell->orient_ = dbOrientType::MX;
      else
        cell->orient_ = dbOrientType::R0;
    }
  }
  else {
    cell->orient_ = rowOrient(grid_y);
  }
}

}  // namespace opendp
<commit_msg>opendp erase_pixel do not zero xy<commit_after>/////////////////////////////////////////////////////////////////////////////
// Original authors: SangGi Do(sanggido@unist.ac.kr), Mingyu Woo(mwoo@eng.ucsd.edu)
//          (respective Ph.D. advisors: Seokhyeong Kang, Andrew B. Kahng)
// Rewrite by James Cherry, Parallax Software, Inc.

// BSD 3-Clause License
//
// Copyright (c) 2019, James Cherry, Parallax Software, Inc.
// Copyright (c) 2018, SangGi Do and Mingyu Woo
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
///////////////////////////////////////////////////////////////////////////////

#include <cmath>
#include <limits>
#include "openroad/Error.hh"
#include "opendp/Opendp.h"

namespace opendp {

using std::cerr;
using std::cout;
using std::endl;
using std::max;
using std::min;
using std::abs;
using std::round;
using std::numeric_limits;

using ord::error;

void Opendp::initGrid() {
  // Make pixel grid
  grid_ = makeGrid();

  // Fragmented Row Handling
  for(auto db_row : block_->getRows()) {
    int orig_x, orig_y;
    db_row->getOrigin(orig_x, orig_y);

    int x_start = (orig_x - core_.xMin()) / site_width_;
    int y_start = (orig_y - core_.yMin()) / row_height_;

    int x_end = x_start + db_row->getSiteCount();
    int y_end = y_start + 1;

    for(int i = x_start; i < x_end; i++) {
      for(int j = y_start; j < y_end; j++) {
        grid_[j][i].is_valid = true;
      }
    }
  }

  // fixed cell marking
  fixed_cell_assign();
  // group mapping & x_axis dummycell insertion
  group_pixel_assign2();
  // y axis dummycell insertion
  group_pixel_assign();
}

Grid *
Opendp::makeGrid()
{
  Grid *grid = new Pixel*[row_count_];
  for(int i = 0; i < row_count_; i++) {
    grid[i] = new Pixel[row_site_count_];

    for(int j = 0; j < row_site_count_; j++) {
      Pixel &pixel = grid[i][j];
      pixel.grid_y_ = i;
      pixel.grid_x_ = j;
      pixel.cell = nullptr;
      pixel.group_ = nullptr;
      pixel.util = 0.0;
      pixel.is_valid = false;
    }
  }
  return grid;
}

void
Opendp::deleteGrid(Grid *grid)
{
  if (grid) {
    for(int i = 0; i < row_count_; i++) {
      delete [] grid[i];
    }
    delete grid;
  }
}

////////////////////////////////////////////////////////////////

void Opendp::fixed_cell_assign() {
  for(Cell &cell : cells_) {
    if(isFixed(&cell)) {
      int y_start = gridY(&cell);
      int y_end = gridEndY(&cell);
      int x_start = gridPaddedX(&cell);
      int x_end = gridPaddedEndX(&cell);

      int y_start_rf = 0;
      int y_end_rf = gridEndY();
      int x_start_rf = 0;
      int x_end_rf = gridEndX();

      y_start = max(y_start, y_start_rf);
      y_end = min(y_end, y_end_rf);
      x_start = max(x_start, x_start_rf);
      x_end = min(x_end, x_end_rf);

#ifdef ODP_DEBUG
      cout << "FixedCellAssign: cell_name : "
           << cell.name() << endl;
      cout << "FixedCellAssign: y_start : " << y_start << endl;
      cout << "FixedCellAssign: y_end   : " << y_end << endl;
      cout << "FixedCellAssign: x_start : " << x_start << endl;
      cout << "FixedCellAssign: x_end   : " << x_end << endl;
#endif
      for(int j = y_start; j < y_end; j++) {
        for(int k = x_start; k < x_end; k++) {
	  Pixel &pixel = grid_[j][k];
          pixel.cell = &cell;
          pixel.util = 1.0;
        }
      }
    }
  }
}

void Opendp::group_cell_region_assign() {
  for(Group& group : groups_) {
    int64_t site_count = 0;
    for(int j = 0; j < row_count_; j++) {
      for(int k = 0; k < row_site_count_; k++) {
	Pixel &pixel = grid_[j][k];
	if(pixel.is_valid
	   && pixel.group_ == &group)
	  site_count++;
      }
    }
    int64_t area = site_count * site_width_ * row_height_;

    int64_t cell_area = 0;
    for(Cell* cell : group.cells_) {
      cell_area += cell->area();

      for(Rect &rect : group.regions) {
	if (check_inside(cell, &rect))
	  cell->region_ = ▭
      }
      if(cell->region_ == nullptr)
	cell->region_ = &group.regions[0];
    }
    group.util = static_cast<double>(cell_area) / area;
  }
}

void Opendp::group_pixel_assign2() {
  for(int i = 0; i < row_count_; i++) {
    for(int j = 0; j < row_site_count_; j++) {
      Rect sub;
      sub.init(j * site_width_, i * row_height_,
	       (j + 1) * site_width_, (i + 1) * row_height_);
      for(Group& group : groups_) {
        for(Rect &rect : group.regions) {
	  if(!check_inside(sub, rect) &&
             check_overlap(sub, rect)) {
            Pixel &pixel = grid_[i][j];
	    pixel.util = 0.0;
            pixel.cell = &dummy_cell_;
            pixel.is_valid = false;
          }
        }
      }
    }
  }
}

void Opendp::group_pixel_assign() {
  for(int i = 0; i < row_count_; i++) {
    for(int j = 0; j < row_site_count_; j++) {
      grid_[i][j].util = 0.0;
    }
  }

  for(Group& group : groups_) {
    for(Rect &rect : group.regions) {
      int row_start = divCeil(rect.yMin(), row_height_);
      int row_end = divFloor(rect.yMax(), row_height_);

      for(int k = row_start; k < row_end; k++) {
        int col_start = divCeil(rect.xMin(), site_width_);
        int col_end = divFloor(rect.xMax(), site_width_);

        for(int l = col_start; l < col_end; l++) {
          grid_[k][l].util += 1.0;
        }
        if(rect.xMin() % site_width_ != 0) {
          grid_[k][col_start].util -=
	    (rect.xMin() % site_width_) / static_cast<double>(site_width_);
        }
        if(rect.xMax() % site_width_ != 0) {
          grid_[k][col_end - 1].util -=
	    ((site_width_ - rect.xMax()) % site_width_) / static_cast<double>(site_width_);
        }
      }
    }
    for(Rect& rect : group.regions) {
      int row_start = divCeil(rect.yMin(), row_height_);
      int row_end = divFloor(rect.yMax(), row_height_);

      for(int k = row_start; k < row_end; k++) {
        int col_start = divCeil(rect.xMin(), site_width_);
        int col_end = divFloor(rect.xMax(), site_width_);

        // Assign group to each pixel.
        for(int l = col_start; l < col_end; l++) {
	  Pixel &pixel = grid_[k][l];
          if(pixel.util == 1.0) {
            pixel.group_ = &group;
	    pixel.is_valid = true;
            pixel.util = 1.0;
	  }
          else if(pixel.util > 0.0 && pixel.util < 1.0) {
            pixel.cell = &dummy_cell_;
            pixel.util = 0.0;
            pixel.is_valid = false;
          }
        }
      }
    }
  }
}

void Opendp::erase_pixel(Cell* cell) {
  if(!(isFixed(cell) || !cell->is_placed_)) {
    int x_step = gridPaddedWidth(cell);
    int y_step = gridHeight(cell);
    for(int i = gridY(cell); i < gridY(cell) + y_step; i++) {
      for(int j = gridPaddedX(cell); j < gridPaddedX(cell) + x_step; j++) {
	Pixel &pixel = grid_[i][j];
	pixel.cell = nullptr;
	pixel.util = 0;
      }
    }
    cell->is_placed_ = false;
    cell->hold_ = false;
  }
}

void Opendp::paint_pixel(Cell* cell, int grid_x, int grid_y) {
  assert(!cell->is_placed_);
  int x_step = gridPaddedWidth(cell);
  int y_step = gridHeight(cell);

  setGridPaddedLoc(cell, grid_x, grid_y);
  cell->is_placed_ = true;

#ifdef ODP_DEBUG
  cout << "paint cell : " << cell->name() << endl;
  cout << "x_ - y_ : " << cell->x_ << " - "
       << cell->y_ << endl;
  cout << "x_step - y_step : " << x_step << " - " << y_step << endl;
  cout << "grid_x - grid_y : " << grid_x << " - " << grid_y << endl;
#endif

  for(int i = grid_y; i < grid_y + y_step; i++) {
    for(int j = grid_x; j < grid_x + x_step; j++) {
      Pixel &pixel = grid_[i][j];
      if(pixel.cell != nullptr) {
        error("Cannot paint grid because it is already occupied.");
      }
      else {
        pixel.cell = cell;
        pixel.util = 1.0;
      }
    }
  }
  if(max_cell_height_ > 1) {
    if(y_step % 2 == 1) {
      if(rowTopPower(grid_y) != topPower(cell))
        cell->orient_ = dbOrientType::MX;
      else
        cell->orient_ = dbOrientType::R0;
    }
  }
  else {
    cell->orient_ = rowOrient(grid_y);
  }
}

}  // namespace opendp
<|endoftext|>


<commit_before>#include <stdio.h>
#include <memory.h>
#include <assert.h>
#include <stdlib.h>

#include "halide_benchmark.h"
#include "process.h"

void usage(char *prg_name) {
    const char usage_string[] = " Run a bunch of small filters\n\n"
                                "\t -m -> hvx_mode - options are hvx64, hvx128. Default is to run hvx64, hvx128 and cpu\n"
                                "\t -n -> number of iterations\n"
                                "\t -h -> print this help message\n";
    printf ("%s - %s", prg_name, usage_string);

}

const char *to_string(bmark_run_mode_t mode) {
    if (mode == bmark_run_mode_t::hvx64) {
        return "(64 byte mode)";
    } else if (mode == bmark_run_mode_t::hvx128) {
        return "(128 byte mode)";
    } else {
        return "(cpu)";
    }
}

int main(int argc, char **argv) {
    // Set some defaults first.
    const int W = 1024;
    const int H = 1024;
    std::vector<bmark_run_mode_t> modes;
    int iterations = 10;

    // Process command line args.
    for (int i = 1; i < argc; ++i) {
        if (argv[i][0] == '-') {
            switch (argv[i][1]) {
            case 'm':
                {
                    std::string mode_to_run = argv[i+1];
                    if (mode_to_run == "hvx64") {
                        modes.push_back(bmark_run_mode_t::hvx64);
                    } else if (mode_to_run == "hvx128") {
                        modes.push_back(bmark_run_mode_t::hvx128);
                    } else if (mode_to_run == "cpu") {
                        modes.push_back(bmark_run_mode_t::cpu);
                    } else {
                        usage(argv[0]);
                        abort();
                    }
                    i++;
                }
                break;
            case 'h':
                usage(argv[0]);
                return 0;
                break;
            case 'n':
                iterations = atoi(argv[i+1]);
                i++;
                break;
            }
        }
    }
    if (modes.empty()) {
        modes.push_back(bmark_run_mode_t::hvx64);
        modes.push_back(bmark_run_mode_t::hvx128);
        modes.push_back(bmark_run_mode_t::cpu);
    }
    Conv3x3a16Descriptor conv3x3a16_pipeline(W, H);
    Dilate3x3Descriptor dilate3x3_pipeine(W, H);
    Median3x3Descriptor median3x3_pipeline(W, H);
    Gaussian5x5Descriptor gaussian5x5_pipeline(W, H);
    SobelDescriptor sobel_pipeline(W, H);
    Conv3x3a32Descriptor conv3x3a32_pipeline(W, H);

    std::vector<PipelineDescriptorBase *> pipelines = {&conv3x3a16_pipeline, &dilate3x3_pipeine, &median3x3_pipeline,
                                                       &gaussian5x5_pipeline, &sobel_pipeline, &conv3x3a32_pipeline};

    for (bmark_run_mode_t m : modes) {
        for (PipelineDescriptorBase *p : pipelines) {
            if (!p->defined()) {
                continue;
            }
            p->init();
            printf ("Running %s...\n", p->name());

            // To avoid the cost of powering HVX on in each call of the
            // pipeline, power it on once now. Also, set Hexagon performance to turbo.
            halide_hexagon_set_performance_mode(NULL, halide_hexagon_power_turbo);
            halide_hexagon_power_hvx_on(NULL);

            double time = benchmark(iterations, 10, [&]() {
                    int result = p->run(m);
                    if (result != 0) {
                        printf("pipeline failed! %d\n", result);
                    }
                });
            printf("Done, time (%s): %g s %s\n", p->name(), time, to_string(m));

            // We're done with HVX, power it off, and reset the performance mode
            // to default to save power.
            halide_hexagon_power_hvx_off(NULL);
            halide_hexagon_set_performance_mode(NULL, halide_hexagon_power_default);

            if (!p->verify(W, H)) {
                abort();
            }
            p->finalize();
        }
    }

    printf("Success!\n");
    return 0;
}
<commit_msg>Fix process.cpp in new hexagon_benchmark<commit_after>#include <stdio.h>
#include <memory.h>
#include <assert.h>
#include <stdlib.h>

#include "halide_benchmark.h"
#include "process.h"

void usage(char *prg_name) {
    const char usage_string[] = " Run a bunch of small filters\n\n"
                                "\t -m -> hvx_mode - options are hvx64, hvx128. Default is to run hvx64, hvx128 and cpu\n"
                                "\t -n -> number of iterations\n"
                                "\t -h -> print this help message\n";
    printf ("%s - %s", prg_name, usage_string);

}

const char *to_string(bmark_run_mode_t mode) {
    if (mode == bmark_run_mode_t::hvx64) {
        return "(64 byte mode)";
    } else if (mode == bmark_run_mode_t::hvx128) {
        return "(128 byte mode)";
    } else {
        return "(cpu)";
    }
}

int main(int argc, char **argv) {
    // Set some defaults first.
    const int W = 1024;
    const int H = 1024;
    std::vector<bmark_run_mode_t> modes;
    int iterations = 10;

    // Process command line args.
    for (int i = 1; i < argc; ++i) {
        if (argv[i][0] == '-') {
            switch (argv[i][1]) {
            case 'm':
                {
                    std::string mode_to_run = argv[i+1];
                    if (mode_to_run == "hvx64") {
                        modes.push_back(bmark_run_mode_t::hvx64);
                    } else if (mode_to_run == "hvx128") {
                        modes.push_back(bmark_run_mode_t::hvx128);
                    } else if (mode_to_run == "cpu") {
                        modes.push_back(bmark_run_mode_t::cpu);
                    } else {
                        usage(argv[0]);
                        abort();
                    }
                    i++;
                }
                break;
            case 'h':
                usage(argv[0]);
                return 0;
                break;
            case 'n':
                iterations = atoi(argv[i+1]);
                i++;
                break;
            }
        }
    }
    if (modes.empty()) {
        modes.push_back(bmark_run_mode_t::hvx64);
        modes.push_back(bmark_run_mode_t::hvx128);
        modes.push_back(bmark_run_mode_t::cpu);
    }
    Conv3x3a16Descriptor conv3x3a16_pipeline(W, H);
    Dilate3x3Descriptor dilate3x3_pipeine(W, H);
    Median3x3Descriptor median3x3_pipeline(W, H);
    Gaussian5x5Descriptor gaussian5x5_pipeline(W, H);
    SobelDescriptor sobel_pipeline(W, H);
    Conv3x3a32Descriptor conv3x3a32_pipeline(W, H);

    std::vector<PipelineDescriptorBase *> pipelines = {&conv3x3a16_pipeline, &dilate3x3_pipeine, &median3x3_pipeline,
                                                       &gaussian5x5_pipeline, &sobel_pipeline, &conv3x3a32_pipeline};

    for (bmark_run_mode_t m : modes) {
        for (PipelineDescriptorBase *p : pipelines) {
            if (!p->defined()) {
                continue;
            }
            p->init();
            printf ("Running %s...\n", p->name());

            // To avoid the cost of powering HVX on in each call of the
            // pipeline, power it on once now. Also, set Hexagon performance to turbo.
            halide_hexagon_set_performance_mode(NULL, halide_hexagon_power_turbo);
            halide_hexagon_power_hvx_on(NULL);

            double time = Halide::Tools::benchmark(iterations, 10, [&]() {
                    int result = p->run(m);
                    if (result != 0) {
                        printf("pipeline failed! %d\n", result);
                    }
                });
            printf("Done, time (%s): %g s %s\n", p->name(), time, to_string(m));

            // We're done with HVX, power it off, and reset the performance mode
            // to default to save power.
            halide_hexagon_power_hvx_off(NULL);
            halide_hexagon_set_performance_mode(NULL, halide_hexagon_power_default);

            if (!p->verify(W, H)) {
                abort();
            }
            p->finalize();
        }
    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>