<commit_before>#include <array>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <math.h>
#include <omp.h>

#include <xmmintrin.h>
#include <pmmintrin.h>

#include "main.hpp"
#include "min_heap.hpp"
#include "universe.hpp"

#define IACA_SSC_MARK( MARK_ID )						\
__asm__ __volatile__ (								\
					  "\n\t  movl $"#MARK_ID", %%ebx"	\
					  "\n\t  .byte 0x64, 0x67, 0x90"	\
					  : : : "memory" );

#define IACA_START {IACA_SSC_MARK(111)}
#define IACA_END {IACA_SSC_MARK(222)}

#define AU_TO_M 149597870700.0
#define LY_TO_M 9460730472580800.0

#if defined(__AVX__)
#include <immintrin.h>
#define VECTOR_WIDTH 8
typedef __m256 vector_type;
#elif defined(__SSE__)
#define VECTOR_WIDTH 4
typedef __m128 vector_type;
#else
#error "Here's a nickel kid, buy yourself a real computer."
#endif

enum measurement_point {
    MB_TOTAL_START, MB_TOTAL_END,
    MB_INIT_START, MB_INIT_END,
    MB_SYSTEM_START, MB_SYSTEM_END,
    MB_GATE_START, MB_GATE_END,
    MB_JUMP_START, MB_JUMP_END,
    MB_SELECT_START, MB_SELECT_END,
    MB_MAX
};

static struct timespec mbt[MB_MAX];
static long mba[MB_MAX] = {0};

static void update_timers(enum measurement_point p) {
    if (verbose >= 1) {
        clock_gettime(CLOCK_MONOTONIC, &mbt[p]);
        mba[p] += time_diff(&mbt[p - 1], &mbt[p]);
    }
}

inline float __attribute__((always_inline)) entity_distance(Celestial *a, Celestial *b) {
    if (a->system != b->system) return INFINITY;

    float dx = a->pos[0] - b->pos[0];
    float dy = a->pos[1] - b->pos[1];
    float dz = a->pos[2] - b->pos[2];

    return sqrt(dx * dx + dy * dy + dz * dz);
}

double get_time(double distance, double v_wrp) {
    double k_accel = v_wrp;
    double k_decel = (v_wrp / 3) < 2 ? (v_wrp / 3) : 2;

    double v_max_wrp = v_wrp * AU_TO_M;

    double d_accel = AU_TO_M;
    double d_decel = v_max_wrp / k_decel;

    double d_min = d_accel + d_decel;

    double cruise_time = 0;

    if (d_min > distance) {
        v_max_wrp = distance * k_accel * k_decel / (k_accel + k_decel);
    } else {
        cruise_time = (distance - d_min) / v_max_wrp;
    }

    double t_accel = log(v_max_wrp / k_accel) / k_accel;
    double t_decel = log(v_max_wrp / 100) / k_decel;

    return cruise_time + t_accel + t_decel;
}

Route *dijkstra(Universe &u, Celestial *src, Celestial *dst, struct trip *parameters) {
    update_timers(MB_TOTAL_START);
    update_timers(MB_INIT_START);

    int *prev = (int *) malloc(u.entity_count * sizeof(int));
    int *vist = (int *) malloc(u.entity_count * sizeof(int));
    float *cost = (float *) malloc(u.entity_count * sizeof(float));
    enum movement_type *type = (enum movement_type *) malloc(u.entity_count * sizeof(enum movement_type));

    float *sys_c = (float *) calloc(4 * (u.system_count + VECTOR_WIDTH), sizeof(float));
    float *sys_x = (float *) calloc((u.system_count + VECTOR_WIDTH), sizeof(float));
    float *sys_y = (float *) calloc((u.system_count + VECTOR_WIDTH), sizeof(float));
    float *sys_z = (float *) calloc((u.system_count + VECTOR_WIDTH), sizeof(float));

    MinHeap<float, int> queue(u.entity_count);

    float distance, cur_cost;

    for (int i = 0; i < u.system_count; i++) {
        _mm_store_ps(&sys_c[i * 4], u.systems[i].pos);
        sys_x[i] = u.systems[i].pos[0];
        sys_y[i] = u.systems[i].pos[1];
        sys_z[i] = u.systems[i].pos[2];
    }

    for (int i = 0; i < u.entity_count; i++) {
        if (!u.entities[i].destination && u.entities[i].seq_id != src->seq_id && u.entities[i].seq_id != dst->seq_id) continue;

        vist[i] = i == src->seq_id ? 1 : 0;
        prev[i] = i == src->seq_id ? -2 : -1;
        type[i] = STRT;
        cost[i] = i == src->seq_id ? 0.0 : INFINITY;

        queue.insert(cost[i], i);
    }

    int tmp, v;
    int loops = 0;
    float sqjr = pow(parameters->jump_range * LY_TO_M, 2.0);

    vector_type x_vec, y_vec, z_vec;
    vector_type x_src_vec, y_src_vec, z_src_vec;

    System *sys, *jsys;
    Celestial *ent;

    tmp = queue.extract();

    int remaining = u.entity_count;

    update_timers(MB_INIT_END);

    #pragma omp parallel private(v, cur_cost, jsys, distance, x_vec, y_vec, z_vec) num_threads(3)
    while (remaining > 0 && tmp != dst->seq_id && !isinf(cost[tmp])) {
        #pragma omp master
        {
            update_timers(MB_SYSTEM_START);
            ent = &u.entities[tmp];
            sys = ent->system;
            vist[tmp] = 1;

            // System set
            for (int i = 0; i < sys->entity_count; i++) {
                if (!sys->entities[i].destination && sys->entities[i].seq_id != src->seq_id && sys->entities[i].seq_id != dst->seq_id) {
                    continue;
                }

                if (tmp == sys->entities[i].seq_id) {
                    continue;
                }

                v = sys->entities[i].seq_id;
                cur_cost = cost[tmp] + parameters->align_time + get_time(entity_distance(ent, &sys->entities[i]), parameters->warp_speed);

                if (cur_cost <= cost[v] && !vist[v]) {
                    queue.decrease_raw(cur_cost, v);
                    prev[v] = tmp;
                    cost[v] = cur_cost;
                    type[v] = WARP;
                }
            }
            update_timers(MB_SYSTEM_END);

            update_timers(MB_GATE_START);
            // Gate set
            if (ent->destination && parameters->gate_cost >= 0.0) {
                v = ent->destination->seq_id;
                cur_cost = cost[tmp] + parameters->gate_cost;

                if (cur_cost <= cost[v] && !vist[v]) {
                    queue.decrease_raw(cur_cost, v);
                    prev[v] = tmp;
                    cost[v] = cur_cost;
                    type[v] = GATE;
                }
            }
            update_timers(MB_GATE_END);

            update_timers(MB_JUMP_START);

            #if VECTOR_WIDTH == 4
            x_src_vec = _mm_set1_ps(sys->pos[0]);
            y_src_vec = _mm_set1_ps(sys->pos[1]);
            z_src_vec = _mm_set1_ps(sys->pos[2]);
            #elif VECTOR_WIDTH == 8
            x_src_vec = _mm256_set1_ps(sys->pos[0]);
            y_src_vec = _mm256_set1_ps(sys->pos[1]);
            z_src_vec = _mm256_set1_ps(sys->pos[2]);
            #endif
        }

        // Jump set
        if (!isnan(parameters->jump_range)) {
            #pragma omp for schedule(guided)
            for (int k = 0; k < u.system_count; k += VECTOR_WIDTH) {
                #if VECTOR_WIDTH == 4
                x_vec = _mm_load_ps(sys_x + k);
                y_vec = _mm_load_ps(sys_y + k);
                z_vec = _mm_load_ps(sys_z + k);
                #elif VECTOR_WIDTH == 8
                x_vec = _mm256_load_ps(sys_x + k);
                y_vec = _mm256_load_ps(sys_y + k);
                z_vec = _mm256_load_ps(sys_z + k);
                #endif

                x_vec -= x_src_vec;
                y_vec -= y_src_vec;
                z_vec -= z_src_vec;

                x_vec = (x_vec * x_vec) + (y_vec * y_vec) + (z_vec * z_vec);

                for (int i = 0; i < VECTOR_WIDTH; i++) {
                    if (x_vec[i] > sqjr || sys->id == u.systems[i].id) continue;

                    jsys = u.systems + k + i;
                    distance = sqrt(x_vec[i]) / LY_TO_M;

                    for (int j = jsys->gates - jsys->entities; j < jsys->entity_count; j++) {
                        if (!jsys->entities[j].destination && ((jsys->entities[j].seq_id != src->seq_id && jsys->entities[j].seq_id != dst->seq_id))) continue;

                        v = jsys->entities[j].seq_id;
                        cur_cost = cost[tmp] + 60 * (distance + 1);

                        if (cur_cost <= cost[v] && !vist[v]) {
                            queue.decrease_raw(cur_cost, v);
                            prev[v] = tmp;
                            cost[v] = cur_cost;
                            type[v] = JUMP;
                        }
                    }
                }
            }
        }

        #pragma omp master
        {
            update_timers(MB_JUMP_END);

            update_timers(MB_SELECT_START);
            remaining--;
            loops++;
            tmp = queue.extract();
            update_timers(MB_SELECT_END);
        }

        #pragma omp barrier
    }

    update_timers(MB_TOTAL_END);

    Route *route = new Route();

    if (verbose >= 1) {
        unsigned long mba_total = 0;

        for (int i = 3; i < MB_MAX; i += 2) {
            mba_total += mba[i];
        }

        for (int i = 1; i < MB_MAX; i += 2) {
            fprintf(stderr, "%0.3f ms (%.1f%%), ", mba[i] / 1000000.0, (mba[i] / (double) mba_total) * 100);
        }

        fprintf(stderr, "\n");
    }

    route->loops = loops;
    route->cost = cost[dst->seq_id];

    for (int c = dst->seq_id; c != -2; c = prev[c]) {
        route->points.push_front((struct waypoint) {&u.entities[c], type[c]});
    }

    free(prev);
    free(cost);
    free(vist);
    free(type);
    free(sys_c);

    return route;
}
<commit_msg>Fix a memory alignment issue with AVX.<commit_after>#include <array>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <math.h>
#include <omp.h>

#include <xmmintrin.h>
#include <pmmintrin.h>

#include "main.hpp"
#include "min_heap.hpp"
#include "universe.hpp"

#define IACA_SSC_MARK( MARK_ID )						\
__asm__ __volatile__ (								\
					  "\n\t  movl $"#MARK_ID", %%ebx"	\
					  "\n\t  .byte 0x64, 0x67, 0x90"	\
					  : : : "memory" );

#define IACA_START {IACA_SSC_MARK(111)}
#define IACA_END {IACA_SSC_MARK(222)}

#define AU_TO_M 149597870700.0
#define LY_TO_M 9460730472580800.0

#if defined(__AVX__)
#include <immintrin.h>
#define VECTOR_WIDTH 8
typedef __m256 vector_type;
#elif defined(__SSE__)
#define VECTOR_WIDTH 4
typedef __m128 vector_type;
#else
#error "Here's a nickel kid, buy yourself a real computer."
#endif

enum measurement_point {
    MB_TOTAL_START, MB_TOTAL_END,
    MB_INIT_START, MB_INIT_END,
    MB_SYSTEM_START, MB_SYSTEM_END,
    MB_GATE_START, MB_GATE_END,
    MB_JUMP_START, MB_JUMP_END,
    MB_SELECT_START, MB_SELECT_END,
    MB_MAX
};

static struct timespec mbt[MB_MAX];
static long mba[MB_MAX] = {0};

static void update_timers(enum measurement_point p) {
    if (verbose >= 1) {
        clock_gettime(CLOCK_MONOTONIC, &mbt[p]);
        mba[p] += time_diff(&mbt[p - 1], &mbt[p]);
    }
}

inline float __attribute__((always_inline)) entity_distance(Celestial *a, Celestial *b) {
    if (a->system != b->system) return INFINITY;

    float dx = a->pos[0] - b->pos[0];
    float dy = a->pos[1] - b->pos[1];
    float dz = a->pos[2] - b->pos[2];

    return sqrt(dx * dx + dy * dy + dz * dz);
}

double get_time(double distance, double v_wrp) {
    double k_accel = v_wrp;
    double k_decel = (v_wrp / 3) < 2 ? (v_wrp / 3) : 2;

    double v_max_wrp = v_wrp * AU_TO_M;

    double d_accel = AU_TO_M;
    double d_decel = v_max_wrp / k_decel;

    double d_min = d_accel + d_decel;

    double cruise_time = 0;

    if (d_min > distance) {
        v_max_wrp = distance * k_accel * k_decel / (k_accel + k_decel);
    } else {
        cruise_time = (distance - d_min) / v_max_wrp;
    }

    double t_accel = log(v_max_wrp / k_accel) / k_accel;
    double t_decel = log(v_max_wrp / 100) / k_decel;

    return cruise_time + t_accel + t_decel;
}

Route *dijkstra(Universe &u, Celestial *src, Celestial *dst, struct trip *parameters) {
    update_timers(MB_TOTAL_START);
    update_timers(MB_INIT_START);

    int *prev = (int *) malloc(u.entity_count * sizeof(int));
    int *vist = (int *) malloc(u.entity_count * sizeof(int));
    float *cost = (float *) malloc(u.entity_count * sizeof(float));
    enum movement_type *type = (enum movement_type *) malloc(u.entity_count * sizeof(enum movement_type));

    float *sys_c = (float *) calloc(4 * (u.system_count + VECTOR_WIDTH), sizeof(float));
    float *sys_x = (float *) calloc((u.system_count + VECTOR_WIDTH), sizeof(float));
    float *sys_y = (float *) calloc((u.system_count + VECTOR_WIDTH), sizeof(float));
    float *sys_z = (float *) calloc((u.system_count + VECTOR_WIDTH), sizeof(float));

    MinHeap<float, int> queue(u.entity_count);

    float distance, cur_cost;

    for (int i = 0; i < u.system_count; i++) {
        _mm_store_ps(&sys_c[i * 4], u.systems[i].pos);
        sys_x[i] = u.systems[i].pos[0];
        sys_y[i] = u.systems[i].pos[1];
        sys_z[i] = u.systems[i].pos[2];
    }

    for (int i = 0; i < u.entity_count; i++) {
        if (!u.entities[i].destination && u.entities[i].seq_id != src->seq_id && u.entities[i].seq_id != dst->seq_id) continue;

        vist[i] = i == src->seq_id ? 1 : 0;
        prev[i] = i == src->seq_id ? -2 : -1;
        type[i] = STRT;
        cost[i] = i == src->seq_id ? 0.0 : INFINITY;

        queue.insert(cost[i], i);
    }

    int tmp, v;
    int loops = 0;
    float sqjr = pow(parameters->jump_range * LY_TO_M, 2.0);

    vector_type x_vec, y_vec, z_vec;
    vector_type x_src_vec, y_src_vec, z_src_vec;

    System *sys, *jsys;
    Celestial *ent;

    tmp = queue.extract();

    int remaining = u.entity_count;

    update_timers(MB_INIT_END);

    #pragma omp parallel private(v, cur_cost, jsys, distance, x_vec, y_vec, z_vec) num_threads(3)
    while (remaining > 0 && tmp != dst->seq_id && !isinf(cost[tmp])) {
        #pragma omp master
        {
            update_timers(MB_SYSTEM_START);
            ent = &u.entities[tmp];
            sys = ent->system;
            vist[tmp] = 1;

            // System set
            for (int i = 0; i < sys->entity_count; i++) {
                if (!sys->entities[i].destination && sys->entities[i].seq_id != src->seq_id && sys->entities[i].seq_id != dst->seq_id) {
                    continue;
                }

                if (tmp == sys->entities[i].seq_id) {
                    continue;
                }

                v = sys->entities[i].seq_id;
                cur_cost = cost[tmp] + parameters->align_time + get_time(entity_distance(ent, &sys->entities[i]), parameters->warp_speed);

                if (cur_cost <= cost[v] && !vist[v]) {
                    queue.decrease_raw(cur_cost, v);
                    prev[v] = tmp;
                    cost[v] = cur_cost;
                    type[v] = WARP;
                }
            }
            update_timers(MB_SYSTEM_END);

            update_timers(MB_GATE_START);
            // Gate set
            if (ent->destination && parameters->gate_cost >= 0.0) {
                v = ent->destination->seq_id;
                cur_cost = cost[tmp] + parameters->gate_cost;

                if (cur_cost <= cost[v] && !vist[v]) {
                    queue.decrease_raw(cur_cost, v);
                    prev[v] = tmp;
                    cost[v] = cur_cost;
                    type[v] = GATE;
                }
            }
            update_timers(MB_GATE_END);

            update_timers(MB_JUMP_START);

            #if VECTOR_WIDTH == 4
            x_src_vec = _mm_set1_ps(sys->pos[0]);
            y_src_vec = _mm_set1_ps(sys->pos[1]);
            z_src_vec = _mm_set1_ps(sys->pos[2]);
            #elif VECTOR_WIDTH == 8
            x_src_vec = _mm256_set1_ps(sys->pos[0]);
            y_src_vec = _mm256_set1_ps(sys->pos[1]);
            z_src_vec = _mm256_set1_ps(sys->pos[2]);
            #endif
        }

        // Jump set
        if (!isnan(parameters->jump_range)) {
            #pragma omp for schedule(guided)
            for (int k = 0; k < u.system_count; k += VECTOR_WIDTH) {
                #if VECTOR_WIDTH == 4
                x_vec = _mm_load_ps(sys_x + k);
                y_vec = _mm_load_ps(sys_y + k);
                z_vec = _mm_load_ps(sys_z + k);
                #elif VECTOR_WIDTH == 8
                x_vec = _mm256_loadu_ps(sys_x + k);
                y_vec = _mm256_loadu_ps(sys_y + k);
                z_vec = _mm256_loadu_ps(sys_z + k);
                #endif

                x_vec -= x_src_vec;
                y_vec -= y_src_vec;
                z_vec -= z_src_vec;

                x_vec = (x_vec * x_vec) + (y_vec * y_vec) + (z_vec * z_vec);

                for (int i = 0; i < VECTOR_WIDTH; i++) {
                    if (x_vec[i] > sqjr || sys->id == u.systems[i].id) continue;

                    jsys = u.systems + k + i;
                    distance = sqrt(x_vec[i]) / LY_TO_M;

                    for (int j = jsys->gates - jsys->entities; j < jsys->entity_count; j++) {
                        if (!jsys->entities[j].destination && ((jsys->entities[j].seq_id != src->seq_id && jsys->entities[j].seq_id != dst->seq_id))) continue;

                        v = jsys->entities[j].seq_id;
                        cur_cost = cost[tmp] + 60 * (distance + 1);

                        if (cur_cost <= cost[v] && !vist[v]) {
                            queue.decrease_raw(cur_cost, v);
                            prev[v] = tmp;
                            cost[v] = cur_cost;
                            type[v] = JUMP;
                        }
                    }
                }
            }
        }

        #pragma omp master
        {
            update_timers(MB_JUMP_END);

            update_timers(MB_SELECT_START);
            remaining--;
            loops++;
            tmp = queue.extract();
            update_timers(MB_SELECT_END);
        }

        #pragma omp barrier
    }

    update_timers(MB_TOTAL_END);

    Route *route = new Route();

    if (verbose >= 1) {
        unsigned long mba_total = 0;

        for (int i = 3; i < MB_MAX; i += 2) {
            mba_total += mba[i];
        }

        for (int i = 1; i < MB_MAX; i += 2) {
            fprintf(stderr, "%0.3f ms (%.1f%%), ", mba[i] / 1000000.0, (mba[i] / (double) mba_total) * 100);
        }

        fprintf(stderr, "\n");
    }

    route->loops = loops;
    route->cost = cost[dst->seq_id];

    for (int c = dst->seq_id; c != -2; c = prev[c]) {
        route->points.push_front((struct waypoint) {&u.entities[c], type[c]});
    }

    free(prev);
    free(cost);
    free(vist);
    free(type);
    free(sys_c);

    return route;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//
// Created by sancar koyunlu on 30/12/13.
//

#include "hazelcast/util/Util.h"
#include "hazelcast/client/connection/IOHandler.h"
#include "hazelcast/client/connection/IOSelector.h"
#include "hazelcast/client/connection/Connection.h"
#include "hazelcast/util/ILogger.h"

namespace hazelcast {
    namespace client {
        namespace connection {

            IOHandler::IOHandler(Connection& connection, IOSelector& ioSelector)
            : ioSelector(ioSelector)
            , connection(connection) {

            }

            void IOHandler::registerSocket() {
                ioSelector.addTask(this);
                ioSelector.wakeUp();
            }

            void IOHandler::registerHandler() {
                if (!connection.live)
                    return;
                Socket const& socket = connection.getSocket();
                ioSelector.addSocket(socket);
            }

            void IOHandler::deRegisterSocket() {
                ioSelector.cancelTask(this);
                ioSelector.removeSocket(connection.getSocket());
            }

            IOHandler::~IOHandler() {

            }

            void IOHandler::handleSocketException(const std::string& message) {
                Address const& address = connection.getRemoteEndpoint();

                size_t len = message.length() + 150;
                char *msg = new char[len];
                util::snprintf(msg, len, "[IOHandler::handleSocketException] Closing socket to endpoint %s:%d, Cause:%s\n",
                        address.getHost().c_str(), address.getPort(), message.c_str());
                util::ILogger::getLogger().getLogger().warning(msg);

                // TODO: This call shall resend pending requests and reregister events, hence it can be off-loaded
                // to another thread in order not to block the critical IO thread
                connection.close();
            }
        }
    }
}

<commit_msg>Release memory to prevent memory leak. (#169)<commit_after>/*
 * Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//
// Created by sancar koyunlu on 30/12/13.
//

#include "hazelcast/util/Util.h"
#include "hazelcast/client/connection/IOHandler.h"
#include "hazelcast/client/connection/IOSelector.h"
#include "hazelcast/client/connection/Connection.h"
#include "hazelcast/util/ILogger.h"

namespace hazelcast {
    namespace client {
        namespace connection {

            IOHandler::IOHandler(Connection& connection, IOSelector& ioSelector)
            : ioSelector(ioSelector)
            , connection(connection) {

            }

            void IOHandler::registerSocket() {
                ioSelector.addTask(this);
                ioSelector.wakeUp();
            }

            void IOHandler::registerHandler() {
                if (!connection.live)
                    return;
                Socket const& socket = connection.getSocket();
                ioSelector.addSocket(socket);
            }

            void IOHandler::deRegisterSocket() {
                ioSelector.cancelTask(this);
                ioSelector.removeSocket(connection.getSocket());
            }

            IOHandler::~IOHandler() {

            }

            void IOHandler::handleSocketException(const std::string& message) {
                Address const& address = connection.getRemoteEndpoint();

                size_t len = message.length() + 150;
                char *msg = new char[len];
                util::snprintf(msg, len, "[IOHandler::handleSocketException] Closing socket to endpoint %s:%d, Cause:%s\n",
                        address.getHost().c_str(), address.getPort(), message.c_str());
                util::ILogger::getLogger().getLogger().warning(msg);

                // release the memory for the message
                delete [] msg;

                // TODO: This call shall resend pending requests and reregister events, hence it can be off-loaded
                // to another thread in order not to block the critical IO thread
                connection.close();
            }
        }
    }
}

<|endoftext|>


<commit_before>/**
 * @file /grid_map_visualisations/include/grid_map_visualisations/formatters.hpp
 */
/*****************************************************************************
** Ifdefs
*****************************************************************************/

#ifndef grid_map_visualisations_FORMATTERS_HPP_
#define grid_map_visualisations_FORMATTERS_HPP_

/*****************************************************************************
** Includes
*****************************************************************************/

#include <ecl/formatters.hpp>
#include <grid_map_core/grid_map_core.hpp>
#include <limits>
#include <string>

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace grid_map_extras {

/*****************************************************************************
** Interfaces
*****************************************************************************/

class Formatter {
public:
public:
  /**
   * @brief Default constructor.
   *
   * Initialises the format tags for width, and precision, and a layer to
   * format. Note this only formats a single layer.
   *
   * @param layer_name : look for this layer in any passed grid to format.
   * @param scaled : scale values on the range -99.0 -> 99.0 (for formatting ease).
   * @param w : width (default - no width constraints)
   * @param p : the number of decimal places of precision (default - 4)
   **/
  Formatter(const std::string& layer_name,
            const int &w = -1,
            const unsigned int &p = 2,
            const bool& scaled = true
            )
  : format(w, p, ecl::RightAlign)
  , tmp_width(w)
  , tmp_precision(p)
  , tmp_formatting(false)
  , ready_to_format(false)
  , grid_(nullptr)
  , layer_name_(layer_name)
  , scaled_(scaled)
{}
  virtual ~Formatter() {}
  /**
   * @brief Sets the precision format parameter.
   *
   * @param p : the number of decimal places of precision.
   * @return Formatter& : this formatter readied for use with a stream.
   **/
  Formatter& precision( const unsigned int &p ) {
    format.precision(p);
    return *this;
  }
  /**
   * @brief Sets the width format parameter.
   *
   * Sets the width format parameter.
   *
   * @param w : the width to use for inserted floats (-1 is no width constraint).
   * @return FloatMatrixFormatter& : this formatter readied for use with a stream.
   **/
  Formatter& width( const int &w ) {
    format.width(w);
    return *this;
  }
  /**
   * @brief Returns the current precision setting.
   * @return unsigned int : the precision value.
   */
  unsigned int precision() { return format.precision(); }

  /**
   * @brief Returns the current width setting.
   * @return int : the witdh value (-1 for no width constraint).
   */
  int width() { return format.width(); }

  /**
   * @brief Format a sophus transform with permanently stored precision/width.
   *
   * This function directly formats the specified input value
   * with the stored settings.
   * @code
   * cout << format(nav_msgs::OccupancyGrid()) << endl;
   * @endcode
   * @param matrix : the matrix to be formatted (gets temporarily stored as a pointer).
   * @return FloatMatrixFormatter& : this formatter readied for use with a stream.
   **/
  Formatter& operator() (const grid_map::GridMap& grid ) {
    grid_ = &grid;
    ready_to_format = true;
    return (*this);
  }
  /**
   * @brief Format a matrix with temporarily specified precision/width.
   *
   * This function directly formats the specified input value
   * and temporary settings.
   *
   * @code
   * nav_msgs::OccupancyGrid grid;
   * cout << format(grid,3,-1) << endl; // precision of 3 and no width constraint
   * @endcode
   *
   * @param matrix : the matrix to be formatted (gets temporarily stored as a pointer).
   * @param w : the width to use for inserted floats (-1 is no width constraint).
   * @param p : the number of decimal places of precision.
   * @return FloatMatrixFormatter& : this formatter readied for use with a stream.
   **/
  Formatter& operator() (const grid_map::GridMap& grid, const int &w, const unsigned int &p) {
          grid_ = &grid;
          tmp_precision = p;
          tmp_width = w;
          tmp_formatting = true;
          ready_to_format = true;
          return (*this);
  }
  /**
   * @brief Stream the formatter.
   *
   * Insertion operator for sending the formatter  to an output stream.
   *
   * @param ostream : the output stream.
   * @param formatter : the formatter to be inserted.
   * @tparam OutputStream : the type of the output stream to be inserted into.
   * @tparam Derived : matrix type.
   * @return OutputStream : continue streaming with the updated output stream.
   *
   * @exception StandardException : throws if the formatter has un-specified _matrix [debug mode only]
   */
  template <typename OutputStream>
  friend OutputStream& operator << ( OutputStream& ostream, Formatter & formatter ) ecl_assert_throw_decl(ecl::StandardException);

private:
  ecl::Format<float> format;
  int tmp_width;
  unsigned int tmp_precision;
  bool tmp_formatting;
  bool ready_to_format;
  const grid_map::GridMap *grid_;
  const std::string layer_name_;
  bool scaled_;
};

template <typename OutputStream>
OutputStream& operator << (OutputStream& ostream, Formatter & formatter ) ecl_assert_throw_decl(ecl::StandardException) {

  ecl_assert_throw( formatter.grid_, ecl::StandardException(LOC,ecl::UsageError,"The formatter cannot print any data - "
          "grid object was not initialised "
          "please pass the your grid through () operator") );

  ecl_assert_throw(formatter.ready_to_format, ecl::StandardException(LOC,ecl::UsageError,"The formatter cannot print any data - "
          "either there is no data available, or you have tried to use the "
          "formatter more than once in a single streaming operation. "
          "C++ produces unspecified results when functors are used multiply "
          "in the same stream sequence, so this is not permitted here.") );

  if ( formatter.ready_to_format ) {
    unsigned int prm_precision = formatter.format.precision();;
    int prm_width = formatter.format.width();
    if ( formatter.tmp_formatting ) {
      formatter.format.precision(formatter.tmp_precision);
      formatter.format.width(formatter.tmp_width);
    }

    grid_map::Index costmap_index;
    const grid_map::Matrix& data = formatter.grid_->get(std::string(formatter.layer_name_));

    /********************
    ** Scaling
    ********************/
    double max_magnitude = 99.0;
    if ( formatter.scaled_ ) {
      for (grid_map::GridMapIterator iterator(*(formatter.grid_)); !iterator.isPastEnd(); ++iterator) {
        int i = (*iterator)(0);
        int j = (*iterator)(1);
        double value = data(i, j);
        if ( ( std::abs(value) > max_magnitude ) && (value != std::numeric_limits<double>::infinity()) ) {
          max_magnitude = value;
        }
      }
    }

    /*********************
    ** Stream
    **********************/
    int count = 0;
    // Eigen Matrix is row-major, so this grid map iterator usually iterates down before across
    // so have to rearrange the grid into a form that is convenient for streaming to the screen
    // reminder : do not iterate over the matrix directly - the starting index might not be at
    //            the start of the matrix!
    std::vector<double> storage(formatter.grid_->getSize().x() * formatter.grid_->getSize().y(), 0.0);
    for (grid_map::GridMapIterator iterator(*(formatter.grid_)); !iterator.isPastEnd(); ++iterator) {
      int i = (*iterator)(0);
      int j = (*iterator)(1);
      double value = data(i, j);
      if ( formatter.scaled_ ) {
        storage[j + i*formatter.grid_->getSize().x()] = 99.0*value/max_magnitude;
      } else {
        storage[j + i*formatter.grid_->getSize().x()] = value;
      }
    }
    for ( const double& value : storage ) {
      if ( value == std::numeric_limits<double>::infinity() ) {
        for ( unsigned int i = 0; i < formatter.format.width() - 3; ++i ) {
          ostream << " ";
        }
        ostream << "inf";
      } else {
        ostream << formatter.format(value);
      }
      ++count;
      if ( count == formatter.grid_->getSize().x() ) {
        count = 0;
        ostream << "\n";
      }
    }

    /********************
    ** Reset Variables
    ********************/
    if ( formatter.tmp_formatting ) {
      formatter.format.precision(prm_precision);
      formatter.format.width(prm_width);
      formatter.tmp_formatting = false;
    }
    formatter.ready_to_format = false;
  }
  return ostream;
}

} // namespace grid_map_extras

/*****************************************************************************
 ** ECL Format Type
 *****************************************************************************/

namespace ecl {

template <>
class Format<grid_map::GridMap> : public grid_map_extras::Formatter {
public:
  Format(const std::string& layer_name,
         const int &w,
         const unsigned int &p,
         const bool& scaled
         )
  : grid_map_extras::Formatter(layer_name, w, p, scaled)
  {}
};

} // namespace ecl

/*****************************************************************************
** Trailers
*****************************************************************************/

#endif /* grid_map_visualisations_FORMATTERS_HPP_ */
<commit_msg>[grid_map_extras] bugfix magnitude when negative.<commit_after>/**
 * @file /grid_map_visualisations/include/grid_map_visualisations/formatters.hpp
 */
/*****************************************************************************
** Ifdefs
*****************************************************************************/

#ifndef grid_map_visualisations_FORMATTERS_HPP_
#define grid_map_visualisations_FORMATTERS_HPP_

/*****************************************************************************
** Includes
*****************************************************************************/

#include <ecl/formatters.hpp>
#include <grid_map_core/grid_map_core.hpp>
#include <limits>
#include <string>

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace grid_map_extras {

/*****************************************************************************
** Interfaces
*****************************************************************************/

class Formatter {
public:
public:
  /**
   * @brief Default constructor.
   *
   * Initialises the format tags for width, and precision, and a layer to
   * format. Note this only formats a single layer.
   *
   * @param layer_name : look for this layer in any passed grid to format.
   * @param scaled : scale values on the range -99.0 -> 99.0 (for formatting ease).
   * @param w : width (default - no width constraints)
   * @param p : the number of decimal places of precision (default - 4)
   **/
  Formatter(const std::string& layer_name,
            const int &w = -1,
            const unsigned int &p = 2,
            const bool& scaled = true
            )
  : format(w, p, ecl::RightAlign)
  , tmp_width(w)
  , tmp_precision(p)
  , tmp_formatting(false)
  , ready_to_format(false)
  , grid_(nullptr)
  , layer_name_(layer_name)
  , scaled_(scaled)
{}
  virtual ~Formatter() {}
  /**
   * @brief Sets the precision format parameter.
   *
   * @param p : the number of decimal places of precision.
   * @return Formatter& : this formatter readied for use with a stream.
   **/
  Formatter& precision( const unsigned int &p ) {
    format.precision(p);
    return *this;
  }
  /**
   * @brief Sets the width format parameter.
   *
   * Sets the width format parameter.
   *
   * @param w : the width to use for inserted floats (-1 is no width constraint).
   * @return FloatMatrixFormatter& : this formatter readied for use with a stream.
   **/
  Formatter& width( const int &w ) {
    format.width(w);
    return *this;
  }
  /**
   * @brief Returns the current precision setting.
   * @return unsigned int : the precision value.
   */
  unsigned int precision() { return format.precision(); }

  /**
   * @brief Returns the current width setting.
   * @return int : the witdh value (-1 for no width constraint).
   */
  int width() { return format.width(); }

  /**
   * @brief Format a sophus transform with permanently stored precision/width.
   *
   * This function directly formats the specified input value
   * with the stored settings.
   * @code
   * cout << format(nav_msgs::OccupancyGrid()) << endl;
   * @endcode
   * @param matrix : the matrix to be formatted (gets temporarily stored as a pointer).
   * @return FloatMatrixFormatter& : this formatter readied for use with a stream.
   **/
  Formatter& operator() (const grid_map::GridMap& grid ) {
    grid_ = &grid;
    ready_to_format = true;
    return (*this);
  }
  /**
   * @brief Format a matrix with temporarily specified precision/width.
   *
   * This function directly formats the specified input value
   * and temporary settings.
   *
   * @code
   * nav_msgs::OccupancyGrid grid;
   * cout << format(grid,3,-1) << endl; // precision of 3 and no width constraint
   * @endcode
   *
   * @param matrix : the matrix to be formatted (gets temporarily stored as a pointer).
   * @param w : the width to use for inserted floats (-1 is no width constraint).
   * @param p : the number of decimal places of precision.
   * @return FloatMatrixFormatter& : this formatter readied for use with a stream.
   **/
  Formatter& operator() (const grid_map::GridMap& grid, const int &w, const unsigned int &p) {
          grid_ = &grid;
          tmp_precision = p;
          tmp_width = w;
          tmp_formatting = true;
          ready_to_format = true;
          return (*this);
  }
  /**
   * @brief Stream the formatter.
   *
   * Insertion operator for sending the formatter  to an output stream.
   *
   * @param ostream : the output stream.
   * @param formatter : the formatter to be inserted.
   * @tparam OutputStream : the type of the output stream to be inserted into.
   * @tparam Derived : matrix type.
   * @return OutputStream : continue streaming with the updated output stream.
   *
   * @exception StandardException : throws if the formatter has un-specified _matrix [debug mode only]
   */
  template <typename OutputStream>
  friend OutputStream& operator << ( OutputStream& ostream, Formatter & formatter ) ecl_assert_throw_decl(ecl::StandardException);

private:
  ecl::Format<float> format;
  int tmp_width;
  unsigned int tmp_precision;
  bool tmp_formatting;
  bool ready_to_format;
  const grid_map::GridMap *grid_;
  const std::string layer_name_;
  bool scaled_;
};

template <typename OutputStream>
OutputStream& operator << (OutputStream& ostream, Formatter & formatter ) ecl_assert_throw_decl(ecl::StandardException) {

  ecl_assert_throw( formatter.grid_, ecl::StandardException(LOC,ecl::UsageError,"The formatter cannot print any data - "
          "grid object was not initialised "
          "please pass the your grid through () operator") );

  ecl_assert_throw(formatter.ready_to_format, ecl::StandardException(LOC,ecl::UsageError,"The formatter cannot print any data - "
          "either there is no data available, or you have tried to use the "
          "formatter more than once in a single streaming operation. "
          "C++ produces unspecified results when functors are used multiply "
          "in the same stream sequence, so this is not permitted here.") );

  if ( formatter.ready_to_format ) {
    unsigned int prm_precision = formatter.format.precision();;
    int prm_width = formatter.format.width();
    if ( formatter.tmp_formatting ) {
      formatter.format.precision(formatter.tmp_precision);
      formatter.format.width(formatter.tmp_width);
    }

    grid_map::Index costmap_index;
    const grid_map::Matrix& data = formatter.grid_->get(std::string(formatter.layer_name_));

    /********************
    ** Scaling
    ********************/
    double max_magnitude = 99.0;
    if ( formatter.scaled_ ) {
      for (grid_map::GridMapIterator iterator(*(formatter.grid_)); !iterator.isPastEnd(); ++iterator) {
        int i = (*iterator)(0);
        int j = (*iterator)(1);
        double value = data(i, j);
        if ( ( std::abs(value) > max_magnitude ) && (value != std::numeric_limits<double>::infinity()) ) {
          max_magnitude = std::abs(value);
        }
      }
    }

    /*********************
    ** Stream
    **********************/
    int count = 0;
    // Eigen Matrix is row-major, so this grid map iterator usually iterates down before across
    // so have to rearrange the grid into a form that is convenient for streaming to the screen
    // reminder : do not iterate over the matrix directly - the starting index might not be at
    //            the start of the matrix!
    std::vector<double> storage(formatter.grid_->getSize().x() * formatter.grid_->getSize().y(), 0.0);
    for (grid_map::GridMapIterator iterator(*(formatter.grid_)); !iterator.isPastEnd(); ++iterator) {
      int i = (*iterator)(0);
      int j = (*iterator)(1);
      double value = data(i, j);
      if ( formatter.scaled_ ) {
        storage[j + i*formatter.grid_->getSize().x()] = 99.0*value/max_magnitude;
      } else {
        storage[j + i*formatter.grid_->getSize().x()] = value;
      }
    }
    for ( const double& value : storage ) {
      if ( value == std::numeric_limits<double>::infinity() ) {
        for ( unsigned int i = 0; i < formatter.format.width() - 3; ++i ) {
          ostream << " ";
        }
        ostream << "inf";
      } else {
        ostream << formatter.format(value);
      }
      ++count;
      if ( count == formatter.grid_->getSize().x() ) {
        count = 0;
        ostream << "\n";
      }
    }

    /********************
    ** Reset Variables
    ********************/
    if ( formatter.tmp_formatting ) {
      formatter.format.precision(prm_precision);
      formatter.format.width(prm_width);
      formatter.tmp_formatting = false;
    }
    formatter.ready_to_format = false;
  }
  return ostream;
}

} // namespace grid_map_extras

/*****************************************************************************
 ** ECL Format Type
 *****************************************************************************/

namespace ecl {

template <>
class Format<grid_map::GridMap> : public grid_map_extras::Formatter {
public:
  Format(const std::string& layer_name,
         const int &w,
         const unsigned int &p,
         const bool& scaled
         )
  : grid_map_extras::Formatter(layer_name, w, p, scaled)
  {}
};

} // namespace ecl

/*****************************************************************************
** Trailers
*****************************************************************************/

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


<commit_before>#include "mesh_cartesian.h"

#include <algorithm>
#include <cmath>
#include <vector>

#include <deal.II/base/point.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/base/tensor.h>
#include <deal.II/base/utilities.h>

#include "../problem/parameter_types.h"

namespace bart {

namespace domain {

template <int dim>
MeshCartesian<dim>::MeshCartesian(const std::vector<double> spatial_max,
                                              const std::vector<int> n_cells,
                                              const std::string material_mapping)
    : MeshCartesian(spatial_max, n_cells) {
  ParseMaterialMap(material_mapping);
}

template <int dim>
MeshCartesian<dim>::MeshCartesian(const std::vector<double> spatial_max,
                                              const std::vector<int> n_cells) {

  // Check lengths of spatial max and n_cells
  AssertThrow(spatial_max.size() == dim,
              dealii::ExcMessage("MeshCartesian argument error, incorrect spatial vector size"));
  AssertThrow(n_cells.size() == dim,
              dealii::ExcMessage("MeshCartesian argument error, incorrect number of cells vector size"))

      std::copy(n_cells.begin(), n_cells.end(), n_cells_.begin());
  std::copy(spatial_max.begin(), spatial_max.end(), spatial_max_.begin());
}

template <int dim>
void MeshCartesian<dim>::FillTriangulation(dealii::Triangulation<dim> &to_fill) {

  dealii::Point<dim> diagonal;
  dealii::Point<dim> origin;

  for (int i = 0; i < dim; ++i)
    diagonal[i] = spatial_max_[i];

  std::vector<unsigned int> number_of_cells{n_cells_.begin(), n_cells_.end()};

  dealii::GridGenerator::subdivided_hyper_rectangle(to_fill, number_of_cells,
                                                    origin, diagonal);
}

template <int dim>
void MeshCartesian<dim>::ParseMaterialMap(std::string material_mapping) {
  using dealii::Utilities::split_string_list;
  using dealii::Utilities::string_to_int;
  using StringVector = std::vector<std::string>;

  StringVector y_vector = split_string_list(material_mapping, "\n");

  std::reverse(y_vector.begin(), y_vector.end());

  for (int j = 0; j < static_cast<int>(y_vector.size()); ++j ) {

    StringVector x_vector = split_string_list(y_vector[j], " ");

    for (int i = 0; i < static_cast<int>(x_vector.size()); ++i ) {

      std::array<int, 2> location{i, j};
      material_mapping_[location] = string_to_int(x_vector[i]);
    }
    n_material_cells_[0] = x_vector.size();
  }
  n_material_cells_[1] = y_vector.size();
}

template <int dim>
void MeshCartesian<dim>::FillMaterialID(dealii::Triangulation<dim> &to_fill) {
  for (auto cell = to_fill.begin_active(); cell != to_fill.end(); ++cell) {
    if (cell->is_locally_owned()) {
      int material_id = GetMaterialID(cell->center());
      cell->set_material_id(material_id);
    }
  }
}

template <int dim>
void MeshCartesian<dim>::FillBoundaryID(dealii::Triangulation<dim> &to_fill) {
  using Boundary = bart::problem::Boundary;
  int faces_per_cell = dealii::GeometryInfo<dim>::faces_per_cell;
  double zero_tol = 1.0e-14;

  for (auto cell = to_fill.begin_active(); cell != to_fill.end(); ++cell) {
    if (cell->is_locally_owned()) {
      for (int face_id = 0; face_id < faces_per_cell; ++face_id) {
        auto face = cell->face(face_id);
        dealii::Point<dim> face_center = face->center();

        switch (dim) {
          case 2: {
            if (std::fabs(face_center[1]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kYMin));
              break;
            } else if (std::fabs(face_center[1] - spatial_max_[1]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kYMax));
              break;
            }
            [[fallthrough]];
          }
            // Fall through to check x-direction
          case 1: {
            if (std::fabs(face_center[0]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kXMin));
              break;
            } else if (std::fabs(face_center[0] - spatial_max_[0]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kXMax));
              break;
            }
            break;
          }
          default: {
            AssertThrow(false,
                        dealii::ExcMessage("Unsupported number of dimensions in FillBoundaryID"));
          }
        }
      }
    }
  }
}

template <int dim>
int MeshCartesian<dim>::GetMaterialID(dealii::Point<dim> location) {
  std::array<double, dim> array_location;
  for (int i = 0; i < dim; ++i)
    array_location[i] = location[i];
  return GetMaterialID(array_location);
}

template <int dim>
int MeshCartesian<dim>::GetMaterialID(std::array<double, dim> location) {
  std::array<int, 2> relative_location{0, 0};

  for (int i = 0; i < dim; ++i) {
    double cell_size = spatial_max_[i]/n_material_cells_[i];
    double cell_location = location[i] / cell_size;
    int cell_index = std::floor(cell_location);

    if (static_cast<double>(cell_index) == cell_location && cell_index != 0) {
      relative_location[i] = cell_index - 1;
    } else {
      relative_location[i] = cell_index;
    }
  }

  return material_mapping_[relative_location];
}

template class MeshCartesian<1>;
template class MeshCartesian<2>;

} // namespace domain

} // namespace bart
<commit_msg>fixed formatting in MeshCartesian implementation<commit_after>#include "mesh_cartesian.h"

#include <algorithm>
#include <cmath>
#include <vector>

#include <deal.II/base/point.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/base/tensor.h>
#include <deal.II/base/utilities.h>

#include "../problem/parameter_types.h"

namespace bart {

namespace domain {

template <int dim>
MeshCartesian<dim>::MeshCartesian(const std::vector<double> spatial_max,
                                  const std::vector<int> n_cells,
                                  const std::string material_mapping)
    : MeshCartesian(spatial_max, n_cells) {
  ParseMaterialMap(material_mapping);
}

template <int dim>
MeshCartesian<dim>::MeshCartesian(const std::vector<double> spatial_max,
                                  const std::vector<int> n_cells) {

  // Check lengths of spatial max and n_cells
  AssertThrow(spatial_max.size() == dim,
              dealii::ExcMessage("MeshCartesian argument error, incorrect spatial vector size"));
  AssertThrow(n_cells.size() == dim,
              dealii::ExcMessage("MeshCartesian argument error, incorrect number of cells vector size"));

  std::copy(n_cells.begin(), n_cells.end(), n_cells_.begin());
  std::copy(spatial_max.begin(), spatial_max.end(), spatial_max_.begin());
}

template <int dim>
void MeshCartesian<dim>::FillTriangulation(dealii::Triangulation<dim> &to_fill) {

  dealii::Point<dim> diagonal;
  dealii::Point<dim> origin;

  for (int i = 0; i < dim; ++i)
    diagonal[i] = spatial_max_[i];

  std::vector<unsigned int> number_of_cells{n_cells_.begin(), n_cells_.end()};
  dealii::GridGenerator::subdivided_hyper_rectangle(to_fill, number_of_cells,
                                                    origin, diagonal);
}

template <int dim>
void MeshCartesian<dim>::ParseMaterialMap(std::string material_mapping) {
  using dealii::Utilities::split_string_list;
  using dealii::Utilities::string_to_int;
  using StringVector = std::vector<std::string>;

  StringVector y_vector = split_string_list(material_mapping, "\n");

  std::reverse(y_vector.begin(), y_vector.end());

  for (int j = 0; j < static_cast<int>(y_vector.size()); ++j ) {

    StringVector x_vector = split_string_list(y_vector[j], " ");

    for (int i = 0; i < static_cast<int>(x_vector.size()); ++i ) {

      std::array<int, 2> location{i, j};
      material_mapping_[location] = string_to_int(x_vector[i]);
    }
    n_material_cells_[0] = x_vector.size();
  }
  n_material_cells_[1] = y_vector.size();
}

template <int dim>
void MeshCartesian<dim>::FillMaterialID(dealii::Triangulation<dim> &to_fill) {
  for (auto cell = to_fill.begin_active(); cell != to_fill.end(); ++cell) {
    if (cell->is_locally_owned()) {
      int material_id = GetMaterialID(cell->center());
      cell->set_material_id(material_id);
    }
  }
}

template <int dim>
void MeshCartesian<dim>::FillBoundaryID(dealii::Triangulation<dim> &to_fill) {
  using Boundary = bart::problem::Boundary;
  int faces_per_cell = dealii::GeometryInfo<dim>::faces_per_cell;
  double zero_tol = 1.0e-14;

  for (auto cell = to_fill.begin_active(); cell != to_fill.end(); ++cell) {
    if (cell->is_locally_owned()) {
      for (int face_id = 0; face_id < faces_per_cell; ++face_id) {
        auto face = cell->face(face_id);
        dealii::Point<dim> face_center = face->center();

        switch (dim) {
          case 2: {
            if (std::fabs(face_center[1]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kYMin));
              break;
            } else if (std::fabs(face_center[1] - spatial_max_[1]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kYMax));
              break;
            }
            [[fallthrough]];
          }
            // Fall through to check x-direction
          case 1: {
            if (std::fabs(face_center[0]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kXMin));
              break;
            } else if (std::fabs(face_center[0] - spatial_max_[0]) < zero_tol) {
              face->set_boundary_id(static_cast<int>(Boundary::kXMax));
              break;
            }
            break;
          }
          default: {
            AssertThrow(false,
                        dealii::ExcMessage("Unsupported number of dimensions in FillBoundaryID"));
          }
        }
      }
    }
  }
}

template <int dim>
int MeshCartesian<dim>::GetMaterialID(dealii::Point<dim> location) {
  std::array<double, dim> array_location;
  for (int i = 0; i < dim; ++i)
    array_location[i] = location[i];
  return GetMaterialID(array_location);
}

template <int dim>
int MeshCartesian<dim>::GetMaterialID(std::array<double, dim> location) {
  std::array<int, 2> relative_location{0, 0};

  for (int i = 0; i < dim; ++i) {
    double cell_size = spatial_max_[i]/n_material_cells_[i];
    double cell_location = location[i] / cell_size;
    int cell_index = std::floor(cell_location);

    if (static_cast<double>(cell_index) == cell_location && cell_index != 0) {
      relative_location[i] = cell_index - 1;
    } else {
      relative_location[i] = cell_index;
    }
  }

  return material_mapping_[relative_location];
}

template class MeshCartesian<1>;
template class MeshCartesian<2>;

} // namespace domain

} // namespace bart
<|endoftext|>


<commit_before>#include "../VFrame/VGame.h"
#include "../Example/States.h"

int main()
{
	VGame* game = new VGame();

	sf::ContextSettings settings;
	settings.depthBits = 32;
	settings.stencilBits = 8;
	settings.antialiasingLevel = 0;
	settings.majorVersion = 4;
	settings.minorVersion = 5;

	int r = game->Run("VFrame Stuff with SFML " + std::to_string(SFML_VERSION_MAJOR) + "." + std::to_string(SFML_VERSION_MINOR) + "." = std::to_string(SFML_VERSION_PATCH), new DemoStatesManager(), 640, 360, 60.0f, 7, settings);
	delete game;
	return r;
}
<commit_msg>Reducing depth bits to 24-bits for more compatability.<commit_after>#include "../VFrame/VGame.h"
#include "../Example/States.h"

int main()
{
	VGame* game = new VGame();

	sf::ContextSettings settings;
	settings.depthBits = 24;
	settings.stencilBits = 8;
	settings.antialiasingLevel = 0;
	settings.majorVersion = 4;
	settings.minorVersion = 5;

	int r = game->Run("VFrame Stuff with SFML " + std::to_string(SFML_VERSION_MAJOR) + "." + std::to_string(SFML_VERSION_MINOR) + "." = std::to_string(SFML_VERSION_PATCH), new DemoStatesManager(), 640, 360, 60.0f, 7, settings);
	delete game;
	return r;
}
<|endoftext|>


<commit_before>#include "stdafx.h"

#include "TimeUtilities.h"

#include <time.h>

namespace SDK
	{

	namespace Utilities
		{

		void SleepSeconds(ulong i_seconds)
			{
			clock_t now = clock();
			clock_t limit = now + i_seconds * CLOCKS_PER_SEC;
			while ( limit > now )
				now = clock();
			}

		void SleepMiliseconds(ulong i_miliseconds)
			{
			long timeout = clock() + i_miliseconds;
			while( clock() < timeout ) continue;
			}

		} // Utilities

	} // SDK<commit_msg>[Utilities] Use standard functions for Linux and Windows<commit_after>#include "stdafx.h"

#include "TimeUtilities.h"

#include <time.h>

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

namespace SDK
	{

	namespace Utilities
		{

		void SleepSeconds(ulong i_seconds)
			{
			SleepMiliseconds(i_seconds*1000);
			}

		void SleepMiliseconds(ulong i_miliseconds)
			{
			#ifdef _WIN32
				Sleep(i_miliseconds);
			#else
			 usleep(i_miliseconds * 1000); // takes microseconds
			#endif
			}

		} // Utilities

	} // SDK<|endoftext|>


<commit_before>/*!
    \file timestamp.cpp
    \brief Timestamp implementation
    \author Ivan Shynkarenka
    \date 26.01.2016
    \copyright MIT License
*/

#include "time/timestamp.h"

#include "math/math.h"

#if defined(__APPLE__)
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <sys/time.h>
#include <math.h>
#include <time.h>
#elif defined(unix) || defined(__unix) || defined(__unix__)
#include <time.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

namespace CppCommon {

//! @cond INTERNALS
namespace Internals {

#if defined(__APPLE__)

uint32_t CeilLog2(uint32_t x)
{
    uint32_t result = 0;

    --x;
    while (x > 0)
    {
        ++result;
        x >>= 1;
    }

    return result;
}

// This function returns the rational number inside the given interval with
// the smallest denominator (and smallest numerator breaks ties; correctness
// proof neglects floating-point errors).
mach_timebase_info_data_t BestFrac(double a, double b)
{
    if (floor(a) < floor(b))
    {
        mach_timebase_info_data_t rv = { (uint32_t)ceil(a), 1 };
        return rv;
    }

    double m = floor(a);
    mach_timebase_info_data_t next = BestFrac(1 / (b - m), 1 / (a - m));
    mach_timebase_info_data_t rv = { (int)m * next.numer + next.denom, next.numer };
    return rv;
}

// This is just less than the smallest thing we can multiply numer by without
// overflowing. CeilLog2(numer) = 64 - number of leading zeros of numer
uint64_t GetExpressibleSpan(uint32_t numer, uint32_t denom)
{
  uint64_t maxDiffWithoutOverflow = ((uint64_t)1 << (64 - CeilLog2(numer))) - 1;
  return maxDiffWithoutOverflow * numer / denom;
}

// The clock may run up to 0.1% faster or slower than the "exact" tick count.
// However, although the bound on the error is the same as for the pragmatic
// answer, the error is actually minimized over the given accuracy bound.
uint64_t PrepareTimebaseInfo(mach_timebase_info_data_t& tb)
{
    tb.numer = 0;
    tb.denom = 1;

    kern_return_t mtiStatus = mach_timebase_info(&tb);
    if (mtiStatus != KERN_SUCCESS)
        return 0;

    double frac = (double)tb.numer / tb.denom;
    uint64_t spanTarget = 315360000000000000llu;
    if (GetExpressibleSpan(tb.numer, tb.denom) >= spanTarget)
        return 0;

    for (double errorTarget = 1 / 1024.0; errorTarget > 0.000001;)
    {
        mach_timebase_info_data_t newFrac = BestFrac((1 - errorTarget) * frac, (1 + errorTarget) * frac);
        if (GetExpressibleSpan(newFrac.numer, newFrac.denom) < spanTarget)
            break;
        tb = newFrac;
        errorTarget = fabs((double)tb.numer / tb.denom - frac) / frac / 8;
    }

    return mach_absolute_time();
}

#endif

} // namespace Internals
//! @endcond

uint64_t Timestamp::utc()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    struct timespec timestamp;
    if (clock_gettime(CLOCK_REALTIME, &timestamp) != 0)
        throwex SystemException("Cannot get value of CLOCK_REALTIME timer!");
    return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
#elif defined(_WIN32) || defined(_WIN64)
    FILETIME ft;
    GetSystemTimePreciseAsFileTime(&ft);

    ULARGE_INTEGER result;
    result.LowPart = ft.dwLowDateTime;
    result.HighPart = ft.dwHighDateTime;
    return (result.QuadPart - 116444736000000000ull) * 100;
#endif
}

uint64_t Timestamp::local()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    uint64_t timestamp = utc();

    // Adjust UTC time with local timezone offset
    struct tm local;
    time_t seconds = timestamp / (1000000000);
    if (localtime_r(&seconds, &local) != &local)
        throwex SystemException("Cannot convert CLOCK_REALTIME time to local date & time structure!");
    return timestamp + (local.tm_gmtoff * 1000000000);
#elif defined(_WIN32) || defined(_WIN64)
    FILETIME ft;
    GetSystemTimePreciseAsFileTime(&ft);

    FILETIME ft_local;
    if (!FileTimeToLocalFileTime(&ft, &ft_local))
        throwex SystemException("Cannot convert UTC file time to local file time structure!");

    ULARGE_INTEGER result;
    result.LowPart = ft_local.dwLowDateTime;
    result.HighPart = ft_local.dwHighDateTime;
    return (result.QuadPart - 116444736000000000ull) * 100;
#endif
}

uint64_t Timestamp::nano()
{
#if defined(__APPLE__)
    static mach_timebase_info_data_t info;
    static uint64_t bias = Internals::PrepareTimebaseInfo(info);
    return ((mach_absolute_time() - bias) * info.numer) / info.denom;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    struct timespec timestamp = { 0 };
    if (clock_gettime(CLOCK_MONOTONIC, &timestamp) != 0)
        throwex SystemException("Cannot get value of CLOCK_MONOTONIC timer!");
    return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
#elif defined(_WIN32) || defined(_WIN64)
    static uint64_t offset = 0;
    static LARGE_INTEGER first = { 0 };
    static LARGE_INTEGER frequency = { 0 };
    static bool initialized = false;
    static bool qpc = true;

    if (!initialized)
    {
        // Calculate timestamp offset
        FILETIME timestamp;
        GetSystemTimePreciseAsFileTime(&timestamp);

        ULARGE_INTEGER result;
        result.LowPart = timestamp.dwLowDateTime;
        result.HighPart = timestamp.dwHighDateTime;

        // Convert 01.01.1601 to 01.01.1970
        result.QuadPart -= 116444736000000000ll;
        offset = result.QuadPart * 100;

        // Setup performance counter
        qpc = QueryPerformanceFrequency(&frequency) && QueryPerformanceCounter(&first);

        initialized = true;
    }

    if (qpc)
    {
        LARGE_INTEGER timestamp = { 0 };
        QueryPerformanceCounter(&timestamp);
        timestamp.QuadPart -= first.QuadPart;
        return offset + Math::MulDiv64(timestamp.QuadPart, 1000000000, frequency.QuadPart);
    }
    else
        return offset;
#else
    #error Unsupported platform
#endif
}

uint64_t Timestamp::rdts()
{
#if defined(_MSC_VER)
    return __rdtsc();
#elif defined(__i386__)
    uint64_t x;
    __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
    return x;
#elif defined(__x86_64__)
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ((uint64_t)lo) | (((uint64_t)hi) << 32);
#endif
}

} // namespace CppCommon
<commit_msg>update<commit_after>/*!
    \file timestamp.cpp
    \brief Timestamp implementation
    \author Ivan Shynkarenka
    \date 26.01.2016
    \copyright MIT License
*/

#include "time/timestamp.h"

#include "math/math.h"

#if defined(__APPLE__)
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <sys/time.h>
#include <math.h>
#include <time.h>
#elif defined(unix) || defined(__unix) || defined(__unix__)
#include <time.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

namespace CppCommon {

//! @cond INTERNALS
namespace Internals {

#if defined(__APPLE__)

uint32_t CeilLog2(uint32_t x)
{
    uint32_t result = 0;

    --x;
    while (x > 0)
    {
        ++result;
        x >>= 1;
    }

    return result;
}

// This function returns the rational number inside the given interval with
// the smallest denominator (and smallest numerator breaks ties; correctness
// proof neglects floating-point errors).
mach_timebase_info_data_t BestFrac(double a, double b)
{
    if (floor(a) < floor(b))
    {
        mach_timebase_info_data_t rv = { (uint32_t)ceil(a), 1 };
        return rv;
    }

    double m = floor(a);
    mach_timebase_info_data_t next = BestFrac(1 / (b - m), 1 / (a - m));
    mach_timebase_info_data_t rv = { (int)m * next.numer + next.denom, next.numer };
    return rv;
}

// This is just less than the smallest thing we can multiply numer by without
// overflowing. CeilLog2(numer) = 64 - number of leading zeros of numer
uint64_t GetExpressibleSpan(uint32_t numer, uint32_t denom)
{
  uint64_t maxDiffWithoutOverflow = ((uint64_t)1 << (64 - CeilLog2(numer))) - 1;
  return maxDiffWithoutOverflow * numer / denom;
}

// The clock may run up to 0.1% faster or slower than the "exact" tick count.
// However, although the bound on the error is the same as for the pragmatic
// answer, the error is actually minimized over the given accuracy bound.
uint64_t PrepareTimebaseInfo(mach_timebase_info_data_t& tb)
{
    tb.numer = 0;
    tb.denom = 1;

    kern_return_t mtiStatus = mach_timebase_info(&tb);
    if (mtiStatus != KERN_SUCCESS)
        return 0;

    double frac = (double)tb.numer / tb.denom;
    uint64_t spanTarget = 315360000000000000llu;
    if (GetExpressibleSpan(tb.numer, tb.denom) >= spanTarget)
        return 0;

    for (double errorTarget = 1 / 1024.0; errorTarget > 0.000001;)
    {
        mach_timebase_info_data_t newFrac = BestFrac((1 - errorTarget) * frac, (1 + errorTarget) * frac);
        if (GetExpressibleSpan(newFrac.numer, newFrac.denom) < spanTarget)
            break;
        tb = newFrac;
        errorTarget = fabs((double)tb.numer / tb.denom - frac) / frac / 8;
    }

    return 0;
}

#endif

} // namespace Internals
//! @endcond

uint64_t Timestamp::utc()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    struct timespec timestamp;
    if (clock_gettime(CLOCK_REALTIME, &timestamp) != 0)
        throwex SystemException("Cannot get value of CLOCK_REALTIME timer!");
    return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
#elif defined(_WIN32) || defined(_WIN64)
    FILETIME ft;
    GetSystemTimePreciseAsFileTime(&ft);

    ULARGE_INTEGER result;
    result.LowPart = ft.dwLowDateTime;
    result.HighPart = ft.dwHighDateTime;
    return (result.QuadPart - 116444736000000000ull) * 100;
#endif
}

uint64_t Timestamp::local()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    uint64_t timestamp = utc();

    // Adjust UTC time with local timezone offset
    struct tm local;
    time_t seconds = timestamp / (1000000000);
    if (localtime_r(&seconds, &local) != &local)
        throwex SystemException("Cannot convert CLOCK_REALTIME time to local date & time structure!");
    return timestamp + (local.tm_gmtoff * 1000000000);
#elif defined(_WIN32) || defined(_WIN64)
    FILETIME ft;
    GetSystemTimePreciseAsFileTime(&ft);

    FILETIME ft_local;
    if (!FileTimeToLocalFileTime(&ft, &ft_local))
        throwex SystemException("Cannot convert UTC file time to local file time structure!");

    ULARGE_INTEGER result;
    result.LowPart = ft_local.dwLowDateTime;
    result.HighPart = ft_local.dwHighDateTime;
    return (result.QuadPart - 116444736000000000ull) * 100;
#endif
}

uint64_t Timestamp::nano()
{
#if defined(__APPLE__)
    static mach_timebase_info_data_t info;
    static uint64_t bias = Internals::PrepareTimebaseInfo(info);
    return ((mach_absolute_time() - bias) * info.numer) / info.denom;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    struct timespec timestamp = { 0 };
    if (clock_gettime(CLOCK_MONOTONIC, &timestamp) != 0)
        throwex SystemException("Cannot get value of CLOCK_MONOTONIC timer!");
    return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
#elif defined(_WIN32) || defined(_WIN64)
    static uint64_t offset = 0;
    static LARGE_INTEGER first = { 0 };
    static LARGE_INTEGER frequency = { 0 };
    static bool initialized = false;
    static bool qpc = true;

    if (!initialized)
    {
        // Calculate timestamp offset
        FILETIME timestamp;
        GetSystemTimePreciseAsFileTime(&timestamp);

        ULARGE_INTEGER result;
        result.LowPart = timestamp.dwLowDateTime;
        result.HighPart = timestamp.dwHighDateTime;

        // Convert 01.01.1601 to 01.01.1970
        result.QuadPart -= 116444736000000000ll;
        offset = result.QuadPart * 100;

        // Setup performance counter
        qpc = QueryPerformanceFrequency(&frequency) && QueryPerformanceCounter(&first);

        initialized = true;
    }

    if (qpc)
    {
        LARGE_INTEGER timestamp = { 0 };
        QueryPerformanceCounter(&timestamp);
        timestamp.QuadPart -= first.QuadPart;
        return offset + Math::MulDiv64(timestamp.QuadPart, 1000000000, frequency.QuadPart);
    }
    else
        return offset;
#else
    #error Unsupported platform
#endif
}

uint64_t Timestamp::rdts()
{
#if defined(_MSC_VER)
    return __rdtsc();
#elif defined(__i386__)
    uint64_t x;
    __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
    return x;
#elif defined(__x86_64__)
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ((uint64_t)lo) | (((uint64_t)hi) << 32);
#endif
}

} // namespace CppCommon
<|endoftext|>


<commit_before>//===------------------------ CalcSpillWeights.cpp ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "calcspillweights"

#include "llvm/Function.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"

using namespace llvm;

char CalculateSpillWeights::ID = 0;
static RegisterPass<CalculateSpillWeights> X("calcspillweights",
                                             "Calculate spill weights");

void CalculateSpillWeights::getAnalysisUsage(AnalysisUsage &au) const {
  au.addRequired<LiveIntervals>();
  au.addRequired<MachineLoopInfo>();
  au.setPreservesAll();
  MachineFunctionPass::getAnalysisUsage(au);
}

bool CalculateSpillWeights::runOnMachineFunction(MachineFunction &fn) {

  DEBUG(errs() << "********** Compute Spill Weights **********\n"
               << "********** Function: "
               << fn.getFunction()->getName() << '\n');

  LiveIntervals *lis = &getAnalysis<LiveIntervals>();
  MachineLoopInfo *loopInfo = &getAnalysis<MachineLoopInfo>();
  const TargetInstrInfo *tii = fn.getTarget().getInstrInfo();
  MachineRegisterInfo *mri = &fn.getRegInfo();

  SmallSet<unsigned, 4> processed;
  for (MachineFunction::iterator mbbi = fn.begin(), mbbe = fn.end();
       mbbi != mbbe; ++mbbi) {
    MachineBasicBlock* mbb = mbbi;
    SlotIndex mbbEnd = lis->getMBBEndIdx(mbb);
    MachineLoop* loop = loopInfo->getLoopFor(mbb);
    unsigned loopDepth = loop ? loop->getLoopDepth() : 0;
    bool isExiting = loop ? loop->isLoopExiting(mbb) : false;

    for (MachineBasicBlock::const_iterator mii = mbb->begin(), mie = mbb->end();
         mii != mie; ++mii) {
      const MachineInstr *mi = mii;
      if (tii->isIdentityCopy(*mi))
        continue;

      if (mi->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
        continue;

      for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
        const MachineOperand &mopi = mi->getOperand(i);
        if (!mopi.isReg() || mopi.getReg() == 0)
          continue;
        unsigned reg = mopi.getReg();
        if (!TargetRegisterInfo::isVirtualRegister(mopi.getReg()))
          continue;
        // Multiple uses of reg by the same instruction. It should not
        // contribute to spill weight again.
        if (!processed.insert(reg))
          continue;

        bool hasDef = mopi.isDef();
        bool hasUse = !hasDef;
        for (unsigned j = i+1; j != e; ++j) {
          const MachineOperand &mopj = mi->getOperand(j);
          if (!mopj.isReg() || mopj.getReg() != reg)
            continue;
          hasDef |= mopj.isDef();
          hasUse |= mopj.isUse();
          if (hasDef && hasUse)
            break;
        }

        LiveInterval &regInt = lis->getInterval(reg);
        float weight = lis->getSpillWeight(hasDef, hasUse, loopDepth);
        if (hasDef && isExiting) {
          // Looks like this is a loop count variable update.
          SlotIndex defIdx = lis->getInstructionIndex(mi).getDefIndex();
          const LiveRange *dlr =
            lis->getInterval(reg).getLiveRangeContaining(defIdx);
          if (dlr->end >= mbbEnd)
            weight *= 3.0F;
        }
        regInt.weight += weight;
      }
      processed.clear();
    }
  }

  for (LiveIntervals::iterator I = lis->begin(), E = lis->end(); I != E; ++I) {
    LiveInterval &li = *I->second;
    if (TargetRegisterInfo::isVirtualRegister(li.reg)) {
      // If the live interval length is essentially zero, i.e. in every live
      // range the use follows def immediately, it doesn't make sense to spill
      // it and hope it will be easier to allocate for this li.
      if (isZeroLengthInterval(&li)) {
        li.weight = HUGE_VALF;
        continue;
      }

      bool isLoad = false;
      SmallVector<LiveInterval*, 4> spillIs;
      if (lis->isReMaterializable(li, spillIs, isLoad)) {
        // If all of the definitions of the interval are re-materializable,
        // it is a preferred candidate for spilling. If non of the defs are
        // loads, then it's potentially very cheap to re-materialize.
        // FIXME: this gets much more complicated once we support non-trivial
        // re-materialization.
        if (isLoad)
          li.weight *= 0.9F;
        else
          li.weight *= 0.5F;
      }

      // Slightly prefer live interval that has been assigned a preferred reg.
      std::pair<unsigned, unsigned> Hint = mri->getRegAllocationHint(li.reg);
      if (Hint.first || Hint.second)
        li.weight *= 1.01F;

      // Divide the weight of the interval by its size.  This encourages
      // spilling of intervals that are large and have few uses, and
      // discourages spilling of small intervals with many uses.
      li.weight /= lis->getApproximateInstructionCount(li) * SlotIndex::NUM;
    }
  }

  return false;
}

/// Returns true if the given live interval is zero length.
bool CalculateSpillWeights::isZeroLengthInterval(LiveInterval *li) const {
  for (LiveInterval::Ranges::const_iterator
       i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i)
    if (i->end.getPrevIndex() > i->start)
      return false;
  return true;
}
<commit_msg><commit_after>//===------------------------ CalcSpillWeights.cpp ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "calcspillweights"

#include "llvm/Function.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"

using namespace llvm;

char CalculateSpillWeights::ID = 0;
static RegisterPass<CalculateSpillWeights> X("calcspillweights",
                                             "Calculate spill weights");

void CalculateSpillWeights::getAnalysisUsage(AnalysisUsage &au) const {
  au.addRequired<LiveIntervals>();
  au.addRequired<MachineLoopInfo>();
  au.setPreservesAll();
  MachineFunctionPass::getAnalysisUsage(au);
}

bool CalculateSpillWeights::runOnMachineFunction(MachineFunction &fn) {

  DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
               << "********** Function: "
               << fn.getFunction()->getName() << '\n');

  LiveIntervals *lis = &getAnalysis<LiveIntervals>();
  MachineLoopInfo *loopInfo = &getAnalysis<MachineLoopInfo>();
  const TargetInstrInfo *tii = fn.getTarget().getInstrInfo();
  MachineRegisterInfo *mri = &fn.getRegInfo();

  SmallSet<unsigned, 4> processed;
  for (MachineFunction::iterator mbbi = fn.begin(), mbbe = fn.end();
       mbbi != mbbe; ++mbbi) {
    MachineBasicBlock* mbb = mbbi;
    SlotIndex mbbEnd = lis->getMBBEndIdx(mbb);
    MachineLoop* loop = loopInfo->getLoopFor(mbb);
    unsigned loopDepth = loop ? loop->getLoopDepth() : 0;
    bool isExiting = loop ? loop->isLoopExiting(mbb) : false;

    for (MachineBasicBlock::const_iterator mii = mbb->begin(), mie = mbb->end();
         mii != mie; ++mii) {
      const MachineInstr *mi = mii;
      if (tii->isIdentityCopy(*mi))
        continue;

      if (mi->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
        continue;

      for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
        const MachineOperand &mopi = mi->getOperand(i);
        if (!mopi.isReg() || mopi.getReg() == 0)
          continue;
        unsigned reg = mopi.getReg();
        if (!TargetRegisterInfo::isVirtualRegister(mopi.getReg()))
          continue;
        // Multiple uses of reg by the same instruction. It should not
        // contribute to spill weight again.
        if (!processed.insert(reg))
          continue;

        bool hasDef = mopi.isDef();
        bool hasUse = !hasDef;
        for (unsigned j = i+1; j != e; ++j) {
          const MachineOperand &mopj = mi->getOperand(j);
          if (!mopj.isReg() || mopj.getReg() != reg)
            continue;
          hasDef |= mopj.isDef();
          hasUse |= mopj.isUse();
          if (hasDef && hasUse)
            break;
        }

        LiveInterval &regInt = lis->getInterval(reg);
        float weight = lis->getSpillWeight(hasDef, hasUse, loopDepth);
        if (hasDef && isExiting) {
          // Looks like this is a loop count variable update.
          SlotIndex defIdx = lis->getInstructionIndex(mi).getDefIndex();
          const LiveRange *dlr =
            lis->getInterval(reg).getLiveRangeContaining(defIdx);
          if (dlr->end >= mbbEnd)
            weight *= 3.0F;
        }
        regInt.weight += weight;
      }
      processed.clear();
    }
  }

  for (LiveIntervals::iterator I = lis->begin(), E = lis->end(); I != E; ++I) {
    LiveInterval &li = *I->second;
    if (TargetRegisterInfo::isVirtualRegister(li.reg)) {
      // If the live interval length is essentially zero, i.e. in every live
      // range the use follows def immediately, it doesn't make sense to spill
      // it and hope it will be easier to allocate for this li.
      if (isZeroLengthInterval(&li)) {
        li.weight = HUGE_VALF;
        continue;
      }

      bool isLoad = false;
      SmallVector<LiveInterval*, 4> spillIs;
      if (lis->isReMaterializable(li, spillIs, isLoad)) {
        // If all of the definitions of the interval are re-materializable,
        // it is a preferred candidate for spilling. If non of the defs are
        // loads, then it's potentially very cheap to re-materialize.
        // FIXME: this gets much more complicated once we support non-trivial
        // re-materialization.
        if (isLoad)
          li.weight *= 0.9F;
        else
          li.weight *= 0.5F;
      }

      // Slightly prefer live interval that has been assigned a preferred reg.
      std::pair<unsigned, unsigned> Hint = mri->getRegAllocationHint(li.reg);
      if (Hint.first || Hint.second)
        li.weight *= 1.01F;

      // Divide the weight of the interval by its size.  This encourages
      // spilling of intervals that are large and have few uses, and
      // discourages spilling of small intervals with many uses.
      li.weight /= lis->getApproximateInstructionCount(li) * SlotIndex::NUM;
    }
  }

  return false;
}

/// Returns true if the given live interval is zero length.
bool CalculateSpillWeights::isZeroLengthInterval(LiveInterval *li) const {
  for (LiveInterval::Ranges::const_iterator
       i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i)
    if (i->end.getPrevIndex() > i->start)
      return false;
  return true;
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2014-2015 Inviwo Foundation
 * 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.
 *
 * 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 OWNER 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 "imagenormalizationprocessor.h"
#include <inviwo/core/datastructures/image/layerram.h>
#include <modules/opengl/texture/textureutils.h>
#include <modules/opengl/shader/shader.h>

namespace inviwo {

const ProcessorInfo ImageNormalizationProcessor::processorInfo_{
    "org.inviwo.ImageNormalization",  // Class identifier
    "Image Normalization",            // Display name
    "Image Operation",                // Category
    CodeState::Experimental,          // Code state
    Tags::GL,                         // Tags
};
const ProcessorInfo ImageNormalizationProcessor::getProcessorInfo() const {
    return processorInfo_;
}

ImageNormalizationProcessor::ImageNormalizationProcessor()
    : ImageGLProcessor("img_normalize.frag")
    , minMaxInvalid_(true)
    , eachChannelsIndividually_("eachChannelsIndividually","Normalize Channels Individually")
    , zeroAtPoint5_("zeroAtPoint5", "Negative numbers below 0.5",false)
    , minS_("min","Min value","")
    , maxS_("max", "Max value","")
    , min_(0.0)
    , max_(1.0)
{

    minS_.setInvalidationLevel(InvalidationLevel::Valid);
    maxS_.setInvalidationLevel(InvalidationLevel::Valid);
    minS_.setReadOnly(true);
    maxS_.setReadOnly(true);

    addProperty(eachChannelsIndividually_);
    addProperty(zeroAtPoint5_);
    addProperty(minS_);
    addProperty(maxS_);

    inport_.onChange(this, &ImageNormalizationProcessor::invalidateMinMax);
    eachChannelsIndividually_.onChange(this,&ImageNormalizationProcessor::invalidateMinMax);

    setAllPropertiesCurrentStateAsDefault();
}

ImageNormalizationProcessor::~ImageNormalizationProcessor() {}

void ImageNormalizationProcessor::preProcess() {
    if (minMaxInvalid_) updateMinMax();

    if (eachChannelsIndividually_.get()) {
        shader_.setUniform("min_", static_cast<vec4>(min_));
        shader_.setUniform("max_", static_cast<vec4>(max_));
    } else {
        double min = std::min(std::min(min_.x,min_.y),min_.z);
        double max = std::max(std::max(max_.x,max_.y),max_.z);
        shader_.setUniform("min_", vec4(min,min,min,0.0f));
        shader_.setUniform("max_", vec4(max,max,max,1.0f));
    }
}

void ImageNormalizationProcessor::updateMinMax() {
    minMaxInvalid_ = true;
}

void ImageNormalizationProcessor::invalidateMinMax() {
    if (!inport_.hasData()) return;
    const LayerRAM* img = inport_.getData()->getColorLayer()->getRepresentation<LayerRAM>();

    uvec2 dim = img->getDimensions();
    uvec2 pixel(0, 0);
    min_ = img->getValueAsVec4Double(pixel);
    max_ = img->getValueAsVec4Double(pixel);
    for(pixel.y = 0;pixel.y< dim.y;pixel.y++)for(pixel.x = 0;pixel.x< dim.x;pixel.x++){
        dvec4 pixelValue = img->getValueAsVec4Double(pixel);
        min_ = glm::min(min_, pixelValue);
        max_ = glm::max(max_, pixelValue);
    }

    minS_.set(toString(min_));
    maxS_.set(toString(max_));

    if (zeroAtPoint5_) {
        max_ = glm::max(glm::abs(min_), glm::abs(max_));
        min_ = -max_;
    }

    min_.a = 0.0; //never normalize alpha
    max_.a = 1.0;
    minMaxInvalid_ = false;
}

} // namespace

<commit_msg>BaseGL: ImageNormalizationProcessor: Moved the zeroAtpoint5 code to preProcess from onChange since it is only called when the image changed<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2014-2015 Inviwo Foundation
 * 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.
 *
 * 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 OWNER 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 "imagenormalizationprocessor.h"
#include <inviwo/core/datastructures/image/layerram.h>
#include <modules/opengl/texture/textureutils.h>
#include <modules/opengl/shader/shader.h>

namespace inviwo {

const ProcessorInfo ImageNormalizationProcessor::processorInfo_{
    "org.inviwo.ImageNormalization",  // Class identifier
    "Image Normalization",            // Display name
    "Image Operation",                // Category
    CodeState::Experimental,          // Code state
    Tags::GL,                         // Tags
};
const ProcessorInfo ImageNormalizationProcessor::getProcessorInfo() const {
    return processorInfo_;
}

ImageNormalizationProcessor::ImageNormalizationProcessor()
    : ImageGLProcessor("img_normalize.frag")
    , minMaxInvalid_(true)
    , eachChannelsIndividually_("eachChannelsIndividually","Normalize Channels Individually")
    , zeroAtPoint5_("zeroAtPoint5", "Negative numbers below 0.5",false)
    , minS_("min","Min value","")
    , maxS_("max", "Max value","")
    , min_(0.0)
    , max_(1.0)
{

    minS_.setInvalidationLevel(InvalidationLevel::Valid);
    maxS_.setInvalidationLevel(InvalidationLevel::Valid);
    minS_.setReadOnly(true);
    maxS_.setReadOnly(true);

    addProperty(eachChannelsIndividually_);
    addProperty(zeroAtPoint5_);
    addProperty(minS_);
    addProperty(maxS_);

    inport_.onChange(this, &ImageNormalizationProcessor::invalidateMinMax);
    eachChannelsIndividually_.onChange(this,&ImageNormalizationProcessor::invalidateMinMax);

    setAllPropertiesCurrentStateAsDefault();
}

ImageNormalizationProcessor::~ImageNormalizationProcessor() {}

void ImageNormalizationProcessor::preProcess() {
    if (minMaxInvalid_) updateMinMax();

    auto min = min_;
    auto max = max_;

    if (zeroAtPoint5_) {
        max.rgb = glm::max(glm::abs(min.rgb()), glm::abs(max.rgb()));
        min.rgb = -max.rgb();
    }

    if (eachChannelsIndividually_.get()) {
        shader_.setUniform("min_", static_cast<vec4>(min));
        shader_.setUniform("max_", static_cast<vec4>(max));
    } else {
        double minV = std::min(std::min(min.x,min.y),min.z);
        double maxV = std::max(std::max(max.x,max.y),max.z);
        shader_.setUniform("min_", vec4(minV, minV, minV,0.0f));
        shader_.setUniform("max_", vec4(maxV, maxV, maxV,1.0f));
    }
}

void ImageNormalizationProcessor::updateMinMax() {
    minMaxInvalid_ = true;
}

void ImageNormalizationProcessor::invalidateMinMax() {
    if (!inport_.hasData()) return;
    const LayerRAM* img = inport_.getData()->getColorLayer()->getRepresentation<LayerRAM>();

    uvec2 dim = img->getDimensions();
    uvec2 pixel(0, 0);
    min_ = img->getValueAsVec4Double(pixel);
    max_ = img->getValueAsVec4Double(pixel);
    for(pixel.y = 0;pixel.y< dim.y;pixel.y++)for(pixel.x = 0;pixel.x< dim.x;pixel.x++){
        dvec4 pixelValue = img->getValueAsVec4Double(pixel);
        min_ = glm::min(min_, pixelValue);
        max_ = glm::max(max_, pixelValue);
    }

    minS_.set(toString(min_));
    maxS_.set(toString(max_));

    min_.a = 0.0; //never normalize alpha
    max_.a = 1.0;
    minMaxInvalid_ = false;
}

} // namespace

<|endoftext|>


<commit_before>/*******************************************************************************[MaxSatInstance.cc]
Magpie -- Florian Letombe, Joao Marques-Silva, Paulo Matos, Jordi Planes (2007)

Parts of the code in this file have been extracted from SATzilla.
**************************************************************************************************/

#include <algorithm>

#include "MaxSatInstance.hh"
#include "ubcsat/ubcsat.h"

bool MaxSatInstance::isTautologicalClause( int lits[ MAX_NUM_LITERALS ], int& numLits, const int clauseNum ) {
  // sort the clause and remove redundant literals
  //!! For large clauses better use sort()
  for (int i=0; i<numLits-1; i++) {
    for (int j=i+1; j<numLits; j++) {
      if (abs(lits[i]) > abs(lits[j])) { // Bubble sort
        swap( lits[i], lits[j] );
      } else if (lits[i] == lits[j]) {
	lits[j--] = lits[--numLits];
	printf("c literal %d is redundant in clause %d\n", lits[i], clauseNum);
      } else if (abs(lits[i]) == abs(lits[j])) {
	printf("c Clause %d is tautological.\n", clauseNum);
	return true;
      }
    }
  }
  return false;
}

MaxSatInstance::MaxSatInstance( const char* filename )
{
  ifstream infile(filename);
  if (!infile) {
    fprintf(stderr, "c Error: could not read from %s.\n", filename);
    exit(1);
  }
  inputFileName = new char[ strlen( filename ) + 1 ];
  strcpy( inputFileName, filename );

  while (infile.get() != 'p') {
    infile.ignore(MAX_LINE_LENGTH, '\n');
  }

  char strbuf[MAX_LINE_LENGTH];
  infile >> strbuf;

  if( strcmp(strbuf, "cnf")==0 ) {
    format = CNF;
  } else if( strcmp(strbuf, "wcnf")==0 ) {
    format = WEIGHTED;
  } else if( strcmp(strbuf, "pcnf")==0 ) {
    format = PARTIAL;
  } else if( strcmp(strbuf, "wpcnf")==0 ) {
    format = WEIGHTED_PARTIAL;
  } else {
    fprintf(stderr, "c Error: Can only understand cnf format!\n");
    exit(1);
  }

  infile >> numVars >> numClauses;

  negClausesWithVar = new int[ numVars+1 ];
  posClausesWithVar = new int[ numVars+1 ];
  fill( negClausesWithVar, &negClausesWithVar[numVars+1], 0 );
  fill( posClausesWithVar, &posClausesWithVar[numVars+1], 0 );

  unitClauses = binaryClauses = ternaryClauses = 0;

  int lits[ MAX_NUM_LITERALS ];
  for (int clauseNum=0; clauseNum<numClauses; clauseNum++) {

    int numLits = 0;

    infile >> lits[numLits];
    while (lits[numLits] != 0)
      infile >> lits[++numLits];

    if ( numLits == 1 or !isTautologicalClause( lits, numLits, clauseNum )) {
      switch( numLits ) {
      case 1: unitClauses++; break;
      case 2: binaryClauses++; break;
      case 3: ternaryClauses++; break;
      }

      for (int litNum = 0; litNum < numLits; litNum++)
	if (lits[litNum] < 0)
	  negClausesWithVar[abs(lits[litNum])]++;
	else
	  posClausesWithVar[lits[litNum]]++;

    } else {
      clauseNum--;
      numClauses--;
    }
  }
}

MaxSatInstance::~MaxSatInstance() {
  delete negClausesWithVar;
  delete posClausesWithVar;
}

namespace ubcsat { int main(int, char**); }

void MaxSatInstance::computeLocalSearchProperties() {
  printf("local search probe...\n");

  char sTimeout[64];
  char sRuns[64];

  sprintf(sTimeout, "%d", UBCSAT_TIME_LIMIT);
  sprintf(sRuns, "%d", UBCSAT_NUM_RUNS);

  char* vlineFilename = new char[512];
  sprintf(vlineFilename, "%s", P_tmpdir);
  strcat(vlineFilename, "/XXXXXX");
  vlineFilename = mktemp(vlineFilename);

  char strseed[64];
  sprintf(strseed, "%d", UBCSAT_SEED );

  char* argv[] = {"ubcsat",
		  "-alg", NULL, "-noimprove", NULL,  "-i", inputFileName,
		  "-runs", sRuns, "-timeout", sTimeout,
		  "-r", "satcomp", vlineFilename,
		  "-seed", strseed,
		  "-satzilla", "-solve"};

  int argc = 17;

  // -- do saps
  argv[2]="saps";
  argv[4]="0.1";

  if ( ubcsat::main(argc, argv) == 10 ) printf("Instance satisfiable\n");

  // -- do gsat
  argv[2]="gsat";
  argv[4]="0.5";

  if ( ubcsat::main(argc, argv) == 10 ) printf("Instance satisfiable\n");

  delete[] vlineFilename;
}

void MaxSatInstance::printInfo(ostream& os) {
  os << "Number of Variables: " << numVars << endl;
  os << "Number of Clauses: " <<  numClauses << endl;
  os << "Ratio Clauses/Variables: " << (float)numClauses/numVars << endl;
  int negClauses = 0, posClauses = 0;
  for (int varNum=1; varNum<=numVars; varNum++) {
    negClauses += negClausesWithVar[ varNum ];
    posClauses += posClausesWithVar[ varNum ];
  }
  os << "Ratio Negative Clauses: " << (float)negClauses/numClauses << endl;
  os << "Ratio Positive Clauses: " << (float)posClauses/numClauses << endl;
  os << "Ratio Unit Clauses: " << (float)unitClauses/numClauses << endl;
  os << "Ratio Binary Clauses: " << (float)binaryClauses/numClauses << endl;
  os << "Ratio Ternary Clauses: " << (float)ternaryClauses/numClauses << endl;
}
<commit_msg>Removed the line with the local search probe info. It was messing MY scripts.<commit_after>/*******************************************************************************[MaxSatInstance.cc]
Magpie -- Florian Letombe, Joao Marques-Silva, Paulo Matos, Jordi Planes (2007)

Parts of the code in this file have been extracted from SATzilla.
**************************************************************************************************/

#include <algorithm>

#include "MaxSatInstance.hh"
#include "ubcsat/ubcsat.h"

bool MaxSatInstance::isTautologicalClause( int lits[ MAX_NUM_LITERALS ], int& numLits, const int clauseNum ) {
  // sort the clause and remove redundant literals
  //!! For large clauses better use sort()
  for (int i=0; i<numLits-1; i++) {
    for (int j=i+1; j<numLits; j++) {
      if (abs(lits[i]) > abs(lits[j])) { // Bubble sort
        swap( lits[i], lits[j] );
      } else if (lits[i] == lits[j]) {
	lits[j--] = lits[--numLits];
	printf("c literal %d is redundant in clause %d\n", lits[i], clauseNum);
      } else if (abs(lits[i]) == abs(lits[j])) {
	printf("c Clause %d is tautological.\n", clauseNum);
	return true;
      }
    }
  }
  return false;
}

MaxSatInstance::MaxSatInstance( const char* filename )
{
  ifstream infile(filename);
  if (!infile) {
    fprintf(stderr, "c Error: could not read from %s.\n", filename);
    exit(1);
  }
  inputFileName = new char[ strlen( filename ) + 1 ];
  strcpy( inputFileName, filename );

  while (infile.get() != 'p') {
    infile.ignore(MAX_LINE_LENGTH, '\n');
  }

  char strbuf[MAX_LINE_LENGTH];
  infile >> strbuf;

  if( strcmp(strbuf, "cnf")==0 ) {
    format = CNF;
  } else if( strcmp(strbuf, "wcnf")==0 ) {
    format = WEIGHTED;
  } else if( strcmp(strbuf, "pcnf")==0 ) {
    format = PARTIAL;
  } else if( strcmp(strbuf, "wpcnf")==0 ) {
    format = WEIGHTED_PARTIAL;
  } else {
    fprintf(stderr, "c Error: Can only understand cnf format!\n");
    exit(1);
  }

  infile >> numVars >> numClauses;

  negClausesWithVar = new int[ numVars+1 ];
  posClausesWithVar = new int[ numVars+1 ];
  fill( negClausesWithVar, &negClausesWithVar[numVars+1], 0 );
  fill( posClausesWithVar, &posClausesWithVar[numVars+1], 0 );

  unitClauses = binaryClauses = ternaryClauses = 0;

  int lits[ MAX_NUM_LITERALS ];
  for (int clauseNum=0; clauseNum<numClauses; clauseNum++) {

    int numLits = 0;

    infile >> lits[numLits];
    while (lits[numLits] != 0)
      infile >> lits[++numLits];

    if ( numLits == 1 or !isTautologicalClause( lits, numLits, clauseNum )) {
      switch( numLits ) {
      case 1: unitClauses++; break;
      case 2: binaryClauses++; break;
      case 3: ternaryClauses++; break;
      }

      for (int litNum = 0; litNum < numLits; litNum++)
	if (lits[litNum] < 0)
	  negClausesWithVar[abs(lits[litNum])]++;
	else
	  posClausesWithVar[lits[litNum]]++;

    } else {
      clauseNum--;
      numClauses--;
    }
  }
}

MaxSatInstance::~MaxSatInstance() {
  delete negClausesWithVar;
  delete posClausesWithVar;
}

namespace ubcsat { int main(int, char**); }

void MaxSatInstance::computeLocalSearchProperties() {

  char sTimeout[64];
  char sRuns[64];

  sprintf(sTimeout, "%d", UBCSAT_TIME_LIMIT);
  sprintf(sRuns, "%d", UBCSAT_NUM_RUNS);

  char* vlineFilename = new char[512];
  sprintf(vlineFilename, "%s", P_tmpdir);
  strcat(vlineFilename, "/XXXXXX");
  vlineFilename = mktemp(vlineFilename);

  char strseed[64];
  sprintf(strseed, "%d", UBCSAT_SEED );

  char* argv[] = {"ubcsat",
		  "-alg", NULL, "-noimprove", NULL,  "-i", inputFileName,
		  "-runs", sRuns, "-timeout", sTimeout,
		  "-r", "satcomp", vlineFilename,
		  "-seed", strseed,
		  "-satzilla", "-solve"};

  int argc = 17;

  // -- do saps
  argv[2]="saps";
  argv[4]="0.1";

  if ( ubcsat::main(argc, argv) == 10 ) printf("Instance satisfiable\n");

  // -- do gsat
  argv[2]="gsat";
  argv[4]="0.5";

  if ( ubcsat::main(argc, argv) == 10 ) printf("Instance satisfiable\n");

  delete[] vlineFilename;
}

void MaxSatInstance::printInfo(ostream& os) {
  os << "Number of Variables: " << numVars << endl;
  os << "Number of Clauses: " <<  numClauses << endl;
  os << "Ratio Clauses/Variables: " << (float)numClauses/numVars << endl;
  int negClauses = 0, posClauses = 0;
  for (int varNum=1; varNum<=numVars; varNum++) {
    negClauses += negClausesWithVar[ varNum ];
    posClauses += posClausesWithVar[ varNum ];
  }
  os << "Ratio Negative Clauses: " << (float)negClauses/numClauses << endl;
  os << "Ratio Positive Clauses: " << (float)posClauses/numClauses << endl;
  os << "Ratio Unit Clauses: " << (float)unitClauses/numClauses << endl;
  os << "Ratio Binary Clauses: " << (float)binaryClauses/numClauses << endl;
  os << "Ratio Ternary Clauses: " << (float)ternaryClauses/numClauses << endl;
}
<|endoftext|>