<commit_before>/*

Copyright (c) 2010, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 "libtorrent/storage.hpp"
#include "libtorrent/file_pool.hpp"

#include <boost/utility.hpp>

#include <stdlib.h>

using namespace libtorrent;

int main(int argc, char* argv[])
{
	if (argc != 3 && argc != 2)
	{
		fprintf(stderr, "Usage: fragmentation_test torrent-file file-storage-path\n"
			"       fragmentation_test file\n\n");
		return 1;
	}

	if (argc == 2)
	{
		error_code ec;
		file f(argv[1], file::read_only, ec);
		if (ec)
		{
			fprintf(stderr, "Error opening file %s: %s\n", argv[1], ec.message().c_str());
			return 1;
		}
		size_type off = f.phys_offset(0);
		printf("physical offset of file %s: %" PRId64 "\n", argv[1], off);
		return 0;
	}

	error_code ec;
	boost::intrusive_ptr<torrent_info> ti(new torrent_info(argv[1], ec));

	if (ec)
	{
		fprintf(stderr, "Error while loading torrent file: %s\n", ec.message().c_str());
		return 1;
	}

	file_pool fp;
	boost::shared_ptr<storage_interface> st(default_storage_constructor(ti->files(), 0, argv[2], fp, std::vector<boost::uint8_t>()));

	// the first field is the piece index, the second
	// one is the physical location of the piece on disk
	std::vector<std::pair<int, size_type> > pieces;

	// make sure all the files are there
	std::vector<std::pair<size_type, std::time_t> > files = get_filesizes(ti->files(), argv[2]);
	for (int i = 0; i < ti->num_files(); ++i)
	{
		if (ti->file_at(i).size == files[i].first) continue;
		fprintf(stderr, "Files for this torrent are missing or incomplete: %s was %"PRId64" bytes, expected %"PRId64" bytes\n"
			, ti->files().file_path(ti->file_at(i)).c_str(), files[i].first, ti->file_at(i).size);
		return 1;
	}

	for (int i = 0; i < ti->num_pieces(); ++i)
	{
		pieces.push_back(std::make_pair(i, st->physical_offset(i, 0)));
		if (pieces.back().second == size_type(i) * ti->piece_length())
		{
			// this suggests that the OS doesn't support physical offset
			// or that the file doesn't exist, or some other file error
			fprintf(stderr, "Your operating system or filesystem "
				"does not appear to support querying physical disk offset\n");
			return 1;
		}
	}

	FILE* f = fopen("fragmentation.log", "w+");
	if (f == 0)
	{
		fprintf(stderr, "error while opening log file: %s\n", strerror(errno));
		return 1;
	}

	for (int i = 0; i < ti->num_pieces(); ++i)
	{
		fprintf(f, "%d %"PRId64"\n", pieces[i].first, pieces[i].second);
	}

	fclose(f);

	f = fopen("fragmentation.gnuplot", "w+");
	if (f == 0)
	{
		fprintf(stderr, "error while opening gnuplot file: %s\n", strerror(errno));
		return 1;
	}

	fprintf(f,
		"set term png size 1200,800\n"
		"set output \"fragmentation.png\"\n"
		"set xrange [*:*]\n"
		"set xlabel \"piece\"\n"
		"set ylabel \"drive offset\"\n"
		"set key box\n"
		"set title \"fragmentation for '%s'\"\n"
		"set tics nomirror\n"
		"plot \"fragmentation.log\" using 1:2 with dots lt rgb \"#e07070\" notitle axis x1y1, x=0\n"
		, ti->name().c_str());

	fclose(f);

	system("gnuplot fragmentation.gnuplot");
}

<commit_msg>fix gnuplot syntax error in fragmentation test<commit_after>/*

Copyright (c) 2010, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 "libtorrent/storage.hpp"
#include "libtorrent/file_pool.hpp"

#include <boost/utility.hpp>

#include <stdlib.h>

using namespace libtorrent;

int main(int argc, char* argv[])
{
	if (argc != 3 && argc != 2)
	{
		fprintf(stderr, "Usage: fragmentation_test torrent-file file-storage-path\n"
			"       fragmentation_test file\n\n");
		return 1;
	}

	if (argc == 2)
	{
		error_code ec;
		file f(argv[1], file::read_only, ec);
		if (ec)
		{
			fprintf(stderr, "Error opening file %s: %s\n", argv[1], ec.message().c_str());
			return 1;
		}
		size_type off = f.phys_offset(0);
		printf("physical offset of file %s: %" PRId64 "\n", argv[1], off);
		return 0;
	}

	error_code ec;
	boost::intrusive_ptr<torrent_info> ti(new torrent_info(argv[1], ec));

	if (ec)
	{
		fprintf(stderr, "Error while loading torrent file: %s\n", ec.message().c_str());
		return 1;
	}

	file_pool fp;
	boost::shared_ptr<storage_interface> st(default_storage_constructor(ti->files(), 0, argv[2], fp, std::vector<boost::uint8_t>()));

	// the first field is the piece index, the second
	// one is the physical location of the piece on disk
	std::vector<std::pair<int, size_type> > pieces;

	// make sure all the files are there
	std::vector<std::pair<size_type, std::time_t> > files = get_filesizes(ti->files(), argv[2]);
	for (int i = 0; i < ti->num_files(); ++i)
	{
		if (ti->file_at(i).size == files[i].first) continue;
		fprintf(stderr, "Files for this torrent are missing or incomplete: %s was %"PRId64" bytes, expected %"PRId64" bytes\n"
			, ti->files().file_path(ti->file_at(i)).c_str(), files[i].first, ti->file_at(i).size);
		return 1;
	}

	for (int i = 0; i < ti->num_pieces(); ++i)
	{
		pieces.push_back(std::make_pair(i, st->physical_offset(i, 0)));
		if (pieces.back().second == size_type(i) * ti->piece_length())
		{
			// this suggests that the OS doesn't support physical offset
			// or that the file doesn't exist, or some other file error
			fprintf(stderr, "Your operating system or filesystem "
				"does not appear to support querying physical disk offset\n");
			return 1;
		}
	}

	FILE* f = fopen("fragmentation.log", "w+");
	if (f == 0)
	{
		fprintf(stderr, "error while opening log file: %s\n", strerror(errno));
		return 1;
	}

	for (int i = 0; i < ti->num_pieces(); ++i)
	{
		fprintf(f, "%d %"PRId64"\n", pieces[i].first, pieces[i].second);
	}

	fclose(f);

	f = fopen("fragmentation.gnuplot", "w+");
	if (f == 0)
	{
		fprintf(stderr, "error while opening gnuplot file: %s\n", strerror(errno));
		return 1;
	}

	fprintf(f,
		"set term png size 1200,800\n"
		"set output \"fragmentation.png\"\n"
		"set xrange [*:*]\n"
		"set xlabel \"piece\"\n"
		"set ylabel \"drive offset\"\n"
		"set key box\n"
		"set title \"fragmentation for '%s'\"\n"
		"set tics nomirror\n"
		"plot \"fragmentation.log\" using 1:2 with dots lt rgb \"#e07070\" notitle axis x1y1\n"
		, ti->name().c_str());

	fclose(f);

	system("gnuplot fragmentation.gnuplot");
}

<|endoftext|>


<commit_before>/*

  Safety Framework for Component-based Robotics

  Created on: August 13, 2012

  Copyright (C) 2012-2013 Min Yang Jung, Peter Kazanzides

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt)

*/

#include "config.h"
#include "common.h"
#include "json.h"
#include "monitor.h"
#include "cisstMonitor.h"
#include "cisstEventLocation.h"

#include <cisstCommon/cmnGetChar.h>
#include <cisstOSAbstraction/osaSleep.h>
#include <cisstMultiTask/mtsCollectorState.h>
#include <cisstMultiTask/mtsTaskPeriodic.h>
#include <cisstMultiTask/mtsTaskManager.h>
#include <cisstMultiTask/mtsInterfaceProvided.h>
#include <cisstMultiTask/mtsFixedSizeVectorTypes.h>
#if (CISST_OS == CISST_LINUX_XENOMAI)
#include <sys/mman.h>
#endif

using namespace SF;

class PeriodicTask: public mtsTaskPeriodic {
protected:
    //double SleepDuration;
    //mtsDouble SleepDuration;
    //mtsDouble2 SleepDuration;
    vctDoubleVec SleepDuration;

    mtsDouble       d0;
    mtsDouble1      d1;
    mtsDouble2      d2;
    mtsInt          i;
    mtsInt1         i1;
    mtsInt2         i2;
    mtsVctDoubleVec vd;
    mtsVctIntVec    vi;
    mtsVct3         v3;
    mtsVct3         v5;

public:
    PeriodicTask(const std::string & name, double period) :
        mtsTaskPeriodic(name, period, false, 5000)
    {
        //SleepDuration = 10.0;
        //SleepDuration(0) = 100.0;
        //SleepDuration(1) = 1000.0;
        SleepDuration.SetSize(5);

        StateTable.AddData(SleepDuration, "SleepDuration");
#if 0
        StateTable.AddData(d0, "SleepDuration");
        StateTable.AddData(d1, "SleepDuration");
        StateTable.AddData(d2, "SleepDuration");
        StateTable.AddData(i,  "SleepDuration");
        StateTable.AddData(i1, "SleepDuration");
        StateTable.AddData(i2, "SleepDuration");
        StateTable.AddData(vd, "SleepDuration");
        StateTable.AddData(vi, "SleepDuration");
        StateTable.AddData(v3, "SleepDuration");
        StateTable.AddData(v5, "SleepDuration");
#endif

        mtsInterfaceProvided * provided = AddInterfaceProvided("CustomInterface");
        if (provided) {
            provided->AddCommandReadState(StateTable, SleepDuration, "SleepDuration");
        }
    }

    ~PeriodicTask() {}

    void Configure(const std::string & CMN_UNUSED(filename) = "") {}
    void Startup(void) {}
    void Run(void) {
        ProcessQueuedCommands();
        ProcessQueuedEvents();
        //std::cout << "." << std::flush;
        /*
        static int count = 0;
        if (count++ % 10 == 0) {
            this->GenerateFaultEvent(std::string("MY FAULT EVENT"));
        }
        */
        static double T = (1.0 / this->Period) * 60.0 * 60.0;
        static int i = 0;

        //SleepDuration = this->Period * (0.8 * sin(2 * cmnPI * ((double) ++i / T)));
        //osaSleep(SleepDuration);

        //SleepDuration(0) += 0.1;
        //SleepDuration(1) += 0.1;
        //SleepDuration += 0.2;
        SleepDuration(0) += 0.1;
        SleepDuration(1) += 0.2;
        SleepDuration(2) += 0.3;
        SleepDuration(3) += 0.4;
        SleepDuration(4) += 0.5;
    }
    void Cleanup(void) {}
};

// Create periodic task
bool CreatePeriodicThread(const std::string & componentName, double period);
// to monitor values in real-time
bool InstallMonitor(const std::string & targetComponentName, unsigned int frequency);

// Local component manager
mtsManagerLocal * ComponentManager = 0;
// Test periodic task
PeriodicTask * task = 0;

int main(int argc, char *argv[])
{
#if SF_USE_G2LOG
    // Logger setup
    g2LogWorker logger(argv[0], "./");
    g2::initializeLogging(&logger);
    std::cout << "Log file: \"" << logger.logFileName() << "\"\n" << std::endl;
#endif

    cmnLogger::SetMask(CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskFunction(CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskDefaultLog(CMN_LOG_ALLOW_ALL);
    //cmnLogger::AddChannel(std::cout, CMN_LOG_ALLOW_ERRORS_AND_WARNINGS);
    cmnLogger::AddChannel(std::cout, CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskClassMatching("mtsSafetyCoordinator", CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskClassMatching("mtsMonitorComponent", CMN_LOG_ALLOW_ALL);

    // Get instance of the cisst Component Manager
    mtsComponentManager::InstallSafetyCoordinator();
    try {
        ComponentManager = mtsComponentManager::GetInstance();
    } catch (...) {
        SFLOG_ERROR << "Failed to initialize local component manager" << std::endl;
        return 1;
    }

    // Print information about middleware(s) available
    StrVecType info;
    GetMiddlewareInfo(info);
    std::cout << "Middleware(s) detected: ";
    if (info.size() == 0) {
        std::cout << "none" << std::endl;
    } else {
        std::cout << std::endl;
        for (size_t i = 0; i < info.size(); ++i) {
            std::cout << "[" << (i+1) << "] " << info[i] << std::endl;
        }
    }
    std::cout << std::endl;

    // Create five test components with different T
    std::vector<unsigned int> f; // Hz
#if 0
    f.push_back(1);
    f.push_back(2);
    f.push_back(5);
    f.push_back(10);
    f.push_back(20);
    f.push_back(50);
    f.push_back(100);
    f.push_back(200);
    f.push_back(500);
#endif
    f.push_back(1);

    std::string componentName;
    std::stringstream ss;
    for (size_t i = 0; i < f.size(); ++i) {
        ss.str("");
        ss << "Component" << f[i];
        componentName = ss.str();

        // Create periodic task
        if (!CreatePeriodicThread(componentName, 1.0 / (double)f[i])) {
            SFLOG_ERROR << "Failed to add periodic component \"" << componentName << "\"" << std::endl;
            return 1;
        }
        // Install monitor
        if (!InstallMonitor(componentName, f[i])) {
            SFLOG_ERROR << "Failed to install monitor for periodic component \"" << componentName << "\"" << std::endl;
            return 1;
        }
    }

    if (ComponentManager->GetCoordinator()) {
        if (!ComponentManager->GetCoordinator()->DeployMonitorsAndFDDs()) {
            SFLOG_ERROR << "Failed to deploy monitors and FDDs" << std::endl;
            return 1;
        }
    } else {
        SFLOG_ERROR  << "Failed to get coordinator in this process";
        return 1;
    }

    // Create and run all components
    ComponentManager->CreateAll();
    ComponentManager->WaitForStateAll(mtsComponentState::READY);

    ComponentManager->StartAll();
    ComponentManager->WaitForStateAll(mtsComponentState::ACTIVE);

    std::cout << "Press 'q' to quit or click CLOSE button of the visualizer." << std::endl;
    std::cout << "Running periodic tasks ";

    // loop until 'q' is pressed
    int key = ' ';
    while (key != 'q') {
        key = cmnGetChar();
        osaSleep(100 * cmn_ms);
    }
    std::cout << std::endl;

    // Clean up resources
    SFLOG_INFO << "Cleaning up..." << std::endl;

#if (CISST_OS != CISST_LINUX_XENOMAI)
    ComponentManager->KillAll();
    ComponentManager->WaitForStateAll(mtsComponentState::FINISHED, 2.0 * cmn_s);
#endif

    ComponentManager->Cleanup();

    return 0;
}

// Create periodic thread
bool CreatePeriodicThread(const std::string & componentName, double period)
{
    // Create periodic thread
    task = new PeriodicTask(componentName, period);
    if (!ComponentManager->AddComponent(task)) {
        SFLOG_ERROR << "Failed to add component \"" << componentName << "\"" << std::endl;
        return false;
    }

    return true;
}

bool InstallMonitor(const std::string & targetComponentName, unsigned int frequency)
{
    mtsSafetyCoordinator * coordinator = ComponentManager->GetCoordinator();
    if (!coordinator) {
        SFLOG_ERROR  << "Failed to get coordinator in this process";
        return false;
    }

    // Define target
#if 0
    cisstEventLocation * locationID = new cisstEventLocation;
    locationID->SetProcessName(ComponentManager->GetProcessName());
    locationID->SetComponentName(targetComponentName);

    cisstMonitor * monitor;

    // Install monitor for timing fault - period
    monitor = new cisstMonitor(Monitor::TARGET_THREAD_PERIOD,
                               locationID,
                               Monitor::STATE_ON,
                               Monitor::OUTPUT_STREAM,
                               frequency);
    // MJ TODO: Run system for a few minutes, collect experimental data,
    // and determine variance of period with upper/lower limits and thresholds.
    if (!coordinator->AddMonitorTarget(monitor)) {
        SFLOG_ERROR << "Failed to add new monitor target for component \"" << targetComponentName << "\"" << std::endl;
        SFLOG_ERROR << "JSON: " << monitor->GetMonitorJSON() << std::endl;
        return false;
    }
    SFLOG_INFO << "Successfully added monitor target: " << *monitor << std::endl;

    // Install monitor for execution time (user)
    monitor = new cisstMonitor(Monitor::TARGET_THREAD_DUTYCYCLE_USER,
                               locationID,
                               Monitor::STATE_ON,
                               Monitor::OUTPUT_STREAM,
                               frequency);

    if (!coordinator->AddMonitorTarget(monitor)) {
        SFLOG_ERROR << "Failed to add new monitor target for component \"" << targetComponentName << "\"" << std::endl;
        SFLOG_ERROR << "JSON: " << monitor->GetMonitorJSON() << std::endl;
        return false;
    }
    SFLOG_INFO << "Successfully added monitor target: " << *monitor << std::endl;

    // Install monitor for execution time (total)
    monitor = new cisstMonitor(Monitor::TARGET_THREAD_DUTYCYCLE_TOTAL,
                               locationID,
                               Monitor::STATE_ON,
                               Monitor::OUTPUT_STREAM,
                               frequency);

    if (!coordinator->AddMonitorTarget(monitor)) {
        SFLOG_ERROR << "Failed to add new monitor target for component \"" << targetComponentName << "\"" << std::endl;
        SFLOG_ERROR << "JSON: " << monitor->GetMonitorJSON() << std::endl;
        return false;
    }
    SFLOG_INFO << "Successfully added monitor target: " << *monitor << std::endl;
#else
    const std::string jsonFileName(SF_SOURCE_ROOT_DIR"/examples/monitor/monitor.json");
    if (!coordinator->AddMonitorTargetFromJSONFile(jsonFileName)) {
        SFLOG_ERROR << "Failed to load monitoring target file: \"" << jsonFileName << "\"" << std::endl;
        return false;
    }
#endif

    return true;
}
<commit_msg>updated copyright<commit_after>//------------------------------------------------------------------------
//
// CASROS: Component-based Architecture for Safe Robotic Systems
//
// Copyright (C) 2012-2014 Min Yang Jung and Peter Kazanzides
//
//------------------------------------------------------------------------
//
// Created on   : Aug 13, 2012
// Last revision: Apr 15, 2014
// Author       : Min Yang Jung (myj@jhu.edu)
// Github       : https://github.com/minyang/casros
//

#include "config.h"
#include "common.h"
#include "json.h"
#include "monitor.h"
#include "cisstMonitor.h"
#include "cisstEventLocation.h"

#include <cisstCommon/cmnGetChar.h>
#include <cisstOSAbstraction/osaSleep.h>
#include <cisstMultiTask/mtsCollectorState.h>
#include <cisstMultiTask/mtsTaskPeriodic.h>
#include <cisstMultiTask/mtsTaskManager.h>
#include <cisstMultiTask/mtsInterfaceProvided.h>
#include <cisstMultiTask/mtsFixedSizeVectorTypes.h>
#if (CISST_OS == CISST_LINUX_XENOMAI)
#include <sys/mman.h>
#endif

using namespace SF;

class PeriodicTask: public mtsTaskPeriodic {
protected:
    //double SleepDuration;
    //mtsDouble SleepDuration;
    //mtsDouble2 SleepDuration;
    vctDoubleVec SleepDuration;

    mtsDouble       d0;
    mtsDouble1      d1;
    mtsDouble2      d2;
    mtsInt          i;
    mtsInt1         i1;
    mtsInt2         i2;
    mtsVctDoubleVec vd;
    mtsVctIntVec    vi;
    mtsVct3         v3;
    mtsVct3         v5;

public:
    PeriodicTask(const std::string & name, double period) :
        mtsTaskPeriodic(name, period, false, 5000)
    {
        //SleepDuration = 10.0;
        //SleepDuration(0) = 100.0;
        //SleepDuration(1) = 1000.0;
        SleepDuration.SetSize(5);

        StateTable.AddData(SleepDuration, "SleepDuration");
#if 0
        StateTable.AddData(d0, "SleepDuration");
        StateTable.AddData(d1, "SleepDuration");
        StateTable.AddData(d2, "SleepDuration");
        StateTable.AddData(i,  "SleepDuration");
        StateTable.AddData(i1, "SleepDuration");
        StateTable.AddData(i2, "SleepDuration");
        StateTable.AddData(vd, "SleepDuration");
        StateTable.AddData(vi, "SleepDuration");
        StateTable.AddData(v3, "SleepDuration");
        StateTable.AddData(v5, "SleepDuration");
#endif

        mtsInterfaceProvided * provided = AddInterfaceProvided("CustomInterface");
        if (provided) {
            provided->AddCommandReadState(StateTable, SleepDuration, "SleepDuration");
        }
    }

    ~PeriodicTask() {}

    void Configure(const std::string & CMN_UNUSED(filename) = "") {}
    void Startup(void) {}
    void Run(void) {
        ProcessQueuedCommands();
        ProcessQueuedEvents();
        //std::cout << "." << std::flush;
        /*
        static int count = 0;
        if (count++ % 10 == 0) {
            this->GenerateFaultEvent(std::string("MY FAULT EVENT"));
        }
        */
        static double T = (1.0 / this->Period) * 60.0 * 60.0;
        static int i = 0;

        //SleepDuration = this->Period * (0.8 * sin(2 * cmnPI * ((double) ++i / T)));
        //osaSleep(SleepDuration);

        //SleepDuration(0) += 0.1;
        //SleepDuration(1) += 0.1;
        //SleepDuration += 0.2;
        SleepDuration(0) += 0.1;
        SleepDuration(1) += 0.2;
        SleepDuration(2) += 0.3;
        SleepDuration(3) += 0.4;
        SleepDuration(4) += 0.5;
    }
    void Cleanup(void) {}
};

// Create periodic task
bool CreatePeriodicThread(const std::string & componentName, double period);
// to monitor values in real-time
bool InstallMonitor(const std::string & targetComponentName, unsigned int frequency);

// Local component manager
mtsManagerLocal * ComponentManager = 0;
// Test periodic task
PeriodicTask * task = 0;

int main(int argc, char *argv[])
{
#if SF_USE_G2LOG
    // Logger setup
    g2LogWorker logger(argv[0], "./");
    g2::initializeLogging(&logger);
    std::cout << "Log file: \"" << logger.logFileName() << "\"\n" << std::endl;
#endif

    cmnLogger::SetMask(CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskFunction(CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskDefaultLog(CMN_LOG_ALLOW_ALL);
    //cmnLogger::AddChannel(std::cout, CMN_LOG_ALLOW_ERRORS_AND_WARNINGS);
    cmnLogger::AddChannel(std::cout, CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskClassMatching("mtsSafetyCoordinator", CMN_LOG_ALLOW_ALL);
    cmnLogger::SetMaskClassMatching("mtsMonitorComponent", CMN_LOG_ALLOW_ALL);

    // Get instance of the cisst Component Manager
    mtsComponentManager::InstallSafetyCoordinator();
    try {
        ComponentManager = mtsComponentManager::GetInstance();
    } catch (...) {
        SFLOG_ERROR << "Failed to initialize local component manager" << std::endl;
        return 1;
    }

    // Print information about middleware(s) available
    StrVecType info;
    GetMiddlewareInfo(info);
    std::cout << "Middleware(s) detected: ";
    if (info.size() == 0) {
        std::cout << "none" << std::endl;
    } else {
        std::cout << std::endl;
        for (size_t i = 0; i < info.size(); ++i) {
            std::cout << "[" << (i+1) << "] " << info[i] << std::endl;
        }
    }
    std::cout << std::endl;

    // Create five test components with different T
    std::vector<unsigned int> f; // Hz
#if 0
    f.push_back(1);
    f.push_back(2);
    f.push_back(5);
    f.push_back(10);
    f.push_back(20);
    f.push_back(50);
    f.push_back(100);
    f.push_back(200);
    f.push_back(500);
#endif
    f.push_back(1);

    std::string componentName;
    std::stringstream ss;
    for (size_t i = 0; i < f.size(); ++i) {
        ss.str("");
        ss << "Component" << f[i];
        componentName = ss.str();

        // Create periodic task
        if (!CreatePeriodicThread(componentName, 1.0 / (double)f[i])) {
            SFLOG_ERROR << "Failed to add periodic component \"" << componentName << "\"" << std::endl;
            return 1;
        }
        // Install monitor
        if (!InstallMonitor(componentName, f[i])) {
            SFLOG_ERROR << "Failed to install monitor for periodic component \"" << componentName << "\"" << std::endl;
            return 1;
        }
    }

    if (ComponentManager->GetCoordinator()) {
        if (!ComponentManager->GetCoordinator()->DeployMonitorsAndFDDs()) {
            SFLOG_ERROR << "Failed to deploy monitors and FDDs" << std::endl;
            return 1;
        }
    } else {
        SFLOG_ERROR  << "Failed to get coordinator in this process";
        return 1;
    }

    // Create and run all components
    ComponentManager->CreateAll();
    ComponentManager->WaitForStateAll(mtsComponentState::READY);

    ComponentManager->StartAll();
    ComponentManager->WaitForStateAll(mtsComponentState::ACTIVE);

    std::cout << "Press 'q' to quit or click CLOSE button of the visualizer." << std::endl;
    std::cout << "Running periodic tasks ";

    // loop until 'q' is pressed
    int key = ' ';
    while (key != 'q') {
        key = cmnGetChar();
        osaSleep(100 * cmn_ms);
    }
    std::cout << std::endl;

    // Clean up resources
    SFLOG_INFO << "Cleaning up..." << std::endl;

#if (CISST_OS != CISST_LINUX_XENOMAI)
    ComponentManager->KillAll();
    ComponentManager->WaitForStateAll(mtsComponentState::FINISHED, 2.0 * cmn_s);
#endif

    ComponentManager->Cleanup();

    return 0;
}

// Create periodic thread
bool CreatePeriodicThread(const std::string & componentName, double period)
{
    // Create periodic thread
    task = new PeriodicTask(componentName, period);
    if (!ComponentManager->AddComponent(task)) {
        SFLOG_ERROR << "Failed to add component \"" << componentName << "\"" << std::endl;
        return false;
    }

    return true;
}

bool InstallMonitor(const std::string & targetComponentName, unsigned int frequency)
{
    mtsSafetyCoordinator * coordinator = ComponentManager->GetCoordinator();
    if (!coordinator) {
        SFLOG_ERROR  << "Failed to get coordinator in this process";
        return false;
    }

    // Define target
#if 0
    cisstEventLocation * locationID = new cisstEventLocation;
    locationID->SetProcessName(ComponentManager->GetProcessName());
    locationID->SetComponentName(targetComponentName);

    cisstMonitor * monitor;

    // Install monitor for timing fault - period
    monitor = new cisstMonitor(Monitor::TARGET_THREAD_PERIOD,
                               locationID,
                               Monitor::STATE_ON,
                               Monitor::OUTPUT_STREAM,
                               frequency);
    // MJ TODO: Run system for a few minutes, collect experimental data,
    // and determine variance of period with upper/lower limits and thresholds.
    if (!coordinator->AddMonitorTarget(monitor)) {
        SFLOG_ERROR << "Failed to add new monitor target for component \"" << targetComponentName << "\"" << std::endl;
        SFLOG_ERROR << "JSON: " << monitor->GetMonitorJSON() << std::endl;
        return false;
    }
    SFLOG_INFO << "Successfully added monitor target: " << *monitor << std::endl;

    // Install monitor for execution time (user)
    monitor = new cisstMonitor(Monitor::TARGET_THREAD_DUTYCYCLE_USER,
                               locationID,
                               Monitor::STATE_ON,
                               Monitor::OUTPUT_STREAM,
                               frequency);

    if (!coordinator->AddMonitorTarget(monitor)) {
        SFLOG_ERROR << "Failed to add new monitor target for component \"" << targetComponentName << "\"" << std::endl;
        SFLOG_ERROR << "JSON: " << monitor->GetMonitorJSON() << std::endl;
        return false;
    }
    SFLOG_INFO << "Successfully added monitor target: " << *monitor << std::endl;

    // Install monitor for execution time (total)
    monitor = new cisstMonitor(Monitor::TARGET_THREAD_DUTYCYCLE_TOTAL,
                               locationID,
                               Monitor::STATE_ON,
                               Monitor::OUTPUT_STREAM,
                               frequency);

    if (!coordinator->AddMonitorTarget(monitor)) {
        SFLOG_ERROR << "Failed to add new monitor target for component \"" << targetComponentName << "\"" << std::endl;
        SFLOG_ERROR << "JSON: " << monitor->GetMonitorJSON() << std::endl;
        return false;
    }
    SFLOG_INFO << "Successfully added monitor target: " << *monitor << std::endl;
#else
    const std::string jsonFileName(SF_SOURCE_ROOT_DIR"/examples/monitor/monitor.json");
    if (!coordinator->AddMonitorTargetFromJSONFile(jsonFileName)) {
        SFLOG_ERROR << "Failed to load monitoring target file: \"" << jsonFileName << "\"" << std::endl;
        return false;
    }
#endif

    return true;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------
//
// CASROS: Component-based Architecture for Safe Robotic Systems
//
// Copyright (C) 2012-2014 Min Yang Jung and Peter Kazanzides
//
//------------------------------------------------------------------------
//
// Created on   : Apr 22, 2014
// Last revision: Apr 22, 2014
// Author       : Min Yang Jung (myj@jhu.edu)
// Github       : https://github.com/minyang/casros
//
#include "gcm.h"
#include "config.h"
#include <cisstMultiTask/mtsComponent.h>
#include <cisstMultiTask/mtsManagerLocal.h>

namespace SF {

using namespace SF;

GCM::GCM(void) : ComponentName(NONAME)
{
    // Default constructor should not be used
    SFASSERT(false);
}

GCM::GCM(const std::string & componentName)
    : ComponentName(componentName)
{
    States.ComponentFramework   = new StateMachine(componentName);
    States.ComponentApplication = new StateMachine(componentName);
}

GCM::~GCM(void)
{
    if (States.ComponentFramework)
        delete States.ComponentFramework;
    if (States.ComponentApplication)
        delete States.ComponentApplication;

    InterfaceStateMachinesType::iterator it;
    while (!States.RequiredInterfaces.empty()) {
        it = States.RequiredInterfaces.begin();
        States.RequiredInterfaces.erase(it);
        delete it->second;
    }
    while (!States.ProvidedInterfaces.empty()) {
        it = States.ProvidedInterfaces.begin();
        States.ProvidedInterfaces.erase(it);
        delete it->second;
    }
}

void GCM::ToStream(std::ostream & out) const
{
    out << "Owner: " << this->ComponentName
        << std::endl;
}

bool GCM::AddInterface(const std::string & name, const GCM::InterfaceTypes type)
{
    if (type == PROVIDED_INTERFACE) {
        if (States.ProvidedInterfaces.find(name) != States.ProvidedInterfaces.end())
            return false;
        States.ProvidedInterfaces.insert(std::make_pair(name, new StateMachine(name)));
    } else {
        if (States.RequiredInterfaces.find(name) != States.RequiredInterfaces.end())
            return false;
        States.RequiredInterfaces.insert(std::make_pair(name, new StateMachine(name)));
    }

    return true;
}

bool GCM::FindInterface(const std::string & name, const GCM::InterfaceTypes type) const
{
    if (type == PROVIDED_INTERFACE)
        return (States.ProvidedInterfaces.find(name) != States.ProvidedInterfaces.end());
    else
        return (States.RequiredInterfaces.find(name) != States.RequiredInterfaces.end());
}

bool GCM::RemoveInterface(const std::string & name, const GCM::InterfaceTypes type)
{
    InterfaceStateMachinesType::iterator it;
    if (type == PROVIDED_INTERFACE) {
        it = States.ProvidedInterfaces.find(name);
        if (it == States.ProvidedInterfaces.end())
            return false;
        SFASSERT(it->second);
        delete it->second;
        States.ProvidedInterfaces.erase(it);
    } else {
        it = States.RequiredInterfaces.find(name);
        if (it == States.RequiredInterfaces.end())
            return false;
        SFASSERT(it->second);
        delete it->second;
        States.RequiredInterfaces.erase(it);
    }

    return true;
}

void GCM::ProcessEvent_ComponentFramework(const SF::State::TransitionType transition)
{
    // TODO
}

void GCM::ProcessEvent_ComponentApplication(const SF::State::TransitionType transition)
{
    // TODO
}

void GCM::ProcessEvent_Interface(const SF::State::TransitionType transition)
{
    // TODO
}

};
<commit_msg>added debug log to GCM<commit_after>//------------------------------------------------------------------------
//
// CASROS: Component-based Architecture for Safe Robotic Systems
//
// Copyright (C) 2012-2014 Min Yang Jung and Peter Kazanzides
//
//------------------------------------------------------------------------
//
// Created on   : Apr 22, 2014
// Last revision: Apr 22, 2014
// Author       : Min Yang Jung (myj@jhu.edu)
// Github       : https://github.com/minyang/casros
//
#include "gcm.h"
#include "config.h"
#include <cisstMultiTask/mtsComponent.h>
#include <cisstMultiTask/mtsManagerLocal.h>

namespace SF {

using namespace SF;

GCM::GCM(void) : ComponentName(NONAME)
{
    // Default constructor should not be used
    SFASSERT(false);
}

GCM::GCM(const std::string & componentName)
    : ComponentName(componentName)
{
    States.ComponentFramework   = new StateMachine(componentName);
    States.ComponentApplication = new StateMachine(componentName);
}

GCM::~GCM(void)
{
    if (States.ComponentFramework)
        delete States.ComponentFramework;
    if (States.ComponentApplication)
        delete States.ComponentApplication;

    InterfaceStateMachinesType::iterator it;
    while (!States.RequiredInterfaces.empty()) {
        it = States.RequiredInterfaces.begin();
        States.RequiredInterfaces.erase(it);
        delete it->second;
    }
    while (!States.ProvidedInterfaces.empty()) {
        it = States.ProvidedInterfaces.begin();
        States.ProvidedInterfaces.erase(it);
        delete it->second;
    }
}

void GCM::ToStream(std::ostream & out) const
{
    out << "Owner component: " << this->ComponentName << std::endl;
    out << "Required interfaces: ";
    InterfaceStateMachinesType::const_iterator it = States.RequiredInterfaces.begin();
    for (; it != States.RequiredInterfaces.end(); ++it)
        out << "\"" << it->first << "\" ";
    out << std::endl;

    out << "Provided interfaces: ";
    it = States.ProvidedInterfaces.begin();
    for (; it != States.ProvidedInterfaces.end(); ++it)
        out << "\"" << it->first << "\" ";
    out << std::endl;
}

bool GCM::AddInterface(const std::string & name, const GCM::InterfaceTypes type)
{
    if (type == PROVIDED_INTERFACE) {
        if (States.ProvidedInterfaces.find(name) != States.ProvidedInterfaces.end()) {
#if ENABLE_UNIT_TEST
            std::cout << *this << std::endl;
#endif
            return false;
        }
        States.ProvidedInterfaces.insert(std::make_pair(name, new StateMachine(name)));
    } else {
        if (States.RequiredInterfaces.find(name) != States.RequiredInterfaces.end()) {
#if ENABLE_UNIT_TEST
            std::cout << *this << std::endl;
#endif
            return false;
        }
        States.RequiredInterfaces.insert(std::make_pair(name, new StateMachine(name)));
    }

    return true;
}

bool GCM::FindInterface(const std::string & name, const GCM::InterfaceTypes type) const
{
    if (type == PROVIDED_INTERFACE)
        return (States.ProvidedInterfaces.find(name) != States.ProvidedInterfaces.end());
    else
        return (States.RequiredInterfaces.find(name) != States.RequiredInterfaces.end());
}

bool GCM::RemoveInterface(const std::string & name, const GCM::InterfaceTypes type)
{
    InterfaceStateMachinesType::iterator it;
    if (type == PROVIDED_INTERFACE) {
        it = States.ProvidedInterfaces.find(name);
        if (it == States.ProvidedInterfaces.end())
            return false;
        SFASSERT(it->second);
        delete it->second;
        States.ProvidedInterfaces.erase(it);
    } else {
        it = States.RequiredInterfaces.find(name);
        if (it == States.RequiredInterfaces.end())
            return false;
        SFASSERT(it->second);
        delete it->second;
        States.RequiredInterfaces.erase(it);
    }

    return true;
}

void GCM::ProcessEvent_ComponentFramework(const SF::State::TransitionType transition)
{
    // TODO
}

void GCM::ProcessEvent_ComponentApplication(const SF::State::TransitionType transition)
{
    // TODO
}

void GCM::ProcessEvent_Interface(const SF::State::TransitionType transition)
{
    // TODO
}

};
<|endoftext|>


<commit_before>#include <cmath>
#include <iostream>
#include <ale_interface.hpp>
#include <glog/logging.h>
#include <gflags/gflags.h>
#include "prettyprint.hpp"
#include "dqn.hpp"

// DQN Parameters
DEFINE_bool(gpu, true, "Use GPU to brew Caffe");
DEFINE_bool(gui, false, "Open a GUI window");
DEFINE_string(rom, "roms/pong.bin", "Atari 2600 ROM to play");
DEFINE_int32(memory, 400000, "Capacity of replay memory");
DEFINE_int32(explore, 1000000, "Number of iterations needed for epsilon to reach given value.");
DEFINE_double(epsilon, 0.05, "Value of epsilon reached after explore iterations.");
DEFINE_double(gamma, 0.99, "Discount factor of future rewards (0,1]");
DEFINE_int32(clone_freq, 10000, "Frequency (steps) of cloning the target network.");
DEFINE_int32(memory_threshold, 100, "Enough amount of transitions to start learning");
DEFINE_int32(skip_frame, 3, "Number of frames skipped");
DEFINE_bool(show_frame, false, "Show the current frame in CUI");
DEFINE_string(save_screen, "", "File prefix in to save frames");
DEFINE_string(save_binary_screen, "", "File prefix in to save binary frames");
DEFINE_string(weights, "", "The pretrained weights load (*.caffemodel).");
DEFINE_string(snapshot, "", "The solver state to load (*.solverstate).");
DEFINE_bool(evaluate, false, "Evaluation mode: only playing a game, no updates");
DEFINE_double(evaluate_with_epsilon, 0.05, "Epsilon value to be used in evaluation mode");
DEFINE_double(repeat_games, 10, "Number of games played in evaluation mode");
// Solver Parameters
DEFINE_string(solver, "", "Solver parameter file (*.prototxt)");
DEFINE_string(solver_type, "ADADELTA", "Type of solver.");
DEFINE_string(model, "dqn.prototxt", "The model definition (*.prototxt).");
DEFINE_double(momentum, 0.95, "Solver momentum");
DEFINE_double(base_lr, 0.1, "Solver base learning rate");
DEFINE_string(lr_policy, "step", "Solver lr policy");
DEFINE_double(solver_gamma, 0.1, "Solver gamma");
DEFINE_int32(stepsize, 10000000, "Solver stepsize");
DEFINE_int32(max_iter, 10000000, "Maximum number of iterations");
DEFINE_int32(snapshot_frequency, 1000000, "Snapshot frequency in iterations");
DEFINE_int32(display, 10000, "Display frequency in iterations");
DEFINE_string(snapshot_prefix, "state/dqn", "Prefix for saving snapshots");

double CalculateEpsilon(const int iter) {
  if (iter < FLAGS_explore) {
    return 1.0 - (1.0 - FLAGS_epsilon) * (static_cast<double>(iter) / FLAGS_explore);
  } else {
    return FLAGS_epsilon;
  }
}

void SaveScreen(const ALEScreen& screen, const ALEInterface& ale,
                const string filename) {
  IntMatrix screen_matrix;
  for (auto row = 0; row < screen.height(); row++) {
    IntVect row_vec;
    for (auto col = 0; col < screen.width(); col++) {
      int pixel = screen.get(row, col);
      row_vec.emplace_back(pixel);
    }
    screen_matrix.emplace_back(row_vec);
  }
  ale.theOSystem->p_export_screen->save_png(&screen_matrix, filename);
}

void SaveInputFrames(const dqn::InputFrames& frames, const string filename) {
  std::ofstream ofs;
  ofs.open(filename, ios::out | ios::binary);
  for (int i = 0; i < dqn::kInputFrameCount; ++i) {
    const dqn::FrameData& frame = *frames[i];
    for (int j = 0; j < dqn::kCroppedFrameDataSize; ++j) {
      ofs.write((char*) &frame[j], sizeof(uint8_t));
    }
  }
  ofs.close();
}

/**
 * Play one episode and return the total score
 */
double PlayOneEpisode(ALEInterface& ale, dqn::DQN& dqn, const double epsilon,
                      const bool update) {
  CHECK(!ale.game_over());
  std::deque<dqn::FrameDataSp> past_frames;
  auto total_score = 0.0;
  for (auto frame = 0; !ale.game_over(); ++frame) {
    const ALEScreen& screen = ale.getScreen();
    if (!FLAGS_save_screen.empty()) {
      std::stringstream ss;
      ss << FLAGS_save_screen << setfill('0') << setw(5) <<
          std::to_string(frame) << ".png";
      SaveScreen(screen, ale, ss.str());
    }
    const auto current_frame = dqn::PreprocessScreen(screen);
    past_frames.push_back(current_frame);
    if (past_frames.size() < dqn::kInputFrameCount) {
      // If there are not past frames enough for DQN input, just select NOOP
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        total_score += ale.act(PLAYER_A_NOOP);
      }
    } else {
      while (past_frames.size() > dqn::kInputFrameCount) {
        past_frames.pop_front();
      }
      dqn::InputFrames input_frames;
      std::copy(past_frames.begin(), past_frames.end(), input_frames.begin());
      if (!FLAGS_save_binary_screen.empty()) {
        static int binary_save_num = 0;
        string fname = FLAGS_save_binary_screen +
            std::to_string(binary_save_num++) + ".bin";
        SaveInputFrames(input_frames, fname);
      }
      const auto action = dqn.SelectAction(input_frames, epsilon);
      auto immediate_score = 0.0;
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        immediate_score += ale.act(action);
      }
      total_score += immediate_score;
      // Rewards for DQN are normalized as follows:
      // 1 for any positive score, -1 for any negative score, otherwise 0
      const auto reward = immediate_score == 0 ? 0 : immediate_score /
          std::abs(immediate_score);
      assert(reward <= 1 && reward >= -1);
      if (update) {
        // Add the current transition to replay memory
        const auto transition = ale.game_over() ?
            dqn::Transition(input_frames, action, reward, boost::none) :
            dqn::Transition(input_frames, action, reward,
                            dqn::PreprocessScreen(ale.getScreen()));
        dqn.AddTransition(transition);
        // If the size of replay memory is large enough, update DQN
        if (dqn.memory_size() > FLAGS_memory_threshold) {
          dqn.Update();
        }
      }
    }
  }
  ale.reset_game();
  return total_score;
}

/**
 * Evaluate the current player
 */
void Evaluate(ALEInterface& ale, dqn::DQN& dqn) {
  auto total_score = 0.0;
  std::stringstream ss;
  for (auto i = 0; i < FLAGS_repeat_games; ++i) {
    const auto score =
        PlayOneEpisode(ale, dqn, FLAGS_evaluate_with_epsilon, false);
    ss << score << " ";
    total_score += score;
  }
  LOG(INFO) << "Evaluation scores: " << ss.str();
  LOG(INFO) << "Average score: " <<
      total_score / static_cast<double>(FLAGS_repeat_games) << std::endl;
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  google::LogToStderr();

  if (FLAGS_gpu) {
    caffe::Caffe::set_mode(caffe::Caffe::GPU);
  } else {
    caffe::Caffe::set_mode(caffe::Caffe::CPU);
  }

  ALEInterface ale;
  ale.set("display_screen", FLAGS_gui);
  ale.set("disable_color_averaging", true);

  // Load the ROM file
  ale.loadROM(FLAGS_rom);

  // Get the vector of legal actions
  const auto legal_actions = ale.getMinimalActionSet();

  CHECK(FLAGS_snapshot.empty() || FLAGS_weights.empty())
      << "Give a snapshot to resume training or weights to finetune "
      "but not both.";

  // Construct the solver either from file or params
  caffe::SolverParameter solver_param;
  if (!FLAGS_solver.empty()) {
    LOG(INFO) << "Reading solver prototxt from " << FLAGS_solver;
    caffe::ReadProtoFromTextFileOrDie(FLAGS_solver, &solver_param);
  } else {
    LOG(INFO) << "Creating solver from scratch.";
    solver_param.set_net(FLAGS_model);
    ::caffe::SolverParameter_SolverType solver_type;
    CHECK(::caffe::SolverParameter_SolverType_Parse(FLAGS_solver_type, &solver_type))
        << "Invalid Solver Type " << FLAGS_solver_type;
    solver_param.set_solver_type(solver_type);
    solver_param.set_momentum(FLAGS_momentum);
    solver_param.set_base_lr(FLAGS_base_lr);
    solver_param.set_lr_policy(FLAGS_lr_policy);
    solver_param.set_gamma(FLAGS_solver_gamma);
    solver_param.set_stepsize(FLAGS_stepsize);
    solver_param.set_max_iter(FLAGS_max_iter);
    solver_param.set_display(FLAGS_display);
    solver_param.set_snapshot(FLAGS_snapshot_frequency);
    solver_param.set_snapshot_prefix(FLAGS_snapshot_prefix);
  }

  dqn::DQN dqn(legal_actions, solver_param, FLAGS_memory, FLAGS_gamma,
               FLAGS_clone_freq);
  dqn.Initialize();

  if (!FLAGS_save_screen.empty()) {
    LOG(INFO) << "Saving screens to: " << FLAGS_save_screen;
  }

  if (!FLAGS_snapshot.empty()) {
    LOG(INFO) << "Resuming from " << FLAGS_snapshot;
    dqn.RestoreSolver(FLAGS_snapshot);
  } else if (!FLAGS_weights.empty()) {
    LOG(INFO) << "Finetuning from " << FLAGS_weights;
    dqn.LoadTrainedModel(FLAGS_weights);
  }

  if (FLAGS_evaluate) {
    Evaluate(ale, dqn);
    return 0;
  }

  auto episode = 0;
  while (dqn.current_iteration() < solver_param.max_iter()) {
    const auto epsilon = CalculateEpsilon(dqn.current_iteration());
    const auto score = PlayOneEpisode(ale, dqn, epsilon, true);
    LOG(INFO) << "Episode " << episode << ", score = " << score
              << ", epsilon = " << epsilon << ", iter = "
              << dqn.current_iteration();
    episode++;
  }
  Evaluate(ale, dqn);
};
<commit_msg>Updated arguments.<commit_after>#include <cmath>
#include <iostream>
#include <ale_interface.hpp>
#include <glog/logging.h>
#include <gflags/gflags.h>
#include "prettyprint.hpp"
#include "dqn.hpp"

// DQN Parameters
DEFINE_bool(gpu, true, "Use GPU to brew Caffe");
DEFINE_bool(gui, false, "Open a GUI window");
DEFINE_string(rom, "roms/pong.bin", "Atari 2600 ROM to play");
DEFINE_int32(memory, 400000, "Capacity of replay memory");
DEFINE_int32(explore, 1000000, "Iterations for epsilon to reach given value.");
DEFINE_double(epsilon, .05, "Value of epsilon after explore iterations.");
DEFINE_double(gamma, .99, "Discount factor of future rewards (0,1]");
DEFINE_int32(clone_freq, 10000, "Frequency (steps) of cloning the target network.");
DEFINE_int32(memory_threshold, 100, "Number of transitions to start learning");
DEFINE_int32(skip_frame, 3, "Number of frames skipped");
DEFINE_string(save_screen, "", "File prefix in to save frames");
DEFINE_string(save_binary_screen, "", "File prefix in to save binary frames");
DEFINE_string(weights, "", "The pretrained weights load (*.caffemodel).");
DEFINE_string(snapshot, "", "The solver state to load (*.solverstate).");
DEFINE_bool(evaluate, false, "Evaluation mode: only playing a game, no updates");
DEFINE_double(evaluate_with_epsilon, 0.05, "Epsilon value to be used in evaluation mode");
DEFINE_double(repeat_games, 10, "Number of games played in evaluation mode");
// Solver Parameters
DEFINE_string(solver, "", "Solver parameter file (*.prototxt)");
DEFINE_string(solver_type, "ADADELTA", "Type of solver.");
DEFINE_string(model, "dqn.prototxt", "The model definition (*.prototxt).");
DEFINE_double(momentum, 0.95, "Solver momentum");
DEFINE_double(base_lr, 0.1, "Solver base learning rate");
DEFINE_string(lr_policy, "step", "Solver lr policy");
DEFINE_double(solver_gamma, 0.1, "Solver gamma");
DEFINE_int32(stepsize, 10000000, "Solver stepsize");
DEFINE_int32(max_iter, 10000000, "Maximum number of iterations");
DEFINE_int32(snapshot_frequency, 1000000, "Snapshot frequency in iterations");
DEFINE_int32(display, 10000, "Display frequency in iterations");
DEFINE_string(snapshot_prefix, "state/dqn", "Prefix for saving snapshots");

double CalculateEpsilon(const int iter) {
  if (iter < FLAGS_explore) {
    return 1.0 - (1.0 - FLAGS_epsilon) * (static_cast<double>(iter) / FLAGS_explore);
  } else {
    return FLAGS_epsilon;
  }
}

void SaveScreen(const ALEScreen& screen, const ALEInterface& ale,
                const string filename) {
  IntMatrix screen_matrix;
  for (auto row = 0; row < screen.height(); row++) {
    IntVect row_vec;
    for (auto col = 0; col < screen.width(); col++) {
      int pixel = screen.get(row, col);
      row_vec.emplace_back(pixel);
    }
    screen_matrix.emplace_back(row_vec);
  }
  ale.theOSystem->p_export_screen->save_png(&screen_matrix, filename);
}

void SaveInputFrames(const dqn::InputFrames& frames, const string filename) {
  std::ofstream ofs;
  ofs.open(filename, ios::out | ios::binary);
  for (int i = 0; i < dqn::kInputFrameCount; ++i) {
    const dqn::FrameData& frame = *frames[i];
    for (int j = 0; j < dqn::kCroppedFrameDataSize; ++j) {
      ofs.write((char*) &frame[j], sizeof(uint8_t));
    }
  }
  ofs.close();
}

/**
 * Play one episode and return the total score
 */
double PlayOneEpisode(ALEInterface& ale, dqn::DQN& dqn, const double epsilon,
                      const bool update) {
  CHECK(!ale.game_over());
  std::deque<dqn::FrameDataSp> past_frames;
  auto total_score = 0.0;
  for (auto frame = 0; !ale.game_over(); ++frame) {
    const ALEScreen& screen = ale.getScreen();
    if (!FLAGS_save_screen.empty()) {
      std::stringstream ss;
      ss << FLAGS_save_screen << setfill('0') << setw(5) <<
          std::to_string(frame) << ".png";
      SaveScreen(screen, ale, ss.str());
    }
    const auto current_frame = dqn::PreprocessScreen(screen);
    past_frames.push_back(current_frame);
    if (past_frames.size() < dqn::kInputFrameCount) {
      // If there are not past frames enough for DQN input, just select NOOP
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        total_score += ale.act(PLAYER_A_NOOP);
      }
    } else {
      while (past_frames.size() > dqn::kInputFrameCount) {
        past_frames.pop_front();
      }
      dqn::InputFrames input_frames;
      std::copy(past_frames.begin(), past_frames.end(), input_frames.begin());
      if (!FLAGS_save_binary_screen.empty()) {
        static int binary_save_num = 0;
        string fname = FLAGS_save_binary_screen +
            std::to_string(binary_save_num++) + ".bin";
        SaveInputFrames(input_frames, fname);
      }
      const auto action = dqn.SelectAction(input_frames, epsilon);
      auto immediate_score = 0.0;
      for (auto i = 0; i < FLAGS_skip_frame + 1 && !ale.game_over(); ++i) {
        immediate_score += ale.act(action);
      }
      total_score += immediate_score;
      // Rewards for DQN are normalized as follows:
      // 1 for any positive score, -1 for any negative score, otherwise 0
      const auto reward = immediate_score == 0 ? 0 : immediate_score /
          std::abs(immediate_score);
      assert(reward <= 1 && reward >= -1);
      if (update) {
        // Add the current transition to replay memory
        const auto transition = ale.game_over() ?
            dqn::Transition(input_frames, action, reward, boost::none) :
            dqn::Transition(input_frames, action, reward,
                            dqn::PreprocessScreen(ale.getScreen()));
        dqn.AddTransition(transition);
        // If the size of replay memory is large enough, update DQN
        if (dqn.memory_size() > FLAGS_memory_threshold) {
          dqn.Update();
        }
      }
    }
  }
  ale.reset_game();
  return total_score;
}

/**
 * Evaluate the current player
 */
void Evaluate(ALEInterface& ale, dqn::DQN& dqn) {
  auto total_score = 0.0;
  std::stringstream ss;
  for (auto i = 0; i < FLAGS_repeat_games; ++i) {
    const auto score =
        PlayOneEpisode(ale, dqn, FLAGS_evaluate_with_epsilon, false);
    ss << score << " ";
    total_score += score;
  }
  LOG(INFO) << "Evaluation scores: " << ss.str();
  LOG(INFO) << "Average score: " <<
      total_score / static_cast<double>(FLAGS_repeat_games) << std::endl;
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  google::LogToStderr();

  if (FLAGS_gpu) {
    caffe::Caffe::set_mode(caffe::Caffe::GPU);
  } else {
    caffe::Caffe::set_mode(caffe::Caffe::CPU);
  }

  ALEInterface ale;
  ale.set("display_screen", FLAGS_gui);
  ale.set("disable_color_averaging", true);

  // Load the ROM file
  ale.loadROM(FLAGS_rom);

  // Get the vector of legal actions
  const auto legal_actions = ale.getMinimalActionSet();

  CHECK(FLAGS_snapshot.empty() || FLAGS_weights.empty())
      << "Give a snapshot to resume training or weights to finetune "
      "but not both.";

  // Construct the solver either from file or params
  caffe::SolverParameter solver_param;
  if (!FLAGS_solver.empty()) {
    LOG(INFO) << "Reading solver prototxt from " << FLAGS_solver;
    caffe::ReadProtoFromTextFileOrDie(FLAGS_solver, &solver_param);
  } else {
    LOG(INFO) << "Creating solver from scratch.";
    solver_param.set_net(FLAGS_model);
    ::caffe::SolverParameter_SolverType solver_type;
    CHECK(::caffe::SolverParameter_SolverType_Parse(FLAGS_solver_type, &solver_type))
        << "Invalid Solver Type " << FLAGS_solver_type;
    solver_param.set_solver_type(solver_type);
    solver_param.set_momentum(FLAGS_momentum);
    solver_param.set_base_lr(FLAGS_base_lr);
    solver_param.set_lr_policy(FLAGS_lr_policy);
    solver_param.set_gamma(FLAGS_solver_gamma);
    solver_param.set_stepsize(FLAGS_stepsize);
    solver_param.set_max_iter(FLAGS_max_iter);
    solver_param.set_display(FLAGS_display);
    solver_param.set_snapshot(FLAGS_snapshot_frequency);
    solver_param.set_snapshot_prefix(FLAGS_snapshot_prefix);
  }

  dqn::DQN dqn(legal_actions, solver_param, FLAGS_memory, FLAGS_gamma,
               FLAGS_clone_freq);
  dqn.Initialize();

  if (!FLAGS_save_screen.empty()) {
    LOG(INFO) << "Saving screens to: " << FLAGS_save_screen;
  }

  if (!FLAGS_snapshot.empty()) {
    LOG(INFO) << "Resuming from " << FLAGS_snapshot;
    dqn.RestoreSolver(FLAGS_snapshot);
  } else if (!FLAGS_weights.empty()) {
    LOG(INFO) << "Finetuning from " << FLAGS_weights;
    dqn.LoadTrainedModel(FLAGS_weights);
  }

  if (FLAGS_evaluate) {
    Evaluate(ale, dqn);
    return 0;
  }

  auto episode = 0;
  while (dqn.current_iteration() < solver_param.max_iter()) {
    const auto epsilon = CalculateEpsilon(dqn.current_iteration());
    const auto score = PlayOneEpisode(ale, dqn, epsilon, true);
    LOG(INFO) << "Episode " << episode << ", score = " << score
              << ", epsilon = " << epsilon << ", iter = "
              << dqn.current_iteration();
    episode++;
  }
  Evaluate(ale, dqn);
};
<|endoftext|>


<commit_before>//
//
// Copyright (C) 2004 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004 Pingtel Corp.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
//////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include "net/Url.h"
#include "mailboxmgr/VXMLDefs.h"
#include "mailboxmgr/MailboxManager.h"
#include "mailboxmgr/TransferToExtnCGI.h"
#include "mailboxmgr/ValidateMailboxCGIHelper.h"

// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS

/* ============================ CREATORS ================================== */

TransferToExtnCGI::TransferToExtnCGI( const UtlString& extension ) :
    m_extension ( extension )
{}

TransferToExtnCGI::~TransferToExtnCGI()
{}

OsStatus
TransferToExtnCGI::execute(UtlString* out)
{
    OsStatus result = OS_SUCCESS;

        // Get fully qualified SIP URL for the extension
    Url extensionUrl;
        MailboxManager* pMailboxManager = MailboxManager::getInstance();
        pMailboxManager->getWellFormedURL( m_extension, extensionUrl );

        // Validate the mailbox id and extension.
        // If valid, lazy create the physical folders for the mailbox if necessary.
    UtlBoolean checkPermissions = FALSE ;
    ValidateMailboxCGIHelper validateMailboxHelper ( extensionUrl.toString() );
    result = validateMailboxHelper.validate( checkPermissions );
    UtlString dynamicVxml;
        if ( result == OS_SUCCESS )
    {
/*
        UtlString transferUrlString;
        validateMailboxHelper.getMailboxIdentity( transferUrlString );
        if (transferUrlString.index("sip:") == UTL_NOT_FOUND)
        {
            transferUrlString = "sip:" + transferUrlString;
        }
*/
        UtlString ivrPromptUrl;
        MailboxManager::getInstance()->getIvrPromptURL( ivrPromptUrl );

        // Contains the dynamically generated VXML script.
            dynamicVxml =   VXML_BODY_BEGIN \
                        "<form> \n" \
                            "<block> \n" \
                                "<prompt bargein=\"false\"> \n" \
                                "<audio src=\"" + ivrPromptUrl + "/" + UtlString (PROMPT_ALIAS) + "/please_hold.wav\" /> \n" \
                                "</prompt>\n" \
                            "</block> \n" \
                            "<transfer dest=\"" + extensionUrl.toString() /* transferUrlString */ + "\" /> \n" \
                        "</form> \n" \
                        VXML_END;
            // Write out the dynamic VXML script to be processed by OpenVXI
    } else
    {
            dynamicVxml =   VXML_BODY_BEGIN \
                        VXML_INVALID_EXTN_SNIPPET\
                            VXML_END;
    }

        if (out)
        {
        out->remove(0);
        UtlString responseHeaders;
        MailboxManager::getResponseHeaders(dynamicVxml.length(), responseHeaders);

        out->append(responseHeaders.data());
        out->append(dynamicVxml.data());
        }

    return OS_SUCCESS;
}
<commit_msg>Removed playing "please hold" message so to prevent the message being played twice.<commit_after>//
//
// Copyright (C) 2004 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004 Pingtel Corp.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
//////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include "net/Url.h"
#include "mailboxmgr/VXMLDefs.h"
#include "mailboxmgr/MailboxManager.h"
#include "mailboxmgr/TransferToExtnCGI.h"
#include "mailboxmgr/ValidateMailboxCGIHelper.h"

// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS

/* ============================ CREATORS ================================== */

TransferToExtnCGI::TransferToExtnCGI( const UtlString& extension ) :
    m_extension ( extension )
{}

TransferToExtnCGI::~TransferToExtnCGI()
{}

OsStatus
TransferToExtnCGI::execute(UtlString* out)
{
    OsStatus result = OS_SUCCESS;

        // Get fully qualified SIP URL for the extension
    Url extensionUrl;
        MailboxManager* pMailboxManager = MailboxManager::getInstance();
        pMailboxManager->getWellFormedURL( m_extension, extensionUrl );

        // Validate the mailbox id and extension.
        // If valid, lazy create the physical folders for the mailbox if necessary.
    UtlBoolean checkPermissions = FALSE ;
    ValidateMailboxCGIHelper validateMailboxHelper ( extensionUrl.toString() );
    result = validateMailboxHelper.validate( checkPermissions );
    UtlString dynamicVxml;
        if ( result == OS_SUCCESS )
    {
/*
        UtlString transferUrlString;
        validateMailboxHelper.getMailboxIdentity( transferUrlString );
        if (transferUrlString.index("sip:") == UTL_NOT_FOUND)
        {
            transferUrlString = "sip:" + transferUrlString;
        }
*/
        UtlString ivrPromptUrl;
        MailboxManager::getInstance()->getIvrPromptURL( ivrPromptUrl );

        // Contains the dynamically generated VXML script.
            dynamicVxml =   VXML_BODY_BEGIN \
                        "<form> \n" \
                            "<transfer dest=\"" + extensionUrl.toString() /* transferUrlString */ + "\" /> \n" \
                        "</form> \n" \
                        VXML_END;
            // Write out the dynamic VXML script to be processed by OpenVXI
    } else
    {
            dynamicVxml =   VXML_BODY_BEGIN \
                        VXML_INVALID_EXTN_SNIPPET\
                            VXML_END;
    }

        if (out)
        {
        out->remove(0);
        UtlString responseHeaders;
        MailboxManager::getResponseHeaders(dynamicVxml.length(), responseHeaders);

        out->append(responseHeaders.data());
        out->append(dynamicVxml.data());
        }

    return OS_SUCCESS;
}
<|endoftext|>


<commit_before>#pragma once

#include <glm/vec3.hpp>
#include <memory>
#include "../linking.hpp"

class btCollisionShape;
class PhysicsManager;

namespace Physics {
    class Trigger;

    /// Represents a shape for physics objects and facilitates creation of
    /// underlying types.
    class Shape {
        friend class ::PhysicsManager;
        friend class Trigger;

        public:
            /// Parameters used to create a sphere shape.
            struct Sphere {
                explicit Sphere(float radius) : radius(radius) {}
                float radius;
            };

            /// Parameters used to create a plane shape.
            struct Plane {
                Plane(const glm::vec3& normal, float planeCoeff)
                    : normal(normal), planeCoeff(planeCoeff) {}
                glm::vec3 normal;
                float planeCoeff;
            };

            /// Parameters used to create a box shape.
            struct Box {
                Box(float width, float height, float depth)
                    : width(width), height(height), depth(depth) {}
                float width;
                float height;
                float depth;
            };

            /// Parameters used to create a cylinder shape.
            struct Cylinder {
                Cylinder(float radius, float length)
                    : radius(radius), length(length) {}
                float radius;
                float length;
            };

            /// Parameters used to create a cone shape.
            struct Cone {
                Cone(float radius, float height)
                    : radius(radius), height(height) {}
                float radius;
                float height;
            };

            /// Parameters used to create a capsule shape.
            struct Capsule {
                Capsule(float radius, float height)
                    : radius(radius), height(height) {}
                float radius;
                float height;
            };

            /// The various kinds of shapes that are wrapped by %Shape.
            enum class Kind {
                Sphere,
                Plane,
                Box,
                Cylinder,
                Cone,
                Capsule,
            };

            /// Construct a sphere shape.
            /**
             * @param params Sphere specific parameters.
             */
            ENGINE_API explicit Shape(const Sphere& params);

            /// Construct a plane shape.
            /**
             * @param params Plane specific parameters.
             */
            ENGINE_API explicit Shape(const Plane& params);

            /// Construct a box shape.
            /**
             * @param params Box specific parameters.
             */
            ENGINE_API explicit Shape(const Box& params);

            /// Construct a cylinder shape.
            /**
             * @param params Cylinder specific parameters.
             */
            ENGINE_API explicit Shape(const Cylinder& params);

            /// Construct a cone shape.
            /**
             * @param params Cone specific parameters.
             */
            ENGINE_API explicit Shape(const Cone& params);

            /// Construct a capsule shape.
            /**
             * @param params Capsule specific parameters.
             */
            ENGINE_API explicit Shape(const Capsule& params);

            /// Destructor
            ENGINE_API ~Shape();

            /// Get the type of wrapped shape.
            /**
             * @return The type of shape.
             */
            ENGINE_API Kind GetKind() const;

            /// Get sphere data of the shape.
            /**
             * @return Sphere data, or nullptr if the shape is not a sphere.
             */
            ENGINE_API const Sphere* GetSphereData() const;

            /// Get plane data of the shape.
            /**
             * @return Plane data, or nullptr if the shape is not a plane.
             */
            ENGINE_API const Plane* GetPlaneData() const;

            /// Get box data of the shape.
            /**
             * @return Box data, or nullptr if the shape is not a box.
             */
            ENGINE_API const Box* GetBoxData() const;

            /// Get cylinder data of the shape.
            /**
             * @return Cylinder data, or nullptr if the shape is not a cylinder.
             */
            ENGINE_API const Cylinder* GetCylinderData() const;

            /// Get cone data of the shape.
            /**
             * @return Cone data, or nullptr if the shape is not a cone.
             */
            ENGINE_API const Cone* GetConeData() const;

            /// Get capsule data of the shape.
            /**
             * @return Capsule data, or nullptr if the shape is not a capsule.
             */
            ENGINE_API const Capsule* GetCapsuleData() const;

        private:
            /// Get the wrapped Bullet shape.
            /**
             * @return The Bullet shape.
             */
            btCollisionShape* GetShape() const;

            Shape(const Shape& other) = delete;

            std::unique_ptr<btCollisionShape> shape;
            Kind kind;
            union {
                Sphere sphere;
                Plane plane;
                Box box;
                Cylinder cylinder;
                Cone cone;
                Capsule capsule;
            };
    };
}
<commit_msg>Allow the rigid body component access to private members of the shape helper class.<commit_after>#pragma once

#include <glm/vec3.hpp>
#include <memory>
#include "../linking.hpp"

class btCollisionShape;
class PhysicsManager;

namespace Component {
    class RigidBody;
}

namespace Physics {
    class Trigger;

    /// Represents a shape for physics objects and facilitates creation of
    /// underlying types.
    class Shape {
        friend class ::PhysicsManager;
        friend class ::Component::RigidBody;
        friend class Trigger;

        public:
            /// Parameters used to create a sphere shape.
            struct Sphere {
                explicit Sphere(float radius) : radius(radius) {}
                float radius;
            };

            /// Parameters used to create a plane shape.
            struct Plane {
                Plane(const glm::vec3& normal, float planeCoeff)
                    : normal(normal), planeCoeff(planeCoeff) {}
                glm::vec3 normal;
                float planeCoeff;
            };

            /// Parameters used to create a box shape.
            struct Box {
                Box(float width, float height, float depth)
                    : width(width), height(height), depth(depth) {}
                float width;
                float height;
                float depth;
            };

            /// Parameters used to create a cylinder shape.
            struct Cylinder {
                Cylinder(float radius, float length)
                    : radius(radius), length(length) {}
                float radius;
                float length;
            };

            /// Parameters used to create a cone shape.
            struct Cone {
                Cone(float radius, float height)
                    : radius(radius), height(height) {}
                float radius;
                float height;
            };

            /// Parameters used to create a capsule shape.
            struct Capsule {
                Capsule(float radius, float height)
                    : radius(radius), height(height) {}
                float radius;
                float height;
            };

            /// The various kinds of shapes that are wrapped by %Shape.
            enum class Kind {
                Sphere,
                Plane,
                Box,
                Cylinder,
                Cone,
                Capsule,
            };

            /// Construct a sphere shape.
            /**
             * @param params Sphere specific parameters.
             */
            ENGINE_API explicit Shape(const Sphere& params);

            /// Construct a plane shape.
            /**
             * @param params Plane specific parameters.
             */
            ENGINE_API explicit Shape(const Plane& params);

            /// Construct a box shape.
            /**
             * @param params Box specific parameters.
             */
            ENGINE_API explicit Shape(const Box& params);

            /// Construct a cylinder shape.
            /**
             * @param params Cylinder specific parameters.
             */
            ENGINE_API explicit Shape(const Cylinder& params);

            /// Construct a cone shape.
            /**
             * @param params Cone specific parameters.
             */
            ENGINE_API explicit Shape(const Cone& params);

            /// Construct a capsule shape.
            /**
             * @param params Capsule specific parameters.
             */
            ENGINE_API explicit Shape(const Capsule& params);

            /// Destructor
            ENGINE_API ~Shape();

            /// Get the type of wrapped shape.
            /**
             * @return The type of shape.
             */
            ENGINE_API Kind GetKind() const;

            /// Get sphere data of the shape.
            /**
             * @return Sphere data, or nullptr if the shape is not a sphere.
             */
            ENGINE_API const Sphere* GetSphereData() const;

            /// Get plane data of the shape.
            /**
             * @return Plane data, or nullptr if the shape is not a plane.
             */
            ENGINE_API const Plane* GetPlaneData() const;

            /// Get box data of the shape.
            /**
             * @return Box data, or nullptr if the shape is not a box.
             */
            ENGINE_API const Box* GetBoxData() const;

            /// Get cylinder data of the shape.
            /**
             * @return Cylinder data, or nullptr if the shape is not a cylinder.
             */
            ENGINE_API const Cylinder* GetCylinderData() const;

            /// Get cone data of the shape.
            /**
             * @return Cone data, or nullptr if the shape is not a cone.
             */
            ENGINE_API const Cone* GetConeData() const;

            /// Get capsule data of the shape.
            /**
             * @return Capsule data, or nullptr if the shape is not a capsule.
             */
            ENGINE_API const Capsule* GetCapsuleData() const;

        private:
            /// Get the wrapped Bullet shape.
            /**
             * @return The Bullet shape.
             */
            btCollisionShape* GetShape() const;

            Shape(const Shape& other) = delete;

            std::unique_ptr<btCollisionShape> shape;
            Kind kind;
            union {
                Sphere sphere;
                Plane plane;
                Box box;
                Cylinder cylinder;
                Cone cone;
                Capsule capsule;
            };
    };
}
<|endoftext|>


<commit_before>/**
    @file ConnectionSTREAMImages.cpp
    @author Lime Microsystems
    @brief Image updating and version checking
*/

#include "ConnectionSTREAM.h"
#include "ErrorReporting.h"
#include "SystemResources.h"
#include "LMS64CProtocol.h"
#include "LMSBoards.h"
#include <iostream>
#include <fstream>
#include <ciso646>

using namespace lime;

/*!
 * The entry structure that describes a board revision and its fw/gw images
 */
struct ConnectionSTREAMImageEntry
{
    eLMS_DEV dev;
    int hw_rev;

    int fw_ver;
    const char *fw_img;

    int gw_ver;
    int gw_rev;
    const char *gw_rbf;
};

/*!
 * Lookup the board information given hardware type and revision.
 * Edit each entry for supported hardware and image updates.
 */
static const ConnectionSTREAMImageEntry &lookupImageEntry(const LMS64CProtocol::LMSinfo &info)
{
    static const std::vector<ConnectionSTREAMImageEntry> imageEntries = {
        ConnectionSTREAMImageEntry({LMS_DEV_UNKNOWN, -1, -1, "Unknown-USB.img", -1, -1, "Unknown-USB.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 4, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 2, 2,  "LimeSDR-USB_HW_1.4_r2.2.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 3, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 2, 3, "LimeSDR-USB_HW_1.2_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 1, 7, "LimeSDR-USB_HW_1.1_r7.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_STREAM,  3, 8, "STREAM-USB_HW_1.1_r8.0.img",  1, 2,  "STREAM-USB_HW_1.3_r1.2.rbf"})};

    for(const auto &iter : imageEntries)
    {
        if (info.device == iter.dev and info.hardware == iter.hw_rev)
        {
            return iter;
        }
    }

    return imageEntries.front(); //the -1 unknown entry
}

void ConnectionSTREAM::VersionCheck(void)
{
    const auto info = this->GetInfo();
    const auto &entry = lookupImageEntry(info);

    //an entry match was not found
    if (entry.dev == LMS_DEV_UNKNOWN)
    {
        std::cerr << "Unsupported hardware connected: " << GetDeviceName(info.device) << "[HW=" << info.hardware << "]" << std::endl;
        return;
    }

    //check and warn about firmware mismatch problems
    if (info.firmware != entry.fw_ver)
        std::cerr << std::endl
        << "########################################################" << std::endl
        << "##   !!!  Warning: firmware version mismatch  !!!" << std::endl
        << "## Expected firmware version " << entry.fw_ver << ", but found version " << info.firmware << std::endl
        << "## Follow the FW and FPGA upgrade instructions:" << std::endl
        << "## http://wiki.myriadrf.org/Lime_Suite#Flashing_images" << std::endl
        << "## Or run update on the command line: LimeUtil --update" << std::endl
        << "########################################################" << std::endl
        << std::endl;

    //check and warn about gateware mismatch problems
    const auto fpgaInfo = this->GetFPGAInfo();
    if (fpgaInfo.gatewareVersion != entry.gw_ver
        || fpgaInfo.gatewareRevision != entry.gw_rev)
        std::cerr << std::endl
        << "########################################################" << std::endl
        << "##   !!!  Warning: gateware version mismatch  !!!" << std::endl
        << "## Expected gateware version " << entry.gw_ver << ", revision " << entry.gw_rev << std::endl
        << "## But found version " << fpgaInfo.gatewareVersion << ", revision " << fpgaInfo.gatewareRevision<< std::endl
        << "## Follow the FW and FPGA upgrade instructions:" << std::endl
        << "## http://wiki.myriadrf.org/Lime_Suite#Flashing_images" << std::endl
        << "## Or run update on the command line: LimeUtil --update" << std::endl
        << "########################################################" << std::endl
        << std::endl;
}

int ConnectionSTREAM::ProgramUpdate(const bool download, IConnection::ProgrammingCallback callback)
{
    const auto info = this->GetInfo();
    const auto &entry = lookupImageEntry(info);

    //an entry match was not found
    if (entry.dev == LMS_DEV_UNKNOWN)
    {
        return lime::ReportError("Unsupported hardware connected: %s[HW=%d]", GetDeviceName(info.device), info.hardware);
    }

    //download images when missing
    if (download)
    {
        const std::vector<std::string> images = {entry.fw_img, entry.gw_rbf};
        for (const auto &image : images)
        {
            if (not lime::locateImageResource(image).empty()) continue;
            const std::string msg("Downloading: " + image);
            if (callback) callback(0, 1, msg.c_str());
            int ret = lime::downloadImageResource(image);
            if (ret != 0) return ret; //error set by download call
            if (callback) callback(1, 1, "Done!");
        }
    }

    //load firmware into flash
    {
        //open file
        std::ifstream file;
        const auto path = lime::locateImageResource(entry.fw_img);
        file.open(path.c_str(), std::ios::in | std::ios::binary);
        if (not file.good()) return lime::ReportError("Error opening %s", path.c_str());

        //read file
        std::streampos fileSize;
        file.seekg(0, std::ios::end);
        fileSize = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector<char> progData(fileSize, 0);
        file.read(progData.data(), fileSize);

        int device = LMS64CProtocol::FX3; //FX3
        int progMode = 2; //Firmware to FLASH
        auto status = this->ProgramWrite(progData.data(), progData.size(), progMode, device, callback);
        if (status != 0) return status;
    }

    //load gateware into flash
    {
        //open file
        std::ifstream file;
        const auto path = lime::locateImageResource(entry.gw_rbf);
        file.open(path.c_str(), std::ios::in | std::ios::binary);
        if (not file.good()) return lime::ReportError("Error opening %s", path.c_str());

        //read file
        std::streampos fileSize;
        file.seekg(0, std::ios::end);
        fileSize = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector<char> progData(fileSize, 0);
        file.read(progData.data(), fileSize);

        int device = LMS64CProtocol::FPGA; //Altera FPGA
        int progMode = 1; //Bitstream to FLASH
        auto status = this->ProgramWrite(progData.data(), progData.size(), progMode, device, callback);
        if (status != 0) return status;
    }

    //Reset FX3, FPGA should be reloaded on boot
    {
        int device = LMS64CProtocol::FX3; //FX3
        auto status = this->ProgramWrite(nullptr, 0, 0, device, nullptr);
        if (status != 0) return status;
    }

    return 0;
}
<commit_msg>print image path in program update<commit_after>/**
    @file ConnectionSTREAMImages.cpp
    @author Lime Microsystems
    @brief Image updating and version checking
*/

#include "ConnectionSTREAM.h"
#include "ErrorReporting.h"
#include "SystemResources.h"
#include "LMS64CProtocol.h"
#include "LMSBoards.h"
#include <iostream>
#include <fstream>
#include <ciso646>

using namespace lime;

/*!
 * The entry structure that describes a board revision and its fw/gw images
 */
struct ConnectionSTREAMImageEntry
{
    eLMS_DEV dev;
    int hw_rev;

    int fw_ver;
    const char *fw_img;

    int gw_ver;
    int gw_rev;
    const char *gw_rbf;
};

/*!
 * Lookup the board information given hardware type and revision.
 * Edit each entry for supported hardware and image updates.
 */
static const ConnectionSTREAMImageEntry &lookupImageEntry(const LMS64CProtocol::LMSinfo &info)
{
    static const std::vector<ConnectionSTREAMImageEntry> imageEntries = {
        ConnectionSTREAMImageEntry({LMS_DEV_UNKNOWN, -1, -1, "Unknown-USB.img", -1, -1, "Unknown-USB.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 4, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 2, 2,  "LimeSDR-USB_HW_1.4_r2.2.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 3, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 2, 3, "LimeSDR-USB_HW_1.2_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 1, 7, "LimeSDR-USB_HW_1.1_r7.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
        ConnectionSTREAMImageEntry({LMS_DEV_STREAM,  3, 8, "STREAM-USB_HW_1.1_r8.0.img",  1, 2,  "STREAM-USB_HW_1.3_r1.2.rbf"})};

    for(const auto &iter : imageEntries)
    {
        if (info.device == iter.dev and info.hardware == iter.hw_rev)
        {
            return iter;
        }
    }

    return imageEntries.front(); //the -1 unknown entry
}

void ConnectionSTREAM::VersionCheck(void)
{
    const auto info = this->GetInfo();
    const auto &entry = lookupImageEntry(info);

    //an entry match was not found
    if (entry.dev == LMS_DEV_UNKNOWN)
    {
        std::cerr << "Unsupported hardware connected: " << GetDeviceName(info.device) << "[HW=" << info.hardware << "]" << std::endl;
        return;
    }

    //check and warn about firmware mismatch problems
    if (info.firmware != entry.fw_ver)
        std::cerr << std::endl
        << "########################################################" << std::endl
        << "##   !!!  Warning: firmware version mismatch  !!!" << std::endl
        << "## Expected firmware version " << entry.fw_ver << ", but found version " << info.firmware << std::endl
        << "## Follow the FW and FPGA upgrade instructions:" << std::endl
        << "## http://wiki.myriadrf.org/Lime_Suite#Flashing_images" << std::endl
        << "## Or run update on the command line: LimeUtil --update" << std::endl
        << "########################################################" << std::endl
        << std::endl;

    //check and warn about gateware mismatch problems
    const auto fpgaInfo = this->GetFPGAInfo();
    if (fpgaInfo.gatewareVersion != entry.gw_ver
        || fpgaInfo.gatewareRevision != entry.gw_rev)
        std::cerr << std::endl
        << "########################################################" << std::endl
        << "##   !!!  Warning: gateware version mismatch  !!!" << std::endl
        << "## Expected gateware version " << entry.gw_ver << ", revision " << entry.gw_rev << std::endl
        << "## But found version " << fpgaInfo.gatewareVersion << ", revision " << fpgaInfo.gatewareRevision<< std::endl
        << "## Follow the FW and FPGA upgrade instructions:" << std::endl
        << "## http://wiki.myriadrf.org/Lime_Suite#Flashing_images" << std::endl
        << "## Or run update on the command line: LimeUtil --update" << std::endl
        << "########################################################" << std::endl
        << std::endl;
}

static bool programmingCallbackStream(
    int bsent, int btotal, const char* progressMsg,
    const std::string &image,
    IConnection::ProgrammingCallback callback)
{
    const auto msg = std::string(progressMsg) + " (" + image + ")";
    return callback(bsent, btotal, msg.c_str());
}

int ConnectionSTREAM::ProgramUpdate(const bool download, IConnection::ProgrammingCallback callback)
{
    const auto info = this->GetInfo();
    const auto &entry = lookupImageEntry(info);

    //an entry match was not found
    if (entry.dev == LMS_DEV_UNKNOWN)
    {
        return lime::ReportError("Unsupported hardware connected: %s[HW=%d]", GetDeviceName(info.device), info.hardware);
    }

    //download images when missing
    if (download)
    {
        const std::vector<std::string> images = {entry.fw_img, entry.gw_rbf};
        for (const auto &image : images)
        {
            if (not lime::locateImageResource(image).empty()) continue;
            const std::string msg("Downloading: " + image);
            if (callback) callback(0, 1, msg.c_str());
            int ret = lime::downloadImageResource(image);
            if (ret != 0) return ret; //error set by download call
            if (callback) callback(1, 1, "Done!");
        }
    }

    //load firmware into flash
    {
        //open file
        std::ifstream file;
        const auto path = lime::locateImageResource(entry.fw_img);
        file.open(path.c_str(), std::ios::in | std::ios::binary);
        if (not file.good()) return lime::ReportError("Error opening %s", path.c_str());

        //read file
        std::streampos fileSize;
        file.seekg(0, std::ios::end);
        fileSize = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector<char> progData(fileSize, 0);
        file.read(progData.data(), fileSize);

        int device = LMS64CProtocol::FX3; //FX3
        int progMode = 2; //Firmware to FLASH
        using namespace std::placeholders;
        const auto cb = std::bind(&programmingCallbackStream, _1, _2, _3, path, callback);
        auto status = this->ProgramWrite(progData.data(), progData.size(), progMode, device, cb);
        if (status != 0) return status;
    }

    //load gateware into flash
    {
        //open file
        std::ifstream file;
        const auto path = lime::locateImageResource(entry.gw_rbf);
        file.open(path.c_str(), std::ios::in | std::ios::binary);
        if (not file.good()) return lime::ReportError("Error opening %s", path.c_str());

        //read file
        std::streampos fileSize;
        file.seekg(0, std::ios::end);
        fileSize = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector<char> progData(fileSize, 0);
        file.read(progData.data(), fileSize);

        int device = LMS64CProtocol::FPGA; //Altera FPGA
        int progMode = 1; //Bitstream to FLASH
        using namespace std::placeholders;
        const auto cb = std::bind(&programmingCallbackStream, _1, _2, _3, path, callback);
        auto status = this->ProgramWrite(progData.data(), progData.size(), progMode, device, cb);
        if (status != 0) return status;
    }

    //Reset FX3, FPGA should be reloaded on boot
    {
        int device = LMS64CProtocol::FX3; //FX3
        auto status = this->ProgramWrite(nullptr, 0, 0, device, nullptr);
        if (status != 0) return status;
    }

    return 0;
}
<|endoftext|>


<commit_before>/*!
@file

@copyright Edouard Alligand and Joel Falcou 2015-2017
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_BRIGAND_SEQUENCES_FRONT_HPP
#define BOOST_BRIGAND_SEQUENCES_FRONT_HPP

#include <brigand/sequences/filled_list.hpp>
#include <brigand/types/integral_constant.hpp>
#include <brigand/types/type.hpp>

namespace brigand
{
// push_front
namespace detail
{
    template <class L, class... T>
    struct push_front_impl;

    template <template <class...> class L, class... U, class... T>
    struct push_front_impl<L<U...>, T...>
    {
        using type = L<T..., U...>;
    };
}

namespace lazy
{
    template <class L, class... T>
    struct push_front : detail::push_front_impl<L, T...>
    {
    };
}

template <class L, class... T>
using push_front = typename detail::push_front_impl<L, T...>::type;

// front
namespace detail
{
    template <class L>
    struct front_impl;

    template <template <class...> class L, class T, class... U>
    struct front_impl<L<T, U...>>
    {
        using type = T;
    };
}

template <class L>
using front = typename detail::front_impl<L>::type;

// pop front
namespace detail
{
    template <class L, unsigned int N>
    struct pop_front_impl;

    template <template <class...> class L, class T, class... U>
    struct pop_front_impl<L<T, U...>, 1>
    {
        using type = L<U...>;
    };

    template <template <class...> class L, class>
    struct pop_front_element;

    template <template <class...> class L, class... Ts>
    struct pop_front_element<L, list<Ts...>>
    {
        template <class... Us>
        static L<Us...> impl(Ts..., type_<Us> *...);
    };

    template <template <class...> class L, class... Ts, unsigned int N>
    struct pop_front_impl<L<Ts...>, N>
    {
        using type = decltype(pop_front_element<L, filled_list<void const *, N>>::impl(
            static_cast<type_<Ts> *>(nullptr)...));
    };
}
namespace lazy
{
    template <class L, class N = brigand::integral_constant<unsigned int, 1>>
    struct pop_front : detail::pop_front_impl<L, N::value>
    {
    };
}
template <class L, class N = brigand::integral_constant<unsigned int, 1>>
using pop_front = typename detail::pop_front_impl<L, N::value>::type;
}
#endif
<commit_msg>Delete front.hpp<commit_after><|endoftext|>


<commit_before>
#include <mpi.h>

#include "adios2.h"

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>

#include "PrintData.h"

int main(int argc, char *argv[])
{
    MPI_Init(&argc, &argv);

    if (argc < 2)
    {
        std::cout << "Not enough arguments: need an input file\n";
        return 1;
    }
    const char *inputfile = argv[1];

    /* World comm spans all applications started with the same aprun command
     on a Cray XK6. So we have to split and create the local
     'world' communicator for the reader only.
     In normal start-up, the communicator will just equal the MPI_COMM_WORLD.
     */

    int wrank, wnproc;
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
    MPI_Comm_size(MPI_COMM_WORLD, &wnproc);
    MPI_Barrier(MPI_COMM_WORLD);

    const unsigned int color = 2;
    MPI_Comm mpiReaderComm;
    MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &mpiReaderComm);

    int rank, nproc;
    MPI_Comm_rank(mpiReaderComm, &rank);
    MPI_Comm_size(mpiReaderComm, &nproc);

    adios2::ADIOS ad("adios2.xml", mpiReaderComm, adios2::DebugON);

    // Define method for engine creation
    // 1. Get method def from config file or define new one

    adios2::IO &bpReaderIO = ad.DeclareIO("input");
    if (!bpReaderIO.InConfigFile())
    {
        // if not defined by user, we can change the default settings
        // BPFileWriter is the default engine
        bpReaderIO.SetEngine("ADIOS1Reader");
        bpReaderIO.SetParameters({{"num_threads", "2"}});

        // ISO-POSIX file is the default transport
        // Passing parameters to the transport
        bpReaderIO.AddTransport("File", {{"verbose", "4"}});
    }

    auto bpReader =
        bpReaderIO.Open(inputfile, adios2::OpenMode::Read, mpiReaderComm);

    if (!bpReader)
    {
        throw std::ios_base::failure("ERROR: failed to open " +
                                     std::string(inputfile) + "\n");
    }

    unsigned int gndx;
    unsigned int gndy;
    // bpReader->Read<unsigned int>("gndx", &gndx);
    // bpReader->Read<unsigned int>("gndy", &gndy);

    adios2::Variable<unsigned int> *vgndx =
        bpReader->InquireVariable<unsigned int>("gndx");

    gndx = vgndx->m_Data[0];

    adios2::Variable<unsigned int> *vgndy =
        bpReader->InquireVariable<unsigned int>("gndy");
    gndy = vgndy->m_Data[0];

    if (rank == 0)
    {
        std::cout << "gndx       = " << gndx << std::endl;
        std::cout << "gndy       = " << gndy << std::endl;
        std::cout << "# of steps = " << vgndy->m_AvailableSteps << std::endl;
    }

    // 1D decomposition of the columns, which is inefficient for reading!
    std::vector<uint64_t> readsize({gndx, gndy / nproc});
    std::vector<uint64_t> offset({0LL, rank * readsize[1]});
    if (rank == nproc - 1)
    {
        // last process should read all the rest of columns
        readsize[1] = gndy - readsize[1] * (nproc - 1);
    }

    std::cout << "rank " << rank << " reads " << readsize[1]
              << " columns from offset " << offset[1] << std::endl;

    adios2::Variable<double> *vT = bpReader->InquireVariable<double>("T");

    double *T = new double[vT->m_AvailableSteps * readsize[0] * readsize[1]];

    // Create a 2D selection for the subset
    vT->SetSelection(offset, readsize);
    vT->SetStepSelection(0, vT->m_AvailableSteps);

    // Arrays are read by scheduling one or more of them
    // and performing the reads at once
    bpReader->ScheduleRead<double>(*vT, T);
    bpReader->PerformReads(adios2::ReadMode::Blocking);

    printData(T, readsize.data(), offset.data(), rank, vT->m_AvailableSteps);
    bpReader->Close();
    delete[] T;
    MPI_Finalize();
    return 0;
}
<commit_msg>fixed a size_t / uint64_t problem for macOS 10.12 and Clang 8.1.0<commit_after>
#include <mpi.h>

#include "adios2.h"

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>

#include "PrintData.h"

int main(int argc, char *argv[])
{
    MPI_Init(&argc, &argv);

    if (argc < 2)
    {
        std::cout << "Not enough arguments: need an input file\n";
        return 1;
    }
    const char *inputfile = argv[1];

    /* World comm spans all applications started with the same aprun command
     on a Cray XK6. So we have to split and create the local
     'world' communicator for the reader only.
     In normal start-up, the communicator will just equal the MPI_COMM_WORLD.
     */

    int wrank, wnproc;
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
    MPI_Comm_size(MPI_COMM_WORLD, &wnproc);
    MPI_Barrier(MPI_COMM_WORLD);

    const unsigned int color = 2;
    MPI_Comm mpiReaderComm;
    MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &mpiReaderComm);

    int rank, nproc;
    MPI_Comm_rank(mpiReaderComm, &rank);
    MPI_Comm_size(mpiReaderComm, &nproc);

    adios2::ADIOS ad("adios2.xml", mpiReaderComm, adios2::DebugON);

    // Define method for engine creation
    // 1. Get method def from config file or define new one

    adios2::IO &bpReaderIO = ad.DeclareIO("input");
    if (!bpReaderIO.InConfigFile())
    {
        // if not defined by user, we can change the default settings
        // BPFileWriter is the default engine
        bpReaderIO.SetEngine("ADIOS1Reader");
        bpReaderIO.SetParameters({{"num_threads", "2"}});

        // ISO-POSIX file is the default transport
        // Passing parameters to the transport
        bpReaderIO.AddTransport("File", {{"verbose", "4"}});
    }

    auto bpReader =
        bpReaderIO.Open(inputfile, adios2::OpenMode::Read, mpiReaderComm);

    if (!bpReader)
    {
        throw std::ios_base::failure("ERROR: failed to open " +
                                     std::string(inputfile) + "\n");
    }

    unsigned int gndx;
    unsigned int gndy;
    // bpReader->Read<unsigned int>("gndx", &gndx);
    // bpReader->Read<unsigned int>("gndy", &gndy);

    adios2::Variable<unsigned int> *vgndx =
        bpReader->InquireVariable<unsigned int>("gndx");

    gndx = vgndx->m_Data[0];

    adios2::Variable<unsigned int> *vgndy =
        bpReader->InquireVariable<unsigned int>("gndy");
    gndy = vgndy->m_Data[0];

    if (rank == 0)
    {
        std::cout << "gndx       = " << gndx << std::endl;
        std::cout << "gndy       = " << gndy << std::endl;
        std::cout << "# of steps = " << vgndy->m_AvailableSteps << std::endl;
    }

    // 1D decomposition of the columns, which is inefficient for reading!
    std::vector<uint64_t> readsize({gndx, gndy / nproc});
    std::vector<uint64_t> offset({0LL, rank * readsize[1]});
    std::vector<size_t> readsize_size_t({gndx, gndy / nproc});
    std::vector<size_t> offset_size_t({0LL, rank * readsize[1]});
    if (rank == nproc - 1)
    {
        // last process should read all the rest of columns
        readsize[1] = gndy - readsize[1] * (nproc - 1);
    }

    std::cout << "rank " << rank << " reads " << readsize[1]
              << " columns from offset " << offset[1] << std::endl;

    adios2::Variable<double> *vT = bpReader->InquireVariable<double>("T");

    double *T = new double[vT->m_AvailableSteps * readsize[0] * readsize[1]];

    // Create a 2D selection for the subset
    vT->SetSelection(offset_size_t, readsize_size_t);
    vT->SetStepSelection(0, vT->m_AvailableSteps);

    // Arrays are read by scheduling one or more of them
    // and performing the reads at once
    bpReader->ScheduleRead<double>(*vT, T);
    bpReader->PerformReads(adios2::ReadMode::Blocking);

    printData(T, readsize.data(), offset.data(), rank, vT->m_AvailableSteps);
    bpReader->Close();
    delete[] T;
    MPI_Finalize();
    return 0;
}
<|endoftext|>