<commit_before>#include "CGUISharkControlWidget.h"

#include "CProgramContext.h"
#include "CMainState.h"
#include "CTerrainNodeManager.h"
#include "CSharkNodeManager.h"
#include "CSplineNodeManager.h"

#include <Gwen/Controls.h>
#include <Gwen/Controls/ComboBox.h>
#include <sstream>

CGUISharkControlWidget::CGUISharkControlWidget()
{
	Window = new Gwen::Controls::WindowControl(GUIManager->GetCanvas());
	Window->SetDeleteOnClose(false);
	Window->SetBounds(1200, 670, 330, 160);
	Window->SetTitle("Scene Controls");
	Window->SetHidden(true);

	SharkEnableButton = new Gwen::Controls::Button(Window);
	SharkEnableButton->SetBounds(15, 10, 290, 25);
	SharkEnableButton->SetText("Shark Visiblity Button");
	SharkEnableButton->onPress.Add(this, &CGUISharkControlWidget::OnToggleShark);

	SplineEnableButton = new Gwen::Controls::Button(Window);
	SplineEnableButton->SetBounds(15, 45, 290, 25);
	SplineEnableButton->SetText("Spline Visiblity Button");
	SplineEnableButton->onPress.Add(this, &CGUISharkControlWidget::OnToggleSpline);
	SetButtonTitles();
}

void CGUISharkControlWidget::SetButtonTitles()
{
	CProgramContext * Context = & CProgramContext::Get();

	if (Context->Scene.Shark->GetNode()->IsVisible())
		SharkEnableButton->SetText("Disable Shark Visual");
	else
		SharkEnableButton->SetText("Enable Shark Visual");

	if (Context->Scene.Spline->GetNode()->IsVisible())
		SplineEnableButton->SetText("Disable Spline Visual");
	else
		SplineEnableButton->SetText("Enable Spline Visual");
}

void CGUISharkControlWidget::OnToggleShark(Gwen::Controls::Base * Control)
{
	CProgramContext * Context = & CProgramContext::Get();

	if (! Context->Scene.Shark->GetNode()->IsVisible())
	{
		Context->Scene.Shark->GetNode()->SetVisible(true);
		GUIContext->GetConsole()->AddMessage("Shark View Enabled");
		SetButtonTitles();
	}
	else
	{
		Context->Scene.Shark->GetNode()->SetVisible(false);
		GUIContext->GetConsole()->AddMessage("Shark View Disabled");
		SetButtonTitles();
	}
}

void CGUISharkControlWidget::OnToggleSpline(Gwen::Controls::Base * Control)
{
	CProgramContext * Context = &CProgramContext::Get();

	if (!Context->Scene.Spline->GetNode()->IsVisible())
	{
		Context->Scene.Spline->GetNode()->SetVisible(true);
		GUIContext->GetConsole()->AddMessage("Spline View Enabled");
		SetButtonTitles();
	}
	else
	{
		Context->Scene.Spline->GetNode()->SetVisible(false);
		GUIContext->GetConsole()->AddMessage("Spline View Disabled");
		SetButtonTitles();
	}
}

void CGUISharkControlWidget::toggle()
{
	Window->SetHidden(Window->Visible());
}
<commit_msg>Mistitled window fixed<commit_after>#include "CGUISharkControlWidget.h"

#include "CProgramContext.h"
#include "CMainState.h"
#include "CTerrainNodeManager.h"
#include "CSharkNodeManager.h"
#include "CSplineNodeManager.h"

#include <Gwen/Controls.h>
#include <Gwen/Controls/ComboBox.h>
#include <sstream>

CGUISharkControlWidget::CGUISharkControlWidget()
{
	Window = new Gwen::Controls::WindowControl(GUIManager->GetCanvas());
	Window->SetDeleteOnClose(false);
	Window->SetBounds(1200, 670, 330, 160);
	Window->SetTitle("Shark Controls");
	Window->SetHidden(true);

	SharkEnableButton = new Gwen::Controls::Button(Window);
	SharkEnableButton->SetBounds(15, 10, 290, 25);
	SharkEnableButton->SetText("Shark Visiblity Button");
	SharkEnableButton->onPress.Add(this, &CGUISharkControlWidget::OnToggleShark);

	SplineEnableButton = new Gwen::Controls::Button(Window);
	SplineEnableButton->SetBounds(15, 45, 290, 25);
	SplineEnableButton->SetText("Spline Visiblity Button");
	SplineEnableButton->onPress.Add(this, &CGUISharkControlWidget::OnToggleSpline);
	SetButtonTitles();
}

void CGUISharkControlWidget::SetButtonTitles()
{
	CProgramContext * Context = & CProgramContext::Get();

	if (Context->Scene.Shark->GetNode()->IsVisible())
		SharkEnableButton->SetText("Disable Shark Visual");
	else
		SharkEnableButton->SetText("Enable Shark Visual");

	if (Context->Scene.Spline->GetNode()->IsVisible())
		SplineEnableButton->SetText("Disable Spline Visual");
	else
		SplineEnableButton->SetText("Enable Spline Visual");
}

void CGUISharkControlWidget::OnToggleShark(Gwen::Controls::Base * Control)
{
	CProgramContext * Context = & CProgramContext::Get();

	if (! Context->Scene.Shark->GetNode()->IsVisible())
	{
		Context->Scene.Shark->GetNode()->SetVisible(true);
		GUIContext->GetConsole()->AddMessage("Shark View Enabled");
		SetButtonTitles();
	}
	else
	{
		Context->Scene.Shark->GetNode()->SetVisible(false);
		GUIContext->GetConsole()->AddMessage("Shark View Disabled");
		SetButtonTitles();
	}
}

void CGUISharkControlWidget::OnToggleSpline(Gwen::Controls::Base * Control)
{
	CProgramContext * Context = &CProgramContext::Get();

	if (!Context->Scene.Spline->GetNode()->IsVisible())
	{
		Context->Scene.Spline->GetNode()->SetVisible(true);
		GUIContext->GetConsole()->AddMessage("Spline View Enabled");
		SetButtonTitles();
	}
	else
	{
		Context->Scene.Spline->GetNode()->SetVisible(false);
		GUIContext->GetConsole()->AddMessage("Spline View Disabled");
		SetButtonTitles();
	}
}

void CGUISharkControlWidget::toggle()
{
	Window->SetHidden(Window->Visible());
}
<|endoftext|>


<commit_before>// ** DON'T INCLUDE <iostream>! THINGS WILL BREAK! **
#include <ctime>
#include <string>
#include <array>

#include <rtos.h>

#include <helper-funcs.hpp>
#include <watchdog.hpp>
#include <logger.hpp>
#include <assert.hpp>

#include "robot-devices.hpp"
#include "task-signals.hpp"
#include "task-globals.hpp"
#include "commands.hpp"
#include "fpga.hpp"
#include "io-expander.hpp"
#include "neostrip.hpp"

// task globals
uint16_t comm_err = 0;
uint16_t fpga_err = 0;
uint16_t imu_err = 0;

void Task_Controller(void const* args);

/**
 * @brief      { Sets the hardware configurations for the status LEDs & places
 * into the given state }
 *
 * @param[in]  state  { the next state of the LEDs }
 */
void statusLights(bool state) {
    DigitalInOut init_leds[] = {{RJ_BALL_LED, PIN_OUTPUT, OpenDrain, !state},
        {RJ_RX_LED, PIN_OUTPUT, OpenDrain, !state},
        {RJ_TX_LED, PIN_OUTPUT, OpenDrain, !state},
        {RJ_RDY_LED, PIN_OUTPUT, OpenDrain, !state}
    };

    for (int i = 0; i < 4; i++) init_leds[i].mode(PullUp);
}

/**
 * @brief      { Turn all status LEDs on }
 */
void statusLightsON(void const* args) { statusLights(1); }

/**
 * @brief      { Turn all status LEDs off }
 */
void statusLightsOFF(void const* args) { statusLights(0); }

/**
 * [main Main The entry point of the system where each submodule's thread is
 * started.]
 * @return  [none]
 */
int main() {
    // Store the thread's ID
    static const osThreadId mainID = Thread::gettid();
    ASSERT(mainID != nullptr);

    // clear any extraneous rx serial bytes
    if (true) {
        Serial s(RJ_SERIAL_RXTX);
        // flush rx queue
        while (s.readable()) s.getc();

        // print out the baudrate we're using as a last resort
        // to let the user know they may or may not see it
        // depending on many factors.
        s.baud(57600);
    }

    // Turn on some startup LEDs to show they're working, they are turned off
    // before we hit the while loop
    statusLightsON(nullptr);

    // Set the default logging configurations
    isLogging = RJ_LOGGING_EN;
    rjLogLevel = INIT;

    /* Always send out an empty line at startup for keeping the console
     * clean on after a 'reboot' command is called;
     */
    if (isLogging) {
        // reset the console's default settings and enable the cursor
        printf("\033[m");
        fflush(stdout);
    }

    // Setup the interrupt priorities before launching each subsystem's task
    // thread.
    setISRPriorities();

    // Force off since the neopixel's hardware is stateless from previous
    // settings
    NeoStrip rgbLED(RJ_NEOPIXEL, 2);
    rgbLED.clear();

    // Set the RGB LEDs to a medium blue while the threads are started up
    float defaultBrightness = 0.02f;
    rgbLED.brightness(3 * defaultBrightness);
    rgbLED.setPixel(0, 0x00, 0x00, 0xFF);
    rgbLED.setPixel(1, 0x00, 0x00, 0xFF);
    rgbLED.write();

    // Start a periodic blinking LED to show system activity
    std::vector<DigitalOut> mbed_lights;
    mbed_lights.push_back(DigitalOut(LED1, 0));
    mbed_lights.push_back(DigitalOut(LED2, 0));
    mbed_lights.push_back(DigitalOut(LED3, 0));
    mbed_lights.push_back(DigitalOut(LED4, 0));
    RtosTimer live_light(imAlive, osTimerPeriodic, (void*)&mbed_lights);
    live_light.start(RJ_LIFELIGHT_TIMEOUT_MS);

    // Flip off the startup LEDs after a timeout period
    RtosTimer init_leds_off(statusLightsOFF, osTimerOnce);
    init_leds_off.start(RJ_STARTUP_LED_TIMEOUT_MS);

    // This is where the FPGA is actually configured with the bitfile's name
    // passed in
    bool fpga_ready = FPGA::Instance()->Init("/local/rj-fpga.nib");

    /* We MUST wait for the FPGA to COMPLETELY configure before moving on
     * because of threading with the shared the SPI. If we don't
     * explicitly halt main (it's just considered another thread), then
     * the chip select lines will not be in the correct states for
     * communicating between devices exclusively. Many bus faults occured
     * on the road to finding this problem and then determining how to
     * fix it.
     */
    if (fpga_ready == true) {
        LOG(INIT, "FPGA Configuration Successful!");
        osSignalSet(mainID, MAIN_TASK_CONTINUE);
    } else {
        LOG(FATAL, "FPGA Configuration Failed!");
        osSignalSet(mainID, MAIN_TASK_CONTINUE);
    }

    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    fpga_err |= 1 << !fpga_ready;
    // the error code is valid now
    fpga_err |= 1 << 0;

    // Start the thread task for the on-board control loop
    Thread controller_task(Task_Controller, mainID, osPriorityHigh);

    Thread::wait(10);

    // Start the thread task for handling radio communications
    Thread comm_task(Task_CommCtrl, mainID, osPriorityAboveNormal);

    Thread::wait(10);

    // Start the thread task for the serial console
    Thread console_task(Task_SerialConsole, mainID, osPriorityBelowNormal);

    DigitalOut rdy_led(RJ_RDY_LED, !fpga_ready);

    // Make sure all of the motors are enabled
    motors_Init();

    // Wait for all threads to get to their ready state
    for (size_t i = 0; i < 3; ++i)
        Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Set error indicators
    if (fpga_err > 1) {
        // orange - error
        rgbLED.brightness(4 * defaultBrightness);
        rgbLED.setPixel(0, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(defaultBrightness);
        rgbLED.setPixel(0, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1) {
        // orange - error
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1 && fpga_err > 1) {
        // bright as hell to make sure they know
        rgbLED.brightness(10 * defaultBrightness);
        // well, damn. everything is broke as hell
        rgbLED.setPixel(0, 0xFF, 0x00, 0x00);
        rgbLED.setPixel(1, 0xFF, 0x00, 0x00);
    }

    // push out the LED changes to the hardware
    rgbLED.write();

    // Set the watdog timer's initial config
    Watchdog::Set(RJ_WATCHDOG_TIMER_VALUE);

    // Release each thread into its operations in a structured manner
    controller_task.signal_set(SUB_TASK_CONTINUE);
    comm_task.signal_set(SUB_TASK_CONTINUE);
    console_task.signal_set(SUB_TASK_CONTINUE);

    osStatus tState = osThreadSetPriority(mainID, osPriorityNormal);
    ASSERT(tState == osOK);

    rdy_led = fpga_ready;

    unsigned int ll = 0;
    MCP23017::Init();

    while (true) {
        // make sure we can always reach back to main by
        // renewing the watchdog timer periodicly
        rdy_led = !rdy_led;
        Watchdog::Renew();

        // periodically reset the console text's format
        ll++;
        if ((ll % 4) == 0) {
            printf("\033[m");
            fflush(stdout);
        }

        Thread::wait(RJ_WATCHDOG_TIMER_VALUE * 250);
    }
}

#define _EXTERN extern "C"

_EXTERN void HardFault_Handler() {
    __asm volatile(
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, hard_fault_handler_2_const                        \n"
        " bx r2                                                     \n"
        " hard_fault_handler_2_const: .word HARD_FAULT_HANDLER    	\n");
}

_EXTERN void HARD_FAULT_HANDLER(uint32_t* stackAddr) {
    /* These are volatile to try and prevent the compiler/linker optimising them
     * away as the variables never actually get used.  If the debugger won't
     * show the values of the variables, make them global my moving their
     * declaration outside of this function. */
    volatile uint32_t r0;
    volatile uint32_t r1;
    volatile uint32_t r2;
    volatile uint32_t r3;
    volatile uint32_t r12;
    volatile uint32_t lr;  /* Link register. */
    volatile uint32_t pc;  /* Program counter. */
    volatile uint32_t psr; /* Program status register. */

    r0 = stackAddr[0];
    r1 = stackAddr[1];
    r2 = stackAddr[2];
    r3 = stackAddr[3];
    r12 = stackAddr[4];
    lr = stackAddr[5];
    pc = stackAddr[6];
    psr = stackAddr[7];

    LOG(FATAL,
        "\r\n"
        "================================\r\n"
        "========== HARD FAULT ==========\r\n"
        "\r\n"
        "  MSP:\t0x%08X\r\n"
        "  HFSR:\t0x%08X\r\n"
        "  CFSR:\t0x%08X\r\n"
        "\r\n"
        "  r0:\t0x%08X\r\n"
        "  r1:\t0x%08X\r\n"
        "  r2:\t0x%08X\r\n"
        "  r3:\t0x%08X\r\n"
        "  r12:\t0x%08X\r\n"
        "  lr:\t0x%08X\r\n"
        "  pc:\t0x%08X\r\n"
        "  psr:\t0x%08X\r\n"
        "\r\n"
        "========== HARD FAULT ==========\r\n"
        "================================",
        __get_MSP, SCB->HFSR, SCB->CFSR, r0, r1, r2, r3, r12, lr, pc, psr);

    // do nothing so everything remains unchanged for debugging
    while (true)
        ;
}

_EXTERN void NMI_Handler() { std::printf("NMI Fault!\n"); }

_EXTERN void MemManage_Handler() { std::printf("MemManage Fault!\n"); }

_EXTERN void BusFault_Handler() { std::printf("BusFault Fault!\n"); }

_EXTERN void UsageFault_Handler() { std::printf("UsageFault Fault!\n"); }
<commit_msg>fixing timing startup issues between the threads<commit_after>// ** DON'T INCLUDE <iostream>! THINGS WILL BREAK! **
#include <ctime>
#include <string>
#include <array>

#include <rtos.h>

#include <helper-funcs.hpp>
#include <watchdog.hpp>
#include <logger.hpp>
#include <assert.hpp>

#include "robot-devices.hpp"
#include "task-signals.hpp"
#include "task-globals.hpp"
#include "commands.hpp"
#include "fpga.hpp"
#include "io-expander.hpp"
#include "neostrip.hpp"

// task globals
uint16_t comm_err = 0;
uint16_t fpga_err = 0;
uint16_t imu_err = 0;

void Task_Controller(void const* args);

/**
 * @brief      { Sets the hardware configurations for the status LEDs & places
 * into the given state }
 *
 * @param[in]  state  { the next state of the LEDs }
 */
void statusLights(bool state) {
    DigitalInOut init_leds[] = {{RJ_BALL_LED, PIN_OUTPUT, OpenDrain, !state},
        {RJ_RX_LED, PIN_OUTPUT, OpenDrain, !state},
        {RJ_TX_LED, PIN_OUTPUT, OpenDrain, !state},
        {RJ_RDY_LED, PIN_OUTPUT, OpenDrain, !state}
    };

    for (int i = 0; i < 4; i++) init_leds[i].mode(PullUp);
}

/**
 * @brief      { Turn all status LEDs on }
 */
void statusLightsON(void const* args) { statusLights(1); }

/**
 * @brief      { Turn all status LEDs off }
 */
void statusLightsOFF(void const* args) { statusLights(0); }

/**
 * [main Main The entry point of the system where each submodule's thread is
 * started.]
 * @return  [none]
 */
int main() {
    // Store the thread's ID
    static const osThreadId mainID = Thread::gettid();
    ASSERT(mainID != nullptr);

    // clear any extraneous rx serial bytes
    if (true) {
        Serial s(RJ_SERIAL_RXTX);
        // flush rx queue
        while (s.readable()) s.getc();

        // print out the baudrate we're using as a last resort
        // to let the user know they may or may not see it
        // depending on many factors.
        s.baud(57600);
    }

    // Turn on some startup LEDs to show they're working, they are turned off
    // before we hit the while loop
    statusLightsON(nullptr);

    // Set the default logging configurations
    isLogging = RJ_LOGGING_EN;
    rjLogLevel = INIT;

    /* Always send out an empty line at startup for keeping the console
     * clean on after a 'reboot' command is called;
     */
    if (isLogging) {
        // reset the console's default settings and enable the cursor
        printf("\033[m");
        fflush(stdout);
    }

    // Setup the interrupt priorities before launching each subsystem's task
    // thread.
    setISRPriorities();

    // Force off since the neopixel's hardware is stateless from previous
    // settings
    NeoStrip rgbLED(RJ_NEOPIXEL, 2);
    rgbLED.clear();

    // Set the RGB LEDs to a medium blue while the threads are started up
    float defaultBrightness = 0.02f;
    rgbLED.brightness(3 * defaultBrightness);
    rgbLED.setPixel(0, 0x00, 0x00, 0xFF);
    rgbLED.setPixel(1, 0x00, 0x00, 0xFF);
    rgbLED.write();

    // Start a periodic blinking LED to show system activity
    std::vector<DigitalOut> mbed_lights;
    mbed_lights.push_back(DigitalOut(LED1, 0));
    mbed_lights.push_back(DigitalOut(LED2, 0));
    mbed_lights.push_back(DigitalOut(LED3, 0));
    mbed_lights.push_back(DigitalOut(LED4, 0));
    RtosTimer live_light(imAlive, osTimerPeriodic, (void*)&mbed_lights);
    live_light.start(RJ_LIFELIGHT_TIMEOUT_MS);

    // Flip off the startup LEDs after a timeout period
    RtosTimer init_leds_off(statusLightsOFF, osTimerOnce);
    init_leds_off.start(RJ_STARTUP_LED_TIMEOUT_MS);

    // This is where the FPGA is actually configured with the bitfile's name
    // passed in
    bool fpga_ready = FPGA::Instance()->Init("/local/rj-fpga.nib");

    if (fpga_ready == true) {
        LOG(INIT, "FPGA Configuration Successful!");
    } else {
        LOG(FATAL, "FPGA Configuration Failed!");
    }

    fpga_err |= 1 << !fpga_ready;
    // the error code is valid now
    fpga_err |= 1 << 0;

    // Startup the 3 separate threads, being sure that we wait for it
    // to signal back to us that we can startup the next thread. Not doing
    // so results in weird wierd things that are really hard to debug. Even
    // though this is multi-threaded code, that dosen't mean it's
    // a multi-core system.

    // Start the thread task for the on-board control loop
    Thread controller_task(Task_Controller, mainID, osPriorityHigh);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Start the thread task for handling radio communications
    Thread comm_task(Task_CommCtrl, mainID, osPriorityAboveNormal);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Start the thread task for the serial console
    Thread console_task(Task_SerialConsole, mainID, osPriorityBelowNormal);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    DigitalOut rdy_led(RJ_RDY_LED, !fpga_ready);

    // Make sure all of the motors are enabled
    motors_Init();

    // Set error indicators
    if (fpga_err > 1) {
        // orange - error
        rgbLED.brightness(4 * defaultBrightness);
        rgbLED.setPixel(0, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(defaultBrightness);
        rgbLED.setPixel(0, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1) {
        // orange - error
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1 && fpga_err > 1) {
        // bright as hell to make sure they know
        rgbLED.brightness(10 * defaultBrightness);
        // well, damn. everything is broke as hell
        rgbLED.setPixel(0, 0xFF, 0x00, 0x00);
        rgbLED.setPixel(1, 0xFF, 0x00, 0x00);
    }

    // push out the LED changes to the hardware
    rgbLED.write();

    // Set the watdog timer's initial config
    Watchdog::Set(RJ_WATCHDOG_TIMER_VALUE);

    // Release each thread into its operations in a structured manner
    controller_task.signal_set(SUB_TASK_CONTINUE);
    comm_task.signal_set(SUB_TASK_CONTINUE);
    console_task.signal_set(SUB_TASK_CONTINUE);

    osStatus tState = osThreadSetPriority(mainID, osPriorityNormal);
    ASSERT(tState == osOK);

    rdy_led = fpga_ready;

    unsigned int ll = 0;
    MCP23017::Init();

    while (true) {
        // make sure we can always reach back to main by
        // renewing the watchdog timer periodicly
        rdy_led = !rdy_led;
        Watchdog::Renew();

        // periodically reset the console text's format
        ll++;
        if ((ll % 4) == 0) {
            printf("\033[m");
            fflush(stdout);
        }

        Thread::wait(RJ_WATCHDOG_TIMER_VALUE * 250);
    }
}

#define _EXTERN extern "C"

_EXTERN void HardFault_Handler() {
    __asm volatile(
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, hard_fault_handler_2_const                        \n"
        " bx r2                                                     \n"
        " hard_fault_handler_2_const: .word HARD_FAULT_HANDLER    	\n");
}

_EXTERN void HARD_FAULT_HANDLER(uint32_t* stackAddr) {
    /* These are volatile to try and prevent the compiler/linker optimising them
     * away as the variables never actually get used.  If the debugger won't
     * show the values of the variables, make them global my moving their
     * declaration outside of this function. */
    volatile uint32_t r0;
    volatile uint32_t r1;
    volatile uint32_t r2;
    volatile uint32_t r3;
    volatile uint32_t r12;
    volatile uint32_t lr;  /* Link register. */
    volatile uint32_t pc;  /* Program counter. */
    volatile uint32_t psr; /* Program status register. */

    r0 = stackAddr[0];
    r1 = stackAddr[1];
    r2 = stackAddr[2];
    r3 = stackAddr[3];
    r12 = stackAddr[4];
    lr = stackAddr[5];
    pc = stackAddr[6];
    psr = stackAddr[7];

    LOG(FATAL,
        "\r\n"
        "================================\r\n"
        "========== HARD FAULT ==========\r\n"
        "\r\n"
        "  MSP:\t0x%08X\r\n"
        "  HFSR:\t0x%08X\r\n"
        "  CFSR:\t0x%08X\r\n"
        "\r\n"
        "  r0:\t0x%08X\r\n"
        "  r1:\t0x%08X\r\n"
        "  r2:\t0x%08X\r\n"
        "  r3:\t0x%08X\r\n"
        "  r12:\t0x%08X\r\n"
        "  lr:\t0x%08X\r\n"
        "  pc:\t0x%08X\r\n"
        "  psr:\t0x%08X\r\n"
        "\r\n"
        "========== HARD FAULT ==========\r\n"
        "================================",
        __get_MSP, SCB->HFSR, SCB->CFSR, r0, r1, r2, r3, r12, lr, pc, psr);

    // do nothing so everything remains unchanged for debugging
    while (true)
        ;
}

_EXTERN void NMI_Handler() { std::printf("NMI Fault!\n"); }

_EXTERN void MemManage_Handler() { std::printf("MemManage Fault!\n"); }

_EXTERN void BusFault_Handler() { std::printf("BusFault Fault!\n"); }

_EXTERN void UsageFault_Handler() { std::printf("UsageFault Fault!\n"); }
<|endoftext|>


<commit_before>/*
 * DynBetweenness.cpp
 *
 *  Created on: 29.07.2014
 *      Author: ebergamini
 */
#include <stack>
#include <queue>
#include <memory>

#include "../auxiliary/PrioQueue.h"
#include "DynBetweenness.h"
#include "../auxiliary/PrioQueue.h"
#include "../auxiliary/Log.h"
#include "../graph/SSSP.h"
#include "../graph/Dijkstra.h"
#include "../graph/BFS.h"

namespace NetworKit {
DynBetweenness::DynBetweenness(const Graph& G, bool storePredecessors) : Centrality(G, normalized),
maxDistance(G.upperNodeIdBound()),
npaths(G.upperNodeIdBound(), std::vector<count>(G.upperNodeIdBound())),
distances(G.upperNodeIdBound(), std::vector<edgeweight>(G.upperNodeIdBound())),
dependencies(G.upperNodeIdBound(),std::vector<double>(G.upperNodeIdBound(), 0.0)),
storePreds(storePredecessors) {

}

inline bool logically_equal(double a, double b, double error_factor=1.0)
{
  return a==b || std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*error_factor;
}

void DynBetweenness::run() {
    count z = G.upperNodeIdBound();
    scoreData.clear();
    scoreData.resize(z);
    //TODO: resize also npaths, dependencies and distances
    if (storePreds) {
        predecessors.clear();
        predecessors.resize(G.upperNodeIdBound());
        G.forNodes([&](node v){
            predecessors[v].resize(G.upperNodeIdBound());
        });
    }

    auto computeDependencies = [&](node s) {
        // run SSSP algorithm and keep track of everything
        std::unique_ptr<SSSP> sssp;
        if (G.isWeighted()) {
            sssp.reset(new Dijkstra(G, s, true, true));
        } else {
            sssp.reset(new BFS(G, s, true, true));
        }

        sssp->run();

        G.forNodes([&](node t){
            distances[s][t] = sssp->distance(t);
            npaths[s][t] = sssp->numberOfPaths(t);
            if (storePreds) {
                predecessors[s][t] = sssp->getPredecessors(t);
            }
        });

        // compute dependencies for nodes in order of decreasing distance from s
        std::stack<node> stack = sssp->getStack();
        // set maxDistance to the distance of the furthest vertex
        maxDistance[s] = distances[s][stack.top()];
        while (!stack.empty()) {
            node t = stack.top();
            stack.pop();
            for (node p : sssp->getPredecessors(t)) {
                dependencies[s][p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dependencies[s][t]);
            }
            if (t != s) {
                scoreData[t] += dependencies[s][t];
            }
        }
    };

    G.forNodes(computeDependencies);
}

void DynBetweenness::updateUnweighted(GraphEvent e) {
    G.forNodes([&] (node s){
        node u_l, u_h;
        if (distances[s][e.u] > distances[s][e.v]){
            u_l = e.u;
            u_h = e.v;
        } else {
            u_l = e.v;
            u_h = e.u;
        }
        edgeweight difference = distances[s][u_l] - distances[s][u_h];
        if (difference > 0) {
            std::vector<count> new_npaths(G.upperNodeIdBound());
            std::vector<edgeweight> new_dist(G.upperNodeIdBound());
            G.forNodes([&] (node v){
                new_npaths[v] = npaths[s][v];
                new_dist[v] = distances[s][v];
            });
            std::vector<double> new_dep(G.upperNodeIdBound(), 0.0);
            std::vector<int> touched(G.upperNodeIdBound(), 0);
            std::vector<std::queue<node>> l_queues(maxDistance[s]+1);
            std::queue<node> queue_BFS;
            queue_BFS.push(u_l);
            // one-level update
            if (difference == 1) {
                l_queues[distances[s][u_l]].push(u_l);
                if (storePreds)
                    predecessors[s][u_l].push_back(u_h);
                new_npaths[u_l] += npaths[s][u_h];
                touched[u_l] = -1;
                // BFS traversal from u_l
                while (!queue_BFS.empty()) {
                    node v = queue_BFS.front();
                    DEBUG("extracted node ", v);
                    queue_BFS.pop();
                    G.forNeighborsOf(v, [&](node w) {
                        if (new_dist[w] == new_dist[v]+1) {
                            if (touched[w] == 0) {
                                touched[w] = -1;
                                queue_BFS.push(w);
                                l_queues[new_dist[w]].push(w);
                            }
                            new_npaths[w] = new_npaths[w] - npaths[s][v] + new_npaths[v];
                        }
                    });
                }
            } else if (difference > 1) {
                new_dist[u_l] = distances[s][u_h] + 1;
                l_queues[new_dist[u_l]].push(u_l);
                // BFS traversal from u_l
                while (!queue_BFS.empty()) {
                    node v = queue_BFS.front();
                    DEBUG("extracted node ",v);
                    if (storePreds) {
                        predecessors[s][v].clear();
                    }
                    queue_BFS.pop();
                    touched[v] = -1;
                    new_npaths[v] = 0;
                    G.forNeighborsOf(v, [&] (node w){
                            if (new_dist[w] + 1 == new_dist[v]) {
                                new_npaths[v] += new_npaths[w];
                                if (storePreds) {
                                    predecessors[s][v].push_back(w);
                                }
                            }
                            if (new_dist[w] >= new_dist[v] && touched[w] == 0) {
                                if (new_dist[w] > new_dist[v])
                                    new_dist[w] = new_dist[v]+1;
                                touched[w] = -1;
                                l_queues[new_dist[w]].push(w);
                                queue_BFS.push(w);
                            }
                    });
                }
            }
            // dependencies accumulation
            DEBUG("Dependency accumulation");
            count level = maxDistance[s];
            while(level > 0) {
                while(!l_queues[level].empty()) {
                    node w = l_queues[level].front();
                    DEBUG("Node ",w);
                    l_queues[level].pop();
                    auto updateDependency = [&](node w, node v) {
                        if (new_dist[v] < new_dist[w]) {
                            if (touched[v] == 0) {
                                touched[v] = 1;
                                new_dep[v] = dependencies[s][v];
                                l_queues[level-1].push(v);
                            }
                            double new_contrib = double(new_npaths[v])/new_npaths[w]*(1+new_dep[w]);
                            new_dep[v] += new_contrib;
                            double old_contrib = double(npaths[s][v])/npaths[s][w]*(1+dependencies[s][w]);
                            if (touched[v] == 1 && (v != u_h or w!= u_l))
                                new_dep[v] -= old_contrib;
                            DEBUG("Parent ", v);
                        }
                    };
                    if (storePreds) {
                        for (node v : predecessors[s][w]) {
                            updateDependency(w, v);
                        }
                    }
                    else {
                        G.forNeighborsOf(w, [&](node v){
                            updateDependency(w, v);
                        });
                    }
                    if (w != s) {
                        scoreData[w] = scoreData[w] + new_dep[w] - dependencies[s][w];
                    }
                }
                level = level - 1;
            }
            // data structures update
            G.forNodes([&] (node r){
                distances[s][r] = new_dist[r];
                npaths[s][r] = new_npaths[r];
                if (touched[r] != 0)
                    dependencies[s][r] = new_dep[r];
            });
        }
/*

        BFS sssp(G, s, true, true);
        sssp.run();
        G.forNodes([&](node t){
            if(distances[s][t] != sssp.distance(t) || npaths[s][t] != sssp.numberOfPaths(t)) {
                std::cout<<"Source: "<<s<<"  Node "<<t<<std::endl;
                std::cout<<"COMPUTED DISTANCE: "<<distances[s][t]<<"  REAL DISTANCE: "<<sssp.distance(t)<<std::endl;
                std::cout<<"COMPUTED NUMBER OF PATHS: "<<npaths[s][t]<<"  REAL NUMBER OF PATHS: "<<sssp.numberOfPaths(t)<<std::endl;
            }
        });

        // compute dependencies for nodes in order of decreasing distance from s
        std::vector<double> dep(G.upperNodeIdBound());
        std::stack<node> stack = sssp.getStack();
        while (!stack.empty()) {
            node t = stack.top();
            stack.pop();
            for (node p : sssp.getPredecessors(t)) {
                dep[p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dep[t]);
            }
        }

        G.forNodes([&](node t){
            if((dependencies[s][t]-dep[t]>0.000001 || dependencies[s][t]-dep[t]<-0.000001) && s!=t) {
                std::cout<<"Source: "<<s<<"  Node "<<t<<std::endl;
                std::cout<<"COMPUTED DEPENDENCY: "<<dependencies[s][t]<<"  REAL DEPENDENCY: "<<dep[t]<<std::endl;
            }
        });

*/

    });
}

void DynBetweenness::updateWeighted(GraphEvent e) {
    G.forNodes([&] (node s){
        scoreData[s] = 0.0;
    });
    G.forNodes([&] (node s){
        // update of distances and number of shortest paths
        Aux::PrioQueue<double, node> S(G.upperNodeIdBound());
        G.forNodes([&] (node t){
            auto updatePaths = [&](node u, node v, edgeweight w) {
                if (distances[s][t] == distances[s][u] + w + distances[v][t]){
                    npaths[s][t] = npaths[s][t] + npaths[s][u] * npaths[v][t];
                    if (storePreds) {
                        if (t != v){
                            DEBUG("Adding predecessors from v to t to predecessors from s to t");
                            //predecessors[s][t].insert( predecessors[s][t].end(), predecessors[v][t].begin(), predecessors[v][t].end());
                            for (node pv : predecessors[v][t]) {
                                bool wasAlreadyPred = false;
                                for (node ps : predecessors[s][t]) {
                                    if (ps == pv)
                                        wasAlreadyPred = true;
                                }
                                if (!wasAlreadyPred)
                                    predecessors[s][t].push_back(pv);
                            }
                            DEBUG("Finished adding");
                        }
                        else {
                            DEBUG("Adding u to the predecessors of v");
                            predecessors[s][t].push_back(u);
                            DEBUG("Finished adding");
                        }
                    }
                }
                if (distances[s][t] > distances[s][u] + w + distances[v][t]){
                    distances[s][t] = distances[s][u] + w + distances[v][t];
                    npaths[s][t] = npaths[s][u] * npaths[v][t];
                    if (storePreds) {
                        if (t != v) {
                            DEBUG("Replacing predecessors from v to t with predecessors from s to t");
                            predecessors[s][t] = predecessors[v][t];
                            DEBUG("Finished replacing");
                        }
                        else {
                            DEBUG("Replacing old predecessors of v with u");
                            predecessors[s][t].clear();
                            predecessors[s][t].push_back(u);
                            DEBUG("Finished replacing");
                        }
                    }
                }
            };
            if (s != t) {
                updatePaths(e.u, e.v, e.w);
                updatePaths(e.v, e.u, e.w);
                S.insert(-1*distances[s][t], t);
                dependencies[s][t] = 0.0;
            }
        });
        // dependency accumulation
        while (S.size() != 0) {
            // extract the node with the maximum distance
            node t = S.extractMin().second;
            if (storePreds) {
                DEBUG("Computing dependencies");
                for (node p : predecessors[s][t]) {
                    dependencies[s][p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dependencies[s][t]);
                }
            }
            else {
                G.forNeighborsOf(t, [&] (node p){
                    if (logically_equal(distances[s][t], distances[s][p] + G.weight(p, t))) {
                        dependencies[s][p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dependencies[s][t]);
                    }
                });
            }
            if (t != s) {
                scoreData[t] += dependencies[s][t];
            }
        }

    });

}

void DynBetweenness::update(GraphEvent e) {
    if (G.isWeighted())
        updateWeighted(e);
    else
        updateUnweighted(e);
}

} /* namespace NetworKit */
<commit_msg>inserted cleaning of structures at the beginning of the run method in dynbetweenness<commit_after>/*
 * DynBetweenness.cpp
 *
 *  Created on: 29.07.2014
 *      Author: ebergamini
 */
#include <stack>
#include <queue>
#include <memory>

#include "../auxiliary/PrioQueue.h"
#include "DynBetweenness.h"
#include "../auxiliary/PrioQueue.h"
#include "../auxiliary/Log.h"
#include "../graph/SSSP.h"
#include "../graph/Dijkstra.h"
#include "../graph/BFS.h"

namespace NetworKit {
DynBetweenness::DynBetweenness(const Graph& G, bool storePredecessors) : Centrality(G, normalized),
maxDistance(G.upperNodeIdBound()),
npaths(G.upperNodeIdBound(), std::vector<count>(G.upperNodeIdBound())),
distances(G.upperNodeIdBound(), std::vector<edgeweight>(G.upperNodeIdBound())),
dependencies(G.upperNodeIdBound(),std::vector<double>(G.upperNodeIdBound(), 0.0)),
storePreds(storePredecessors) {

}

inline bool logically_equal(double a, double b, double error_factor=1.0)
{
  return a==b || std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*error_factor;
}

void DynBetweenness::run() {
    count z = G.upperNodeIdBound();
    scoreData.clear();
    scoreData.resize(z);
    npaths.clear();
    nPaths.resize(z);
    distances.clear();
    distance.resize(z);
    dependencies.clear();
    dependencies.resize(z);
    if (storePreds) {
        predecessors.clear();
        predecessors.resize(G.upperNodeIdBound());
        G.forNodes([&](node v){
            predecessors[v].resize(G.upperNodeIdBound());
        });
    }

    auto computeDependencies = [&](node s) {
        // run SSSP algorithm and keep track of everything
        std::unique_ptr<SSSP> sssp;
        if (G.isWeighted()) {
            sssp.reset(new Dijkstra(G, s, true, true));
        } else {
            sssp.reset(new BFS(G, s, true, true));
        }

        sssp->run();

        G.forNodes([&](node t){
            distances[s][t] = sssp->distance(t);
            npaths[s][t] = sssp->numberOfPaths(t);
            if (storePreds) {
                predecessors[s][t] = sssp->getPredecessors(t);
            }
        });

        // compute dependencies for nodes in order of decreasing distance from s
        std::stack<node> stack = sssp->getStack();
        // set maxDistance to the distance of the furthest vertex
        maxDistance[s] = distances[s][stack.top()];
        while (!stack.empty()) {
            node t = stack.top();
            stack.pop();
            for (node p : sssp->getPredecessors(t)) {
                dependencies[s][p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dependencies[s][t]);
            }
            if (t != s) {
                scoreData[t] += dependencies[s][t];
            }
        }
    };

    G.forNodes(computeDependencies);
}

void DynBetweenness::updateUnweighted(GraphEvent e) {
    G.forNodes([&] (node s){
        node u_l, u_h;
        if (distances[s][e.u] > distances[s][e.v]){
            u_l = e.u;
            u_h = e.v;
        } else {
            u_l = e.v;
            u_h = e.u;
        }
        edgeweight difference = distances[s][u_l] - distances[s][u_h];
        if (difference > 0) {
            std::vector<count> new_npaths(G.upperNodeIdBound());
            std::vector<edgeweight> new_dist(G.upperNodeIdBound());
            G.forNodes([&] (node v){
                new_npaths[v] = npaths[s][v];
                new_dist[v] = distances[s][v];
            });
            std::vector<double> new_dep(G.upperNodeIdBound(), 0.0);
            std::vector<int> touched(G.upperNodeIdBound(), 0);
            std::vector<std::queue<node>> l_queues(maxDistance[s]+1);
            std::queue<node> queue_BFS;
            queue_BFS.push(u_l);
            // one-level update
            if (difference == 1) {
                l_queues[distances[s][u_l]].push(u_l);
                if (storePreds)
                    predecessors[s][u_l].push_back(u_h);
                new_npaths[u_l] += npaths[s][u_h];
                touched[u_l] = -1;
                // BFS traversal from u_l
                while (!queue_BFS.empty()) {
                    node v = queue_BFS.front();
                    DEBUG("extracted node ", v);
                    queue_BFS.pop();
                    G.forNeighborsOf(v, [&](node w) {
                        if (new_dist[w] == new_dist[v]+1) {
                            if (touched[w] == 0) {
                                touched[w] = -1;
                                queue_BFS.push(w);
                                l_queues[new_dist[w]].push(w);
                            }
                            new_npaths[w] = new_npaths[w] - npaths[s][v] + new_npaths[v];
                        }
                    });
                }
            } else if (difference > 1) {
                new_dist[u_l] = distances[s][u_h] + 1;
                l_queues[new_dist[u_l]].push(u_l);
                // BFS traversal from u_l
                while (!queue_BFS.empty()) {
                    node v = queue_BFS.front();
                    DEBUG("extracted node ",v);
                    if (storePreds) {
                        predecessors[s][v].clear();
                    }
                    queue_BFS.pop();
                    touched[v] = -1;
                    new_npaths[v] = 0;
                    G.forNeighborsOf(v, [&] (node w){
                            if (new_dist[w] + 1 == new_dist[v]) {
                                new_npaths[v] += new_npaths[w];
                                if (storePreds) {
                                    predecessors[s][v].push_back(w);
                                }
                            }
                            if (new_dist[w] >= new_dist[v] && touched[w] == 0) {
                                if (new_dist[w] > new_dist[v])
                                    new_dist[w] = new_dist[v]+1;
                                touched[w] = -1;
                                l_queues[new_dist[w]].push(w);
                                queue_BFS.push(w);
                            }
                    });
                }
            }
            // dependencies accumulation
            DEBUG("Dependency accumulation");
            count level = maxDistance[s];
            while(level > 0) {
                while(!l_queues[level].empty()) {
                    node w = l_queues[level].front();
                    DEBUG("Node ",w);
                    l_queues[level].pop();
                    auto updateDependency = [&](node w, node v) {
                        if (new_dist[v] < new_dist[w]) {
                            if (touched[v] == 0) {
                                touched[v] = 1;
                                new_dep[v] = dependencies[s][v];
                                l_queues[level-1].push(v);
                            }
                            double new_contrib = double(new_npaths[v])/new_npaths[w]*(1+new_dep[w]);
                            new_dep[v] += new_contrib;
                            double old_contrib = double(npaths[s][v])/npaths[s][w]*(1+dependencies[s][w]);
                            if (touched[v] == 1 && (v != u_h or w!= u_l))
                                new_dep[v] -= old_contrib;
                            DEBUG("Parent ", v);
                        }
                    };
                    if (storePreds) {
                        for (node v : predecessors[s][w]) {
                            updateDependency(w, v);
                        }
                    }
                    else {
                        G.forNeighborsOf(w, [&](node v){
                            updateDependency(w, v);
                        });
                    }
                    if (w != s) {
                        scoreData[w] = scoreData[w] + new_dep[w] - dependencies[s][w];
                    }
                }
                level = level - 1;
            }
            // data structures update
            G.forNodes([&] (node r){
                distances[s][r] = new_dist[r];
                npaths[s][r] = new_npaths[r];
                if (touched[r] != 0)
                    dependencies[s][r] = new_dep[r];
            });
        }
/*

        BFS sssp(G, s, true, true);
        sssp.run();
        G.forNodes([&](node t){
            if(distances[s][t] != sssp.distance(t) || npaths[s][t] != sssp.numberOfPaths(t)) {
                std::cout<<"Source: "<<s<<"  Node "<<t<<std::endl;
                std::cout<<"COMPUTED DISTANCE: "<<distances[s][t]<<"  REAL DISTANCE: "<<sssp.distance(t)<<std::endl;
                std::cout<<"COMPUTED NUMBER OF PATHS: "<<npaths[s][t]<<"  REAL NUMBER OF PATHS: "<<sssp.numberOfPaths(t)<<std::endl;
            }
        });

        // compute dependencies for nodes in order of decreasing distance from s
        std::vector<double> dep(G.upperNodeIdBound());
        std::stack<node> stack = sssp.getStack();
        while (!stack.empty()) {
            node t = stack.top();
            stack.pop();
            for (node p : sssp.getPredecessors(t)) {
                dep[p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dep[t]);
            }
        }

        G.forNodes([&](node t){
            if((dependencies[s][t]-dep[t]>0.000001 || dependencies[s][t]-dep[t]<-0.000001) && s!=t) {
                std::cout<<"Source: "<<s<<"  Node "<<t<<std::endl;
                std::cout<<"COMPUTED DEPENDENCY: "<<dependencies[s][t]<<"  REAL DEPENDENCY: "<<dep[t]<<std::endl;
            }
        });

*/

    });
}

void DynBetweenness::updateWeighted(GraphEvent e) {
    G.forNodes([&] (node s){
        scoreData[s] = 0.0;
    });
    G.forNodes([&] (node s){
        // update of distances and number of shortest paths
        Aux::PrioQueue<double, node> S(G.upperNodeIdBound());
        G.forNodes([&] (node t){
            auto updatePaths = [&](node u, node v, edgeweight w) {
                if (distances[s][t] == distances[s][u] + w + distances[v][t]){
                    npaths[s][t] = npaths[s][t] + npaths[s][u] * npaths[v][t];
                    if (storePreds) {
                        if (t != v){
                            DEBUG("Adding predecessors from v to t to predecessors from s to t");
                            //predecessors[s][t].insert( predecessors[s][t].end(), predecessors[v][t].begin(), predecessors[v][t].end());
                            for (node pv : predecessors[v][t]) {
                                bool wasAlreadyPred = false;
                                for (node ps : predecessors[s][t]) {
                                    if (ps == pv)
                                        wasAlreadyPred = true;
                                }
                                if (!wasAlreadyPred)
                                    predecessors[s][t].push_back(pv);
                            }
                            DEBUG("Finished adding");
                        }
                        else {
                            DEBUG("Adding u to the predecessors of v");
                            predecessors[s][t].push_back(u);
                            DEBUG("Finished adding");
                        }
                    }
                }
                if (distances[s][t] > distances[s][u] + w + distances[v][t]){
                    distances[s][t] = distances[s][u] + w + distances[v][t];
                    npaths[s][t] = npaths[s][u] * npaths[v][t];
                    if (storePreds) {
                        if (t != v) {
                            DEBUG("Replacing predecessors from v to t with predecessors from s to t");
                            predecessors[s][t] = predecessors[v][t];
                            DEBUG("Finished replacing");
                        }
                        else {
                            DEBUG("Replacing old predecessors of v with u");
                            predecessors[s][t].clear();
                            predecessors[s][t].push_back(u);
                            DEBUG("Finished replacing");
                        }
                    }
                }
            };
            if (s != t) {
                updatePaths(e.u, e.v, e.w);
                updatePaths(e.v, e.u, e.w);
                S.insert(-1*distances[s][t], t);
                dependencies[s][t] = 0.0;
            }
        });
        // dependency accumulation
        while (S.size() != 0) {
            // extract the node with the maximum distance
            node t = S.extractMin().second;
            if (storePreds) {
                DEBUG("Computing dependencies");
                for (node p : predecessors[s][t]) {
                    dependencies[s][p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dependencies[s][t]);
                }
            }
            else {
                G.forNeighborsOf(t, [&] (node p){
                    if (logically_equal(distances[s][t], distances[s][p] + G.weight(p, t))) {
                        dependencies[s][p] += (double(npaths[s][p]) / npaths[s][t])  * (1 + dependencies[s][t]);
                    }
                });
            }
            if (t != s) {
                scoreData[t] += dependencies[s][t];
            }
        }

    });

}

void DynBetweenness::update(GraphEvent e) {
    if (G.isWeighted())
        updateWeighted(e);
    else
        updateUnweighted(e);
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file transaction.cpp
 * @author Dmitrii Khokhlov <winsvega@mail.ru>
 * @date 2015
 * Transaaction test functions.
 */

#include "TestHelper.h"

using namespace std;
using namespace json_spirit;
using namespace dev;
using namespace dev::eth;
using namespace dev::eth;

namespace dev {  namespace test {

Transaction createTransactionFromFields(mObject& _tObj)
{
	BOOST_REQUIRE(_tObj.count("data") > 0);
	BOOST_REQUIRE(_tObj.count("value") > 0);
	BOOST_REQUIRE(_tObj.count("gasPrice") > 0);
	BOOST_REQUIRE(_tObj.count("gasLimit") > 0);
	BOOST_REQUIRE(_tObj.count("nonce")> 0);
	BOOST_REQUIRE(_tObj.count("to") > 0);

	BOOST_REQUIRE(_tObj.count("v") > 0);
	BOOST_REQUIRE(_tObj.count("r") > 0);
	BOOST_REQUIRE(_tObj.count("s") > 0);

	//Construct Rlp of the given transaction
	RLPStream rlpStream;
	rlpStream.appendList(9);
	rlpStream <<  bigint(_tObj["nonce"].get_str()) << bigint(_tObj["gasPrice"].get_str()) << bigint(_tObj["gasLimit"].get_str());
	if (_tObj["to"].get_str().empty())
		rlpStream << "";
	else
		rlpStream << Address(_tObj["to"].get_str());
	rlpStream << bigint(_tObj["value"].get_str()) << importData(_tObj);
	u256 r = h256(fromHex(_tObj["r"].get_str()));
	u256 s = h256(fromHex(_tObj["s"].get_str()));
	rlpStream << bigint(_tObj["v"].get_str()) << r << s;

	return Transaction(rlpStream.out(), CheckSignature::Sender);
}

void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
	for (auto& i: _v.get_obj())
	{
		cerr << i.first << endl;
		mObject& o = i.second.get_obj();

		if (_fillin == false)
		{
			BOOST_REQUIRE(o.count("rlp") > 0);
			bytes rlpReaded = importByteArray(o["rlp"].get_str());
			Transaction txFromRlp;

			try
			{
				txFromRlp = Transaction(rlpReaded, CheckSignature::Sender);
				if (!txFromRlp.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );
			}
			catch(...)
			{
				BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transction object should not be defined because the RLP is invalid!");
				return;
			}

			BOOST_REQUIRE(o.count("transaction") > 0);

			mObject tObj = o["transaction"].get_obj();
			Transaction txFromFields = createTransactionFromFields(tObj);

			//Check the fields restored from RLP to original fields
			BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!");
			BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), "Value in given RLP not matching the Transaction value!");
			BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), "GasPrice in given RLP not matching the Transaction gasPrice!");
			BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(),"Gas in given RLP not matching the Transaction gas!");
			BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(),"Nonce in given RLP not matching the Transaction nonce!");
			BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), "Receive address in given RLP not matching the Transaction 'to' address!");
			BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
			BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, "However, txFromFields != txFromRlp!");
			BOOST_REQUIRE (o.count("sender") > 0);

			Address addressReaded = Address(o["sender"].get_str());
			BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, "Signature address of sender does not match given sender address!");
		}
		else
		{
			BOOST_REQUIRE(o.count("transaction") > 0);
			mObject tObj = o["transaction"].get_obj();

			//Construct Rlp of the given transaction
			RLPStream rlpStream;
			rlpStream.appendList(tObj.size());

			if (tObj.count("nonce") > 0)
				rlpStream << bigint(tObj["nonce"].get_str());

			if (tObj.count("gasPrice") > 0)
				rlpStream << bigint(tObj["gasPrice"].get_str());

			if (tObj.count("gasLimit") > 0)
				rlpStream << bigint(tObj["gasLimit"].get_str());

			if (tObj.count("to") > 0)
			{
				if (tObj["to"].get_str().empty())
					rlpStream << "";
				else
					rlpStream << Address(tObj["to"].get_str());
			}

			if (tObj.count("value") > 0)
				rlpStream << bigint(tObj["value"].get_str());

			if (tObj.count("data") > 0)
				rlpStream << importData(tObj);

			if (tObj.count("v") > 0)
				rlpStream << bigint(tObj["v"].get_str());

			if (tObj.count("r") > 0)
			{
				u256 r = h256(fromHex(tObj["r"].get_str()));
				rlpStream << r;
			}

			if (tObj.count("s") > 0)
			{
				u256 s = h256(fromHex(tObj["s"].get_str()));
				rlpStream << s;
			}

			if (tObj.count("extrafield") > 0)
				rlpStream << bigint(tObj["extrafield"].get_str());

			o["rlp"] = "0x" + toHex(rlpStream.out());

			try
			{
				Transaction txFromFields(rlpStream.out(), CheckSignature::Sender);
				if (!txFromFields.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );

				o["sender"] = toString(txFromFields.sender());
			}
			catch(...)
			{
				o.erase(o.find("transaction"));
			}
		}
	}//for
}//doTransactionTests

} }// Namespace Close

BOOST_AUTO_TEST_SUITE(TransactionTests)

BOOST_AUTO_TEST_CASE(TransactionTest)
{
	dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(tt10mbDataField)
{
	dev::test::executeTests("tt10mbDataField", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(ttCreateTest)
{
	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
	{
		string arg = boost::unit_test::framework::master_test_suite().argv[i];
		if (arg == "--createtest")
		{
			if (boost::unit_test::framework::master_test_suite().argc <= i + 2)
			{
				cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n";
				return;
			}
			try
			{
				cnote << "Populating tests...";
				json_spirit::mValue v;
				string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1]));
				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty.");
				json_spirit::read_string(s, v);
				dev::test::doTransactionTests(v, true);
				writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true)));
			}
			catch (Exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << diagnostic_information(_e));
			}
			catch (std::exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << _e.what());
			}
		}
	}
}

BOOST_AUTO_TEST_CASE(userDefinedFileTT)
{
	dev::test::userDefinedTest("--ttTest", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>minor changes<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file transaction.cpp
 * @author Dmitrii Khokhlov <winsvega@mail.ru>
 * @date 2015
 * Transaaction test functions.
 */

#include "TestHelper.h"

using namespace std;
using namespace json_spirit;
using namespace dev;
using namespace dev::eth;
using namespace dev::eth;

namespace dev {  namespace test {

Transaction createTransactionFromFields(mObject& _tObj)
{
	BOOST_REQUIRE(_tObj.count("data") > 0);
	BOOST_REQUIRE(_tObj.count("value") > 0);
	BOOST_REQUIRE(_tObj.count("gasPrice") > 0);
	BOOST_REQUIRE(_tObj.count("gasLimit") > 0);
	BOOST_REQUIRE(_tObj.count("nonce")> 0);
	BOOST_REQUIRE(_tObj.count("to") > 0);

	BOOST_REQUIRE(_tObj.count("v") > 0);
	BOOST_REQUIRE(_tObj.count("r") > 0);
	BOOST_REQUIRE(_tObj.count("s") > 0);

	//Construct Rlp of the given transaction
	RLPStream rlpStream;
	rlpStream.appendList(9);
	rlpStream <<  bigint(_tObj["nonce"].get_str()) << bigint(_tObj["gasPrice"].get_str()) << bigint(_tObj["gasLimit"].get_str());
	if (_tObj["to"].get_str().empty())
		rlpStream << "";
	else
		rlpStream << Address(_tObj["to"].get_str());
	rlpStream << bigint(_tObj["value"].get_str()) << importData(_tObj);
	rlpStream << bigint(_tObj["v"].get_str()) << bigint(_tObj["r"].get_str()) << bigint(_tObj["s"].get_str());

	return Transaction(rlpStream.out(), CheckSignature::Sender);
}

void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
	for (auto& i: _v.get_obj())
	{
		cerr << i.first << endl;
		mObject& o = i.second.get_obj();

		if (_fillin == false)
		{
			BOOST_REQUIRE(o.count("rlp") > 0);
			bytes rlpReaded = importByteArray(o["rlp"].get_str());
			Transaction txFromRlp;

			try
			{
				txFromRlp = Transaction(rlpReaded, CheckSignature::Sender);
				if (!txFromRlp.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );
			}
			catch(...)
			{
				BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transction object should not be defined because the RLP is invalid!");
				return;
			}

			BOOST_REQUIRE(o.count("transaction") > 0);

			mObject tObj = o["transaction"].get_obj();
			Transaction txFromFields = createTransactionFromFields(tObj);

			//Check the fields restored from RLP to original fields
			BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!");
			BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), "Value in given RLP not matching the Transaction value!");
			BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), "GasPrice in given RLP not matching the Transaction gasPrice!");
			BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(),"Gas in given RLP not matching the Transaction gas!");
			BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(),"Nonce in given RLP not matching the Transaction nonce!");
			BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), "Receive address in given RLP not matching the Transaction 'to' address!");
			BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
			BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, "However, txFromFields != txFromRlp!");
			BOOST_REQUIRE (o.count("sender") > 0);

			Address addressReaded = Address(o["sender"].get_str());
			BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, "Signature address of sender does not match given sender address!");
		}
		else
		{
			BOOST_REQUIRE(o.count("transaction") > 0);
			mObject tObj = o["transaction"].get_obj();

			//Construct Rlp of the given transaction
			RLPStream rlpStream;
			rlpStream.appendList(tObj.size());

			if (tObj.count("nonce") > 0)
				rlpStream << bigint(tObj["nonce"].get_str());

			if (tObj.count("gasPrice") > 0)
				rlpStream << bigint(tObj["gasPrice"].get_str());

			if (tObj.count("gasLimit") > 0)
				rlpStream << bigint(tObj["gasLimit"].get_str());

			if (tObj.count("to") > 0)
			{
				if (tObj["to"].get_str().empty())
					rlpStream << "";
				else
					rlpStream << Address(tObj["to"].get_str());
			}

			if (tObj.count("value") > 0)
				rlpStream << bigint(tObj["value"].get_str());

			if (tObj.count("data") > 0)
				rlpStream << importData(tObj);

			if (tObj.count("v") > 0)
				rlpStream << bigint(tObj["v"].get_str());

			if (tObj.count("r") > 0)
				rlpStream << bigint(tObj["r"].get_str());

			if (tObj.count("s") > 0)
				rlpStream <<  bigint(tObj["s"].get_str());

			if (tObj.count("extrafield") > 0)
				rlpStream << bigint(tObj["extrafield"].get_str());

			o["rlp"] = "0x" + toHex(rlpStream.out());

			try
			{
				Transaction txFromFields(rlpStream.out(), CheckSignature::Sender);
				if (!txFromFields.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );

				o["sender"] = toString(txFromFields.sender());
			}
			catch(...)
			{
				o.erase(o.find("transaction"));
			}
		}
	}//for
}//doTransactionTests

} }// Namespace Close

BOOST_AUTO_TEST_SUITE(TransactionTests)

BOOST_AUTO_TEST_CASE(TransactionTest)
{
	dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(tt10mbDataField)
{
	dev::test::executeTests("tt10mbDataField", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(ttCreateTest)
{
	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
	{
		string arg = boost::unit_test::framework::master_test_suite().argv[i];
		if (arg == "--createtest")
		{
			if (boost::unit_test::framework::master_test_suite().argc <= i + 2)
			{
				cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n";
				return;
			}
			try
			{
				cnote << "Populating tests...";
				json_spirit::mValue v;
				string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1]));
				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty.");
				json_spirit::read_string(s, v);
				dev::test::doTransactionTests(v, true);
				writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true)));
			}
			catch (Exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << diagnostic_information(_e));
			}
			catch (std::exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << _e.what());
			}
		}
	}
}

BOOST_AUTO_TEST_CASE(userDefinedFileTT)
{
	dev::test::userDefinedTest("--ttTest", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


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

#include <array>
#include <future>
#include <iostream>
#include <vector>

#include <glog/logging.h>

#include <folly/gen/Base.h>
#include <folly/gen/Parallel.h>
#include <folly/gen/test/Bench.h>

DEFINE_int32(
    threads,
    std::max(1, (int32_t)sysconf(_SC_NPROCESSORS_CONF) / 2),
    "Num threads.");

using namespace folly::gen;
using std::vector;

constexpr int kFib = 28; // unit of work
size_t fib(int n) {
  return n <= 1 ? 1 : fib(n - 1) + fib(n - 2);
}

static auto isPrimeSlow = [](int n) {
  if (n < 2) {
    return false;
  } else if (n > 2) {
    for (int d = 3; d * d <= n; d += 2) {
      if (0 == n % d) {
        return false;
      }
    }
  }
  return true;
};

static auto primes = seq(1, 1 << 20) | filter(isPrimeSlow) | as<vector>();

static auto stopc(int n) {
  return [=](int d) { return d * d > n; };
}
static auto divides(int n) {
  return [=](int d) { return 0 == n % d; };
}

static auto isPrime = [](int n) {
  return from(primes) | until(stopc(n)) | filter(divides(n)) | isEmpty;
};

static auto factors = [](int n) {
  return from(primes) | until(stopc(n)) | filter(divides(n)) | count;
};

static auto factorsSlow = [](int n) {
  return from(primes) | filter(divides(n)) | count;
};

static auto sleepyWork = [](int i) {
  const auto sleepyTime = std::chrono::microseconds(100);
  std::this_thread::sleep_for(sleepyTime);
  return i;
};

static auto sleepAndWork = [](int i) { return factorsSlow(i) + sleepyWork(i); };

auto start = 1 << 20;
auto v = seq(start) | take(1 << 20) | as<vector>();
auto small = from(v) | take(1 << 12);
auto medium = from(v) | take(1 << 14);
auto large = from(v) | take(1 << 18);
auto huge = from(v);
auto chunks = chunked(v);

BENCH_GEN(small | map(factorsSlow) | sum);
BENCH_GEN_REL(small | parallel(map(factorsSlow)) | sum);
BENCHMARK_DRAW_LINE();

BENCH_GEN(small | map(factors) | sum);
BENCH_GEN_REL(small | parallel(map(factors)) | sum);
BENCHMARK_DRAW_LINE();

BENCH_GEN(large | map(factors) | sum);
BENCH_GEN_REL(large | parallel(map(factors)) | sum);
BENCHMARK_DRAW_LINE();

auto ch = chunks;
auto cat = concat;
BENCH_GEN(huge | filter(isPrime) | count);
BENCH_GEN_REL(ch | cat | filter(isPrime) | count);
BENCH_GEN_REL(ch | parallel(cat | filter(isPrime)) | count);
BENCH_GEN_REL(ch | parallel(cat | filter(isPrime) | sub(count)) | sum);
BENCHMARK_DRAW_LINE();

BENCH_GEN(small | map(sleepAndWork) | sum);
BENCH_GEN_REL(small | parallel(map(sleepAndWork)) | sum);
BENCHMARK_DRAW_LINE();

const int fibs = 1000;
BENCH_GEN(seq(1, fibs) | map([](int) { return fib(kFib); }) | sum);
// clang-format off
BENCH_GEN_REL(
    seq(1, fibs)
      | parallel(map([](int) { return fib(kFib); }) | sub(sum))
      | sum);
// clang-format on
BENCH_GEN_REL([] {
  // clang-format off
  auto threads = seq(1, int(FLAGS_threads))
      | map([](int i) {
        return std::thread([=] {
          return range(
              (i + 0) * fibs / FLAGS_threads, (i + 1) * fibs / FLAGS_threads)
              | map([](int) { return fib(kFib); })
              | sum;
        });
      })
      | as<vector>();
  from(threads) | [](std::thread &thread) { thread.join(); };
  // clang-format on
  return 1;
}());
BENCHMARK_DRAW_LINE();

#if 0
============================================================================
folly/gen/test/ParallelBenchmark.cpp            relative  time/iter  iters/s
============================================================================
small | map(factorsSlow) | sum                                4.59s  217.87m
small | parallel(map(factorsSlow)) | sum        1588.86%   288.88ms     3.46
----------------------------------------------------------------------------
small | map(factors) | sum                                   9.62ms   103.94
small | parallel(map(factors)) | sum              89.15%    10.79ms    92.66
----------------------------------------------------------------------------
large | map(factors) | sum                                 650.52ms     1.54
large | parallel(map(factors)) | sum              53.82%      1.21s  827.41m
----------------------------------------------------------------------------
huge | filter(isPrime) | count                             295.93ms     3.38
ch | cat | filter(isPrime) | count                99.76%   296.64ms     3.37
ch | parallel(cat | filter(isPrime)) | count     142.75%   207.31ms     4.82
ch | parallel(cat | filter(isPrime) | sub(count 1538.50%    19.24ms    51.99
----------------------------------------------------------------------------
small | map(sleepAndWork) | sum                               5.37s  186.18m
small | parallel(map(sleepAndWork)) | sum       1840.38%   291.85ms     3.43
----------------------------------------------------------------------------
seq(1, fibs) | map([](int) { return fib(kFib);                1.49s  669.53m
seq(1, fibs) | parallel(map([](int) { return fi 1698.07%    87.96ms    11.37
[] { auto threads = seq(1, int(FLAGS_threads))  1571.16%    95.06ms    10.52
----------------------------------------------------------------------------
============================================================================
#endif
int main(int argc, char* argv[]) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  folly::runBenchmarks();
  return 0;
}
<commit_msg>Fix folly/gen/test/ParallelBenchmark.cpp under gcc8 with -Wshadow<commit_after>/*
 * Copyright 2014-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <array>
#include <future>
#include <iostream>
#include <vector>

#include <glog/logging.h>

#include <folly/gen/Base.h>
#include <folly/gen/Parallel.h>
#include <folly/gen/test/Bench.h>

DEFINE_int32(
    threads,
    std::max(1, (int32_t)sysconf(_SC_NPROCESSORS_CONF) / 2),
    "Num threads.");

using namespace folly::gen;
using std::vector;

constexpr int kFib = 28; // unit of work
size_t fib(int n) {
  return n <= 1 ? 1 : fib(n - 1) + fib(n - 2);
}

namespace {
static auto isPrimeSlow = [](int n) {
  if (n < 2) {
    return false;
  } else if (n > 2) {
    for (int d = 3; d * d <= n; d += 2) {
      if (0 == n % d) {
        return false;
      }
    }
  }
  return true;
};

static auto primes = seq(1, 1 << 20) | filter(isPrimeSlow) | as<vector>();

static auto stopc(int n) {
  return [=](int d) { return d * d > n; };
}
static auto divides(int n) {
  return [=](int d) { return 0 == n % d; };
}

static auto isPrime = [](int n) {
  return from(primes) | until(stopc(n)) | filter(divides(n)) | isEmpty;
};

static auto factors = [](int n) {
  return from(primes) | until(stopc(n)) | filter(divides(n)) | count;
};

static auto factorsSlow = [](int n) {
  return from(primes) | filter(divides(n)) | count;
};

static auto sleepyWork = [](int i) {
  const auto sleepyTime = std::chrono::microseconds(100);
  std::this_thread::sleep_for(sleepyTime);
  return i;
};

static auto sleepAndWork = [](int i) { return factorsSlow(i) + sleepyWork(i); };

auto start = 1 << 20;
auto v = seq(start) | take(1 << 20) | as<vector>();
auto small = from(v) | take(1 << 12);
auto medium = from(v) | take(1 << 14);
auto large = from(v) | take(1 << 18);
auto huge = from(v);
auto chunks = chunked(v);
} // namespace

BENCH_GEN(small | map(factorsSlow) | sum);
BENCH_GEN_REL(small | parallel(map(factorsSlow)) | sum);
BENCHMARK_DRAW_LINE();

BENCH_GEN(small | map(factors) | sum);
BENCH_GEN_REL(small | parallel(map(factors)) | sum);
BENCHMARK_DRAW_LINE();

BENCH_GEN(large | map(factors) | sum);
BENCH_GEN_REL(large | parallel(map(factors)) | sum);
BENCHMARK_DRAW_LINE();

auto ch = chunks;
auto cat = concat;
BENCH_GEN(huge | filter(isPrime) | count);
BENCH_GEN_REL(ch | cat | filter(isPrime) | count);
BENCH_GEN_REL(ch | parallel(cat | filter(isPrime)) | count);
BENCH_GEN_REL(ch | parallel(cat | filter(isPrime) | sub(count)) | sum);
BENCHMARK_DRAW_LINE();

BENCH_GEN(small | map(sleepAndWork) | sum);
BENCH_GEN_REL(small | parallel(map(sleepAndWork)) | sum);
BENCHMARK_DRAW_LINE();

const int fibs = 1000;
BENCH_GEN(seq(1, fibs) | map([](int) { return fib(kFib); }) | sum);
// clang-format off
BENCH_GEN_REL(
    seq(1, fibs)
      | parallel(map([](int) { return fib(kFib); }) | sub(sum))
      | sum);
// clang-format on
BENCH_GEN_REL([] {
  // clang-format off
  auto threads = seq(1, int(FLAGS_threads))
      | map([](int i) {
        return std::thread([=] {
          return range(
              (i + 0) * fibs / FLAGS_threads, (i + 1) * fibs / FLAGS_threads)
              | map([](int) { return fib(kFib); })
              | sum;
        });
      })
      | as<vector>();
  from(threads) | [](std::thread &thread) { thread.join(); };
  // clang-format on
  return 1;
}());
BENCHMARK_DRAW_LINE();

#if 0
============================================================================
folly/gen/test/ParallelBenchmark.cpp            relative  time/iter  iters/s
============================================================================
small | map(factorsSlow) | sum                                4.59s  217.87m
small | parallel(map(factorsSlow)) | sum        1588.86%   288.88ms     3.46
----------------------------------------------------------------------------
small | map(factors) | sum                                   9.62ms   103.94
small | parallel(map(factors)) | sum              89.15%    10.79ms    92.66
----------------------------------------------------------------------------
large | map(factors) | sum                                 650.52ms     1.54
large | parallel(map(factors)) | sum              53.82%      1.21s  827.41m
----------------------------------------------------------------------------
huge | filter(isPrime) | count                             295.93ms     3.38
ch | cat | filter(isPrime) | count                99.76%   296.64ms     3.37
ch | parallel(cat | filter(isPrime)) | count     142.75%   207.31ms     4.82
ch | parallel(cat | filter(isPrime) | sub(count 1538.50%    19.24ms    51.99
----------------------------------------------------------------------------
small | map(sleepAndWork) | sum                               5.37s  186.18m
small | parallel(map(sleepAndWork)) | sum       1840.38%   291.85ms     3.43
----------------------------------------------------------------------------
seq(1, fibs) | map([](int) { return fib(kFib);                1.49s  669.53m
seq(1, fibs) | parallel(map([](int) { return fi 1698.07%    87.96ms    11.37
[] { auto threads = seq(1, int(FLAGS_threads))  1571.16%    95.06ms    10.52
----------------------------------------------------------------------------
============================================================================
#endif
int main(int argc, char* argv[]) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  folly::runBenchmarks();
  return 0;
}
<|endoftext|>


<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

// MOOSE includes
#include "DOFMapOutput.h"
#include "FEProblem.h"
#include "KernelBase.h"
#include "MooseApp.h"
#include "Moose.h"

// libMesh includes
#include "libmesh/fe.h"

template<>
InputParameters validParams<DOFMapOutput>()
{
  // Get the parameters from the base class
  InputParameters params = validParams<FileOutput>();
  params += Output::enableOutputTypes("system_information");

  // Screen and file output toggles
  params.addParam<bool>("output_screen", false, "Output to the screen");
  params.addParam<bool>("output_file", true, "Output to the file");
  params.addParam<std::string>("system_name", "nl0", "System to output");
  return params;
}

DOFMapOutput::DOFMapOutput(const std::string & name, InputParameters parameters) :
    FileOutput(name, parameters),
    _write_file(getParam<bool>("output_file")),
    _write_screen(getParam<bool>("output_screen")),
    _system_name(getParam<std::string>("system_name")),
    _mesh(_mci_feproblem.mesh()),
    _console_buffer(_app.getOutputWarehouse().consoleBuffer())
{
  // Set output coloring
  if (Moose::_color_console)
  {
    char * term_env = getenv("TERM");
    if (term_env)
    {
      std::string term(term_env);
      if (term != "xterm-256color" && term != "xterm")
        Moose::_color_console = false;
    }
  }
}

DOFMapOutput::~DOFMapOutput()
{
  // Write the file output stream
  writeStreamToFile();
}

void
DOFMapOutput::initialSetup()
{
  // If file output is desired, wipe out the existing file if not recovering
  if (!_app.isRecovering())
    writeStreamToFile(false);

  // Output the system information
  if (_system_information && _allow_output)
    outputSystemInformation();
}

std::string
DOFMapOutput::filename()
{
  return _file_base + ".json";
}

void
DOFMapOutput::writeStreamToFile(bool append)
{
  if (!_write_file)
    return;

  // Create the stream
  std::ofstream output;

  // Open the file
  if (append)
    output.open(filename().c_str(), std::ios::app | std::ios::out);
  else
    output.open(filename().c_str(), std::ios::trunc);

  // Write contents of file output stream and close the file
  output << _file_output_stream.str();
  output.close();

  // Clear the file output stream
  _file_output_stream.str("");
}

template<typename T>
std::string
DOFMapOutput::join(const T & begin, const T & end, const char* const delim)
{
  std::ostringstream os;
  for (T it = begin; it != end; ++it)
    os << (it != begin ? delim : "") << *it;
  return os.str();
}

void
DOFMapOutput::write(std::string message)
{
  // Do nothing if the message is empty, writing empty strings messes with multiapp indenting
  if (message.empty())
    return;

  // Write the message to file
  if (_write_file)
    _file_output_stream << message << std::endl;

  // Write message to the screen
  if (_write_screen)
    Moose::out << message;
}

void
DOFMapOutput::mooseConsoleOutput(const std::string & message)
{
  // Write the messages
  write(message);

  // Flush the stream to the screen
  Moose::out << std::flush;
}

void
DOFMapOutput::outputSystemInformation()
{
  // Don't build this information if nothing is to be written
  if (!_write_screen && !_write_file)
    return;

  std::stringstream oss;

  // Get the DOF Map through the equation system
  const System & sys = _problem_ptr->es().get_system(_system_name); // TransientNonlinearImplicit
  const DofMap & dof_map = sys.get_dof_map();

  // fetch the KernelWarehouse through the NonlinearSystem
  NonlinearSystem & nl = _problem_ptr->getNonlinearSystem();
  const KernelWarehouse & kernels = nl.getKernelWarehouse(0);

  // get a set of all subdomains
  const std::set<SubdomainID> & subdomains = _mesh.meshSubdomains();

  bool first = true;
  oss << '[';
  for (unsigned int vg = 0; vg < dof_map.n_variable_groups(); ++vg)
  {
    const VariableGroup &vg_description (dof_map.variable_group(vg));
    for (unsigned int vn = 0; vn < vg_description.n_variables(); ++vn)
    {
      unsigned int var = vg_description.number(vn);

      if (!first)
        oss << ", ";
      first = false;

      oss << "{\"var\": \"" << vg_description.name(vn) << "\", \"subdomains\": [";
      for (std::set<SubdomainID>::const_iterator sd = subdomains.begin(); sd != subdomains.end(); ++sd)
      {
        oss << (sd != subdomains.begin() ? ", " : "") << "{\"id\": " << *sd << ", \"kernels\": [";

        // build a list of all kernels in the current subdomain
        nl.updateActiveKernels(*sd, 0);
        const std::vector<KernelBase *> & active_kernels = kernels.activeVar(var);
        for (unsigned i = 0; i<active_kernels.size(); ++i)
          oss << (i>0 ? ", \"" : "\"") << active_kernels[i]->name() << '"';

        oss << "], \"dofs\": [";

        // get the list of unique DOFs for this variable
        std::set<dof_id_type> dofs;
        for (unsigned int i = 0; i < _mesh.nElem(); ++i)
          if (_mesh.elem(i)->subdomain_id() == *sd)
          {
            std::vector<dof_id_type> di;
            dof_map.dof_indices(_mesh.elem(i), di, var);
            dofs.insert(di.begin(), di.end());
          }
        oss << join(dofs.begin(), dofs.end(), ", ") << "]}";
      }
      oss << "]}";
    }
  }
  oss << "]\n";

  // Output the information
  write(oss.str());
}
<commit_msg>Total number of DOFs (#4155)<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

// MOOSE includes
#include "DOFMapOutput.h"
#include "FEProblem.h"
#include "KernelBase.h"
#include "MooseApp.h"
#include "Moose.h"

// libMesh includes
#include "libmesh/fe.h"

template<>
InputParameters validParams<DOFMapOutput>()
{
  // Get the parameters from the base class
  InputParameters params = validParams<FileOutput>();
  params += Output::enableOutputTypes("system_information");

  // Screen and file output toggles
  params.addParam<bool>("output_screen", false, "Output to the screen");
  params.addParam<bool>("output_file", true, "Output to the file");
  params.addParam<std::string>("system_name", "nl0", "System to output");
  return params;
}

DOFMapOutput::DOFMapOutput(const std::string & name, InputParameters parameters) :
    FileOutput(name, parameters),
    _write_file(getParam<bool>("output_file")),
    _write_screen(getParam<bool>("output_screen")),
    _system_name(getParam<std::string>("system_name")),
    _mesh(_mci_feproblem.mesh()),
    _console_buffer(_app.getOutputWarehouse().consoleBuffer())
{
  // Set output coloring
  if (Moose::_color_console)
  {
    char * term_env = getenv("TERM");
    if (term_env)
    {
      std::string term(term_env);
      if (term != "xterm-256color" && term != "xterm")
        Moose::_color_console = false;
    }
  }
}

DOFMapOutput::~DOFMapOutput()
{
  // Write the file output stream
  writeStreamToFile();
}

void
DOFMapOutput::initialSetup()
{
  // If file output is desired, wipe out the existing file if not recovering
  if (!_app.isRecovering())
    writeStreamToFile(false);

  // Output the system information
  if (_system_information && _allow_output)
    outputSystemInformation();
}

std::string
DOFMapOutput::filename()
{
  return _file_base + ".json";
}

void
DOFMapOutput::writeStreamToFile(bool append)
{
  if (!_write_file)
    return;

  // Create the stream
  std::ofstream output;

  // Open the file
  if (append)
    output.open(filename().c_str(), std::ios::app | std::ios::out);
  else
    output.open(filename().c_str(), std::ios::trunc);

  // Write contents of file output stream and close the file
  output << _file_output_stream.str();
  output.close();

  // Clear the file output stream
  _file_output_stream.str("");
}

template<typename T>
std::string
DOFMapOutput::join(const T & begin, const T & end, const char* const delim)
{
  std::ostringstream os;
  for (T it = begin; it != end; ++it)
    os << (it != begin ? delim : "") << *it;
  return os.str();
}

void
DOFMapOutput::write(std::string message)
{
  // Do nothing if the message is empty, writing empty strings messes with multiapp indenting
  if (message.empty())
    return;

  // Write the message to file
  if (_write_file)
    _file_output_stream << message << std::endl;

  // Write message to the screen
  if (_write_screen)
    Moose::out << message;
}

void
DOFMapOutput::mooseConsoleOutput(const std::string & message)
{
  // Write the messages
  write(message);

  // Flush the stream to the screen
  Moose::out << std::flush;
}

void
DOFMapOutput::outputSystemInformation()
{
  // Don't build this information if nothing is to be written
  if (!_write_screen && !_write_file)
    return;

  std::stringstream oss;

  // Get the DOF Map through the equation system
  const System & sys = _problem_ptr->es().get_system(_system_name); // TransientNonlinearImplicit
  const DofMap & dof_map = sys.get_dof_map();

  // fetch the KernelWarehouse through the NonlinearSystem
  NonlinearSystem & nl = _problem_ptr->getNonlinearSystem();
  const KernelWarehouse & kernels = nl.getKernelWarehouse(0);

  // get a set of all subdomains
  const std::set<SubdomainID> & subdomains = _mesh.meshSubdomains();

  bool first = true;
  oss << "{\"ndof\": " << sys.n_dofs() << ", \"vars\": [";
  for (unsigned int vg = 0; vg < dof_map.n_variable_groups(); ++vg)
  {
    const VariableGroup &vg_description (dof_map.variable_group(vg));
    for (unsigned int vn = 0; vn < vg_description.n_variables(); ++vn)
    {
      unsigned int var = vg_description.number(vn);

      if (!first)
        oss << ", ";
      first = false;

      oss << "{\"var\": \"" << vg_description.name(vn) << "\", \"subdomains\": [";
      for (std::set<SubdomainID>::const_iterator sd = subdomains.begin(); sd != subdomains.end(); ++sd)
      {
        oss << (sd != subdomains.begin() ? ", " : "") << "{\"id\": " << *sd << ", \"kernels\": [";

        // build a list of all kernels in the current subdomain
        nl.updateActiveKernels(*sd, 0);
        const std::vector<KernelBase *> & active_kernels = kernels.activeVar(var);
        for (unsigned i = 0; i<active_kernels.size(); ++i)
          oss << (i>0 ? ", \"" : "\"") << active_kernels[i]->name() << '"';

        oss << "], \"dofs\": [";

        // get the list of unique DOFs for this variable
        std::set<dof_id_type> dofs;
        for (unsigned int i = 0; i < _mesh.nElem(); ++i)
          if (_mesh.elem(i)->subdomain_id() == *sd)
          {
            std::vector<dof_id_type> di;
            dof_map.dof_indices(_mesh.elem(i), di, var);
            dofs.insert(di.begin(), di.end());
          }
        oss << join(dofs.begin(), dofs.end(), ", ") << "]}";
      }
      oss << "]}";
    }
  }
  oss << "]}\n";

  // Output the information
  write(oss.str());
}
<|endoftext|>