<commit_before>
// Server.cpp

// Interfaces to the cServer class encapsulating the entire "server"

#include "Globals.h"
#include "Server.h"
#include "Connection.h"

cServer::cServer(void)
{
}

int cServer::Init(short a_ListenPort, short a_ConnectPort)
{
	m_ConnectPort = a_ConnectPort;

	#ifdef _WIN32
		WSAData wsa;
		int res = WSAStartup(0x0202, &wsa);
		if (res != 0)
		{
			printf("Cannot initialize WinSock: %d\n", res);
			return res;
		}
	#endif  // _WIN32

	printf("Generating protocol encryption keypair...\n");
	m_PrivateKey.Generate();
	m_PublicKeyDER = m_PrivateKey.GetPubKeyDER();

	m_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_ListenSocket < 0)
	{
		#ifdef _WIN32
			int err = WSAGetLastError();
		#else
			int err = errno;
		#endif
		printf("Failed to create listener socket: %d\n", err);
		return err;
	}
	sockaddr_in local;
	memset(&local, 0, sizeof(local));
	local.sin_family = AF_INET;
	local.sin_addr.s_addr = 130;  // INADDR_ANY;  // All interfaces
	local.sin_port = htons(a_ListenPort);
	if (!bind(m_ListenSocket, (sockaddr *)&local, sizeof(local)))
	{
		#ifdef _WIN32
			int err = WSAGetLastError();
		#else
			int err = errno;
		#endif
		printf("Failed to bind listener socket: %d\n", err);
		return err;
	}
	if (listen(m_ListenSocket, 1) != 0)
	{
		#ifdef _WIN32
			int err = WSAGetLastError();
		#else
			int err = errno;
		#endif
		printf("Failed to listen on socket: %d\n", err);
		return err;
	}

	printf("Listening on port %d, connecting to localhost:%d\n", a_ListenPort, a_ConnectPort);

	return 0;
}

void cServer::Run(void)
{
	printf("Server running.\n");
	while (true)
	{
		sockaddr_in Addr;
		memset(&Addr, 0, sizeof(Addr));
		socklen_t AddrSize = sizeof(Addr);
		SOCKET client = accept(m_ListenSocket, (sockaddr *)&Addr, &AddrSize);
		if (client == INVALID_SOCKET)
		{
			printf("accept returned an error: %d; bailing out.\n", SocketError);
			return;
		}
		printf("Client connected, proxying...\n");
		cConnection Connection(client, *this);
		Connection.Run();
		printf("Client disconnected. Ready for another connection.\n");
	}
}

<commit_msg>Fixed Server.cpp<commit_after>
// Server.cpp

// Interfaces to the cServer class encapsulating the entire "server"

#include "Globals.h"
#include "Server.h"
#include "Connection.h"

cServer::cServer(void)
{
}

int cServer::Init(short a_ListenPort, short a_ConnectPort)
{
	m_ConnectPort = a_ConnectPort;

	#ifdef _WIN32
		WSAData wsa;
		int res = WSAStartup(0x0202, &wsa);
		if (res != 0)
		{
			printf("Cannot initialize WinSock: %d\n", res);
			return res;
		}
	#endif  // _WIN32

	puts("Generating protocol encryption keypair...");
	m_PrivateKey.Generate();
	m_PublicKeyDER = m_PrivateKey.GetPubKeyDER();

	m_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_ListenSocket < 0)
	{
		#ifdef _WIN32
			int err = WSAGetLastError();
		#else
			int err = errno;
		#endif
		printf("Failed to create listener socket: %d\n", err);
		return err;
	}
	sockaddr_in local;
	memset(&local, 0, sizeof(local));
	local.sin_family = AF_INET;
	local.sin_addr.s_addr = 130;  // INADDR_ANY;  // All interfaces
	local.sin_port = htons(a_ListenPort);
	if (!bind(m_ListenSocket, (sockaddr *)&local, sizeof(local)))
	{
		#ifdef _WIN32
			int err = WSAGetLastError();
		#else
			int err = errno;
		#endif
		printf("Failed to bind listener socket: %d\n", err);
		return err;
	}
	if (listen(m_ListenSocket, 1) != 0)
	{
		#ifdef _WIN32
			int err = WSAGetLastError();
		#else
			int err = errno;
		#endif
		printf("Failed to listen on socket: %d\n", err);
		return err;
	}

	printf("Listening on port %d, connecting to localhost:%d\n", a_ListenPort, a_ConnectPort);

	return 0;
}

void cServer::Run(void)
{
	puts("Server running.");
	while (true)
	{
		sockaddr_in Addr;
		memset(&Addr, 0, sizeof(Addr));
		socklen_t AddrSize = sizeof(Addr);
		SOCKET client = accept(m_ListenSocket, (sockaddr *)&Addr, &AddrSize);
		if (client == INVALID_SOCKET)
		{
			printf("accept returned an error: %d; bailing out.\n", SocketError);
			return;
		}
		puts("Client connected, proxying...");
		cConnection Connection(client, *this);
		Connection.Run();
		puts("Client disconnected. Ready for another connection.");
	}
}

<|endoftext|>


<commit_before>#include "util\includeGL.h"

#include <iostream>

#include "Application.h"
#include "interfaces\Locator.h"
#include "processes\Timer.h"
#include "processes\TestProcess.h"
#include "events\QuitApplication.h"
#include "events\EventCameraTransform.h"
#include "events\EventToggleProjectionMode.h"
#include "events\EventToggleModelRotation.h"

Application::Application()
{
}

Application::~Application()
{
}

int Application::init(int* argc, char** argv)
{
	/* TODO:
		- Detect multiple instances of the application
		- Check secondary storage space and memory
		- Calculate the CPU speed
		- Load resource cache
		- Load string messages for application
		- Create LUA Script Manager
		- Create Event Manager
		- Script Manager to load initial options
		- Initialize window and input devices
		- Create game logic and game views
		- Set directory for saving sessions and temporary files
		- Preload selected resources from the resource cache
	*/

	this->processManager = std::make_shared<ProcessManager>();
	this->inputHandler = InputHandler::getInstance();
	this->eventManager = EventManager::getInstance();
	this->actorManager = std::make_shared<ActorManager>();
	this->renderer = Renderer::getInstance();

	Locator::provideRenderer(this->renderer);

	glutInit(argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(this->renderer->getWindowWidth(), this->renderer->getWindowHeight());
	glutInitWindowPosition(470, 0);
	glutCreateWindow(this->windowTitle);

	GLenum result = glewInit();
	if (result != GLEW_OK)
	{
		std::cerr << "Error initializing glew: \n"
			<< reinterpret_cast<const char*>(glewGetErrorString(result)) << std::endl;
		return -1;
	}

	glutKeyboardFunc(this->inputHandler->keyboardCall);
	glutMouseFunc(this->inputHandler->mouseCall);
	glutMouseWheelFunc(this->inputHandler->mouseWheelCall);
	glutMotionFunc(this->inputHandler->motionCall);

	return 1;
}

int Application::execute()
{
	std::chrono::time_point<std::chrono::high_resolution_clock> prevTime = std::chrono::high_resolution_clock::now();
	std::chrono::time_point<std::chrono::high_resolution_clock> currTime;

	this->actorManager->createActor("actors//car.xml");

	std::shared_ptr<Process> timer = std::make_shared<Timer>(2000);
	std::shared_ptr<Process> testProcess = std::make_shared<TestProcess>();
	timer->attachChild(testProcess);

	this->processManager->attachProcess(timer);
	this->processManager->attachProcess(this->renderer);

	this->eventManager->addListener(shared_from_this(), std::make_shared<QuitApplication>());
	this->eventManager->addListener(this->renderer, std::make_shared<EventCameraTransform>());
	this->eventManager->addListener(this->renderer, std::make_shared<EventToggleProjectionMode>());
	this->eventManager->addListener(this->renderer, std::make_shared<EventToggleModelRotation>());

	unsigned long duration;
	unsigned long prefDuration = unsigned long (1000 / this->preferredFPS);

	std::printf("Preferred Duration: %lu\n", prefDuration);

	while (!this->quit)
	{
		currTime = std::chrono::high_resolution_clock::now();
		duration = std::chrono::duration_cast<std::chrono::milliseconds>(currTime - prevTime).count();
		prevTime = currTime;

		if (duration < prefDuration)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds((prefDuration - duration)/2));
			duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - prevTime).count();
		}

		glutMainLoopEvent();

		this->update();
		this->eventManager->update();
		this->processManager->updateProcesses(duration);

	}

	printf("Exit Application::execute()\n");
	return 0;
}

int Application::shutdown()
{
	/*
		- Release resources
		- Save session to save directory and remove temporary files
		- Shutdown game logic and game views
		- Shutdown/release window and input devices
		- Shutdown Event Manager
		- Shutdown Script Manager
		- Delete string messages
		- Shutdown resource cache
		- ... make sure a graceful exit will happen
	*/

	printf("Shutdown renderer...\n");
	this->renderer.reset();

	printf("Shutdown ActorManager...\n");
	this->actorManager.reset();

	printf("Shutdown EventManager...\n");
	this->eventManager.reset();

	printf("Shutdown InputHandler...\n");
	this->inputHandler.reset();

	printf("Shutdown ProcessManager...\n");
	this->processManager.reset();

	return 0;
}

void Application::handleEvent(const std::shared_ptr<Event>& event_)
{
	if (std::shared_ptr<QuitApplication> quitMe = std::dynamic_pointer_cast<QuitApplication>(event_))
	{
		quitMe->sayHallo();
		this->quit = true;
	}
}<commit_msg>Load a \'default\' shaderprogram.<commit_after>#include "util\includeGL.h"

#include <iostream>

#include "Application.h"
#include "interfaces\Locator.h"
#include "processes\Timer.h"
#include "processes\TestProcess.h"
#include "events\QuitApplication.h"
#include "events\EventCameraTransform.h"
#include "events\EventToggleProjectionMode.h"
#include "events\EventToggleModelRotation.h"

Application::Application()
{
}

Application::~Application()
{
}

int Application::init(int* argc, char** argv)
{
	/* TODO:
		- Detect multiple instances of the application
		- Check secondary storage space and memory
		- Calculate the CPU speed
		- Load resource cache
		- Load string messages for application
		- Create LUA Script Manager
		- Create Event Manager
		- Script Manager to load initial options
		- Initialize window and input devices
		- Create game logic and game views
		- Set directory for saving sessions and temporary files
		- Preload selected resources from the resource cache
	*/

	this->processManager = std::make_shared<ProcessManager>();
	this->inputHandler = InputHandler::getInstance();
	this->eventManager = EventManager::getInstance();
	this->actorManager = std::make_shared<ActorManager>();
	this->renderer = Renderer::getInstance();

	Locator::provideRenderer(this->renderer);

	glutInit(argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(this->renderer->getWindowWidth(), this->renderer->getWindowHeight());
	glutInitWindowPosition(470, 0);
	glutCreateWindow(this->windowTitle);

	GLenum result = glewInit();
	if (result != GLEW_OK)
	{
		std::cerr << "Error initializing glew: \n"
			<< reinterpret_cast<const char*>(glewGetErrorString(result)) << std::endl;
		return -1;
	}

	glutKeyboardFunc(this->inputHandler->keyboardCall);
	glutMouseFunc(this->inputHandler->mouseCall);
	glutMouseWheelFunc(this->inputHandler->mouseWheelCall);
	glutMotionFunc(this->inputHandler->motionCall);

	this->renderer->getShaderProgram("phongLighting");

	return 1;
}

int Application::execute()
{
	std::chrono::time_point<std::chrono::high_resolution_clock> prevTime = std::chrono::high_resolution_clock::now();
	std::chrono::time_point<std::chrono::high_resolution_clock> currTime;

	this->actorManager->createActor("actors//car.xml");

	std::shared_ptr<Process> timer = std::make_shared<Timer>(2000);
	std::shared_ptr<Process> testProcess = std::make_shared<TestProcess>();
	timer->attachChild(testProcess);

	this->processManager->attachProcess(timer);
	this->processManager->attachProcess(this->renderer);

	this->eventManager->addListener(shared_from_this(), std::make_shared<QuitApplication>());
	this->eventManager->addListener(this->renderer, std::make_shared<EventCameraTransform>());
	this->eventManager->addListener(this->renderer, std::make_shared<EventToggleProjectionMode>());
	this->eventManager->addListener(this->renderer, std::make_shared<EventToggleModelRotation>());

	unsigned long duration;
	unsigned long prefDuration = unsigned long (1000 / this->preferredFPS);

	std::printf("Preferred Duration: %lu\n", prefDuration);

	while (!this->quit)
	{
		currTime = std::chrono::high_resolution_clock::now();
		duration = std::chrono::duration_cast<std::chrono::milliseconds>(currTime - prevTime).count();
		prevTime = currTime;

		if (duration < prefDuration)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds((prefDuration - duration)/2));
			duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - prevTime).count();
		}

		glutMainLoopEvent();

		this->update();
		this->eventManager->update();
		this->processManager->updateProcesses(duration);

	}

	printf("Exit Application::execute()\n");
	return 0;
}

int Application::shutdown()
{
	/*
		- Release resources
		- Save session to save directory and remove temporary files
		- Shutdown game logic and game views
		- Shutdown/release window and input devices
		- Shutdown Event Manager
		- Shutdown Script Manager
		- Delete string messages
		- Shutdown resource cache
		- ... make sure a graceful exit will happen
	*/

	printf("Shutdown renderer...\n");
	this->renderer.reset();

	printf("Shutdown ActorManager...\n");
	this->actorManager.reset();

	printf("Shutdown EventManager...\n");
	this->eventManager.reset();

	printf("Shutdown InputHandler...\n");
	this->inputHandler.reset();

	printf("Shutdown ProcessManager...\n");
	this->processManager.reset();

	return 0;
}

void Application::handleEvent(const std::shared_ptr<Event>& event_)
{
	if (std::shared_ptr<QuitApplication> quitMe = std::dynamic_pointer_cast<QuitApplication>(event_))
	{
		quitMe->sayHallo();
		this->quit = true;
	}
}<|endoftext|>


<commit_before>
// This file is part of the GDAL OPeNDAP Adapter

// Copyright (c) 2004 OPeNDAP, Inc.
// Author: Frank Warmerdam <warmerdam@pobox.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

//#define DODS_DEBUG 1

#include <iostream>
#include <sstream>
#include <string>

#include <gdal.h>

#include <DDS.h>
#include <DAS.h>
#include <ResponseBuilder.h>
#include <debug.h>

#include "GDALTypes.h"

extern void gdal_read_dataset_attributes(DAS &dds, const string &filename);

/************************************************************************/
/*                          read_descriptors()                          */
/************************************************************************/

GDALDatasetH gdal_read_dataset_variables(DDS *dds, const string &filename)
{
    GDALDatasetH hDS;
/* -------------------------------------------------------------------- */
/*      Open the dataset.                                               */
/* -------------------------------------------------------------------- */

    // TODO Since this code no longer closes the dataset, it would be
    // better to move the open operation outside it, to the caller.
    // jhrg 7/26/12
    GDALAllRegister();
    hDS = GDALOpen(filename.c_str(), GA_ReadOnly);

    if (hDS == NULL)
        throw Error(string(CPLGetLastErrorMsg()));

/* -------------------------------------------------------------------- */
/*      Create the basic matrix for each band.                          */
/* -------------------------------------------------------------------- */
    GDALDataType eBufType;

    for( int iBand = 0; iBand < GDALGetRasterCount( hDS ); iBand++ )
    {
        DBG(cerr << "In dgal_dds.cc  iBand" << endl);

        GDALRasterBandH hBand = GDALGetRasterBand( hDS, iBand+1 );
#if 0
        //BaseType *bt;
        // TODO ostringstream
        char szName[32];
        // nsprintf if not ostringstream
        sprintf( szName, "band_%d", iBand+1 );
#endif
        ostringstream oss;
        oss << "band_" << iBand+1;

        eBufType = GDALGetRasterDataType( hBand );

        BaseType *bt;
        switch( GDALGetRasterDataType( hBand ) )
        {
          case GDT_Byte:
            bt = new Byte( oss.str() );
            break;

          case GDT_UInt16:
            bt = new UInt16( oss.str() );
            break;

          case GDT_Int16:
            bt = new Int16( oss.str() );
            break;

          case GDT_UInt32:
            bt = new UInt32( oss.str() );
            break;

          case GDT_Int32:
            bt = new Int32( oss.str() );
            break;

          case GDT_Float32:
            bt = new Float32( oss.str() );
            break;

          case GDT_Float64:
            bt = new Float64( oss.str() );
            break;

          case GDT_CFloat32:
          case GDT_CFloat64:
          case GDT_CInt16:
          case GDT_CInt32:
          default:
            // TODO eventually we need to preserve complex info
            bt = new Float64( oss.str() );
            eBufType = GDT_Float64;
            break;
        }

/* -------------------------------------------------------------------- */
/*      Create a grid to hold the raster.                               */
/* -------------------------------------------------------------------- */
        Grid *grid;
        grid = new GDALGrid( filename, hBand, eBufType );
        grid->set_name(oss.str());

/* -------------------------------------------------------------------- */
/*      Make into an Array for the raster data with appropriate         */
/*      dimensions.                                                     */
/* -------------------------------------------------------------------- */
        Array *ar;
        // A 'feature' of Array is that it copies the variable passed to
        // its ctor. To get around that, pass null and use add_var_nocopy().
        ar = new GDALArray( oss.str(), 0 );
        ar->add_var_nocopy( bt );
        ar->append_dim( GDALGetRasterYSize( hDS ), "northing" );
        ar->append_dim( GDALGetRasterXSize( hDS ), "easting" );

        grid->add_var_nocopy( ar, array );

/* -------------------------------------------------------------------- */
/*      Add the dimension map arrays.                                   */
/* -------------------------------------------------------------------- */
        bt = new GDALFloat64( "northing" );
        ar = new GDALArray( "northing", 0 );
        ar->add_var_nocopy( bt );
        ar->append_dim( GDALGetRasterYSize( hDS ), "northing" );

        grid->add_var_nocopy( ar, maps );

        bt = new GDALFloat64( "easting" );
        ar = new GDALArray( "easting", 0 );
        ar->add_var_nocopy( bt );
        ar->append_dim( GDALGetRasterXSize( hDS ), "easting" );

        grid->add_var_nocopy( ar, maps );

        DBG(cerr << "Type of grid: " << typeid(grid).name() << endl);

        dds->add_var_nocopy( grid );
    }

    return hDS;
}
<commit_msg>Removed the libdap ResponseBuilder.h include from gdal_dds.cc (it's moved into the BES dap module and it's no longer needed).<commit_after>
// This file is part of the GDAL OPeNDAP Adapter

// Copyright (c) 2004 OPeNDAP, Inc.
// Author: Frank Warmerdam <warmerdam@pobox.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

//#define DODS_DEBUG 1

#include <iostream>
#include <sstream>
#include <string>

#include <gdal.h>

#include <DDS.h>
#include <DAS.h>
//TODO Remove #include <ResponseBuilder.h>
#include <debug.h>

#include "GDALTypes.h"

extern void gdal_read_dataset_attributes(DAS &dds, const string &filename);

/************************************************************************/
/*                          read_descriptors()                          */
/************************************************************************/

GDALDatasetH gdal_read_dataset_variables(DDS *dds, const string &filename)
{
    GDALDatasetH hDS;
/* -------------------------------------------------------------------- */
/*      Open the dataset.                                               */
/* -------------------------------------------------------------------- */

    // TODO Since this code no longer closes the dataset, it would be
    // better to move the open operation outside it, to the caller.
    // jhrg 7/26/12
    GDALAllRegister();
    hDS = GDALOpen(filename.c_str(), GA_ReadOnly);

    if (hDS == NULL)
        throw Error(string(CPLGetLastErrorMsg()));

/* -------------------------------------------------------------------- */
/*      Create the basic matrix for each band.                          */
/* -------------------------------------------------------------------- */
    GDALDataType eBufType;

    for( int iBand = 0; iBand < GDALGetRasterCount( hDS ); iBand++ )
    {
        DBG(cerr << "In dgal_dds.cc  iBand" << endl);

        GDALRasterBandH hBand = GDALGetRasterBand( hDS, iBand+1 );
#if 0
        //BaseType *bt;
        // TODO ostringstream
        char szName[32];
        // nsprintf if not ostringstream
        sprintf( szName, "band_%d", iBand+1 );
#endif
        ostringstream oss;
        oss << "band_" << iBand+1;

        eBufType = GDALGetRasterDataType( hBand );

        BaseType *bt;
        switch( GDALGetRasterDataType( hBand ) )
        {
          case GDT_Byte:
            bt = new Byte( oss.str() );
            break;

          case GDT_UInt16:
            bt = new UInt16( oss.str() );
            break;

          case GDT_Int16:
            bt = new Int16( oss.str() );
            break;

          case GDT_UInt32:
            bt = new UInt32( oss.str() );
            break;

          case GDT_Int32:
            bt = new Int32( oss.str() );
            break;

          case GDT_Float32:
            bt = new Float32( oss.str() );
            break;

          case GDT_Float64:
            bt = new Float64( oss.str() );
            break;

          case GDT_CFloat32:
          case GDT_CFloat64:
          case GDT_CInt16:
          case GDT_CInt32:
          default:
            // TODO eventually we need to preserve complex info
            bt = new Float64( oss.str() );
            eBufType = GDT_Float64;
            break;
        }

/* -------------------------------------------------------------------- */
/*      Create a grid to hold the raster.                               */
/* -------------------------------------------------------------------- */
        Grid *grid;
        grid = new GDALGrid( filename, hBand, eBufType );
        grid->set_name(oss.str());

/* -------------------------------------------------------------------- */
/*      Make into an Array for the raster data with appropriate         */
/*      dimensions.                                                     */
/* -------------------------------------------------------------------- */
        Array *ar;
        // A 'feature' of Array is that it copies the variable passed to
        // its ctor. To get around that, pass null and use add_var_nocopy().
        ar = new GDALArray( oss.str(), 0 );
        ar->add_var_nocopy( bt );
        ar->append_dim( GDALGetRasterYSize( hDS ), "northing" );
        ar->append_dim( GDALGetRasterXSize( hDS ), "easting" );

        grid->add_var_nocopy( ar, array );

/* -------------------------------------------------------------------- */
/*      Add the dimension map arrays.                                   */
/* -------------------------------------------------------------------- */
        bt = new GDALFloat64( "northing" );
        ar = new GDALArray( "northing", 0 );
        ar->add_var_nocopy( bt );
        ar->append_dim( GDALGetRasterYSize( hDS ), "northing" );

        grid->add_var_nocopy( ar, maps );

        bt = new GDALFloat64( "easting" );
        ar = new GDALArray( "easting", 0 );
        ar->add_var_nocopy( bt );
        ar->append_dim( GDALGetRasterXSize( hDS ), "easting" );

        grid->add_var_nocopy( ar, maps );

        DBG(cerr << "Type of grid: " << typeid(grid).name() << endl);

        dds->add_var_nocopy( grid );
    }

    return hDS;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */

#include "sgbuilder.h"
#include "halBlockMapper.h"

using namespace std;
using namespace hal;

SGBuilder::SGBuilder() : _sg(0), _root(0), _lookup(0), _mapMrca(0)
{

}

SGBuilder::~SGBuilder()
{
  clear();
}

void SGBuilder::init(AlignmentConstPtr alignment, const Genome* root)
{
  clear();
  _alignment = alignment;
  _sg = new SideGraph();
  _root = root;
}

void SGBuilder::clear()
{
  delete _sg;
  _sg = NULL;
  _alignment = AlignmentConstPtr();
  for (GenomeLUMap::iterator i = _luMap.begin(); i != _luMap.end(); ++i)
  {
    delete i->second;
  }
  _luMap.clear();
  _lookup = NULL;
  _seqMapBack.clear();
  _mapPath.clear();
  _mapMrca = NULL;
}

const SideGraph* SGBuilder::getSideGraph() const
{
  return _sg;
}

void SGBuilder::addGenome(const Genome* genome,
                          const Sequence* sequence,
                          hal_index_t start,
                          hal_index_t length)
{
  assert(_luMap.find(genome->getName()) == _luMap.end());

  start = std::max((hal_index_t)0, start);
  if (length <= 0)
  {
    if (sequence == NULL)
    {
      length = genome->getSequenceLength() - start;
    }
    else
    {
      length = sequence->getSequenceLength() - start;
    }
  }

  // Add genomes sequences to the lookup structure
  vector<string> seqNames;
  if (sequence != NULL)
  {
    seqNames.push_back(sequence->getName());
  }
  else
  {
    SequenceIteratorConstPtr si = genome->getSequenceIterator();
    SequenceIteratorConstPtr sie = genome->getSequenceEndIterator();
    const Sequence* curSequence = si->getSequence();
    for (; si != sie; si->toNext())
    {
      if (start <= curSequence->getEndPosition() &&
          (start + length-1) >= curSequence->getStartPosition())
      {
        seqNames.push_back(curSequence->getName());
      }
    }
  }
  _lookup = new SGLookup();
  _lookup->init(seqNames);
  _luMap.insert(pair<string, SGLookup*>(genome->getName(), _lookup));

  // If sequence is not NULL, start in sequence coordinates and
  // need to be converted
  if (sequence != NULL)
  {
    start += sequence->getStartPosition();
  }

  // Compute the target
  const Genome* target = getTarget(genome);
  // Update the mapping structures.  Should verify with Joel what
  // these new parameters mean.
  if (target != NULL)
  {
    set<const Genome*> inputSet;
    inputSet.insert(genome);
    inputSet.insert(target);
    _mapMrca = getLowestCommonAncestor(inputSet);
    inputSet.clear();
    inputSet.insert(_root);
    inputSet.insert(target);
    getGenomesInSpanningTree(inputSet, _mapPath);
  }

  // Convert sequence by sequence
  for (size_t i = 0; i < seqNames.size(); ++i)
  {
    const Sequence* curSequence = genome->getSequence(seqNames[i]);
    hal_index_t endPos = start + length - 1;
    hal_index_t curStart = std::max(start, curSequence->getStartPosition());
    hal_index_t curEnd = std::min(endPos, curSequence->getEndPosition());

    // note all coordinates global
    mapSequence(curSequence, curStart, curEnd, target);
  }
}

const Genome* SGBuilder::getTarget(const Genome* genome)
{
  // This code may be too dumb to be any more than a placeholder, but
  // have no short term designs on huge trees...

  // find the nearest genome in our hal tree that's already been added
  // to the lookup structure.
  size_t dist = numeric_limits<size_t>::max();
  const Genome* best = NULL;
  for (GenomeLUMap::const_iterator i = _luMap.begin(); i != _luMap.end(); ++i)
  {
    const Genome* candidate = _alignment->openGenome(i->first);
    size_t cdist = getGenomeDistance(candidate, genome);
    if (cdist > 0 && cdist < dist)
    {
      dist = cdist;
      best = candidate;
    }
  }
  return best;
}

SGSequence* SGBuilder::createSGSequence(const Sequence* sequence,
                                        hal_index_t startOffset,
                                        hal_index_t length)
{
  // make a new Side Graph Sequence
  SGSequence* sgSeq = new SGSequence();
  sgSeq->_length = length;
  sgSeq->_name = sequence->getName();
  // add to the Side Graph
  _sg->addSequence(sgSeq);
  // keep record of where it came from
  _seqMapBack.insert(pair<SGSequence*, pair<const Sequence*, hal_index_t> >(
                       sgSeq,
                       pair<const Sequence*, hal_index_t>(sequence,
                                                          startOffset)));
  return sgSeq;
}

void SGBuilder::mapSequence(const Sequence* sequence,
                            hal_index_t globalStart,
                            hal_index_t globalEnd,
                            const Genome* target)
{
  //easy case: add sequences without any joins because we are doing root
  //and everything is empty (same logic for empty sequence)
  const Genome* genome = sequence->getGenome();
  if ((target == NULL && genome == _root) || globalEnd == globalStart)
  {
    createSGSequence(sequence, globalStart - sequence->getStartPosition(),
                     globalEnd - globalStart + 1);
  }
  else
  {
    if (target == NULL)
    {
      // map to self
      target = genome;
      _mapMrca = genome;
    }

    // block mapping logic below largely taken from halBlockLiftover.cpp
    SegmentIteratorConstPtr refSeg;
    hal_index_t lastIndex;
    if (genome->getNumTopSegments() > 0)
    {
      refSeg = genome->getTopSegmentIterator();
      lastIndex = (hal_index_t)genome->getNumTopSegments();
      for (size_t i = 0; i < lastIndex; ++i)
      {
        TopSegmentIteratorConstPtr ts = genome->getTopSegmentIterator(i);
        if (ts->hasNextParalogy())
        {
          ts->print(cout); cout << endl;
        }
      }
    }
    else
    {
      refSeg = genome->getBottomSegmentIterator();
      lastIndex = (hal_index_t)genome->getNumBottomSegments();
    }

    refSeg->toSite(globalStart, false);
    hal_offset_t startOffset = globalStart - refSeg->getStartPosition();
    hal_offset_t endOffset = 0;
    if (globalEnd <= refSeg->getEndPosition())
    {
      endOffset = refSeg->getEndPosition() - globalEnd;
    }
    refSeg->slice(startOffset, endOffset);

    assert(refSeg->getStartPosition() ==  globalStart);
    assert(refSeg->getEndPosition() <= globalEnd);

    set<MappedSegmentConstPtr> mappedSegments;

    cout << "Mapping " << sequence->getFullName() << " to "
         << target->getName()
         << "; MRC = " << _mapMrca->getName()
         << "; ROOT = " << _root->getName()
         << "; PATH = ";
    for (set<const Genome*>::iterator i = _mapPath.begin();
         i != _mapPath.end(); ++i)
    {
       cout << (*i)->getName() << ", ";
    }
    cout << endl;

    while (refSeg->getArrayIndex() < lastIndex &&
           refSeg->getStartPosition() <= globalEnd)
    {
      refSeg->getMappedSegments(mappedSegments, target, &_mapPath,
                                true, 0, _root, _mapMrca);
      refSeg->toRight(globalEnd);
    }

    vector<Block*> blocks;
    blocks.reserve(mappedSegments.size());

    vector<MappedSegmentConstPtr> fragments;
    BlockMapper::MSSet emptySet;
    set<hal_index_t> queryCutSet;
    set<hal_index_t> targetCutSet;
    for (set<MappedSegmentConstPtr>::iterator i = mappedSegments.begin();
         i != mappedSegments.end(); ++i)
    {
      BlockMapper::extractSegment(i, emptySet, fragments, &mappedSegments,
                                  targetCutSet, queryCutSet);
      Block* block = new Block();
      fragmentsToBlock(fragments, *block);
      blocks.push_back(block);
    }
    // extractSegment() method above works in sorted order by target.
    // we need sorted order by source (to detect insertions, for example).
    sort(blocks.begin(), blocks.end(), BlockPtrLess());

    if (blocks.empty() == true)
    {
      // case with zero mapped blocks.  entire segment will be insertion.
      updateSegment(NULL, NULL, NULL, sequence,
                    genome, globalStart, globalEnd, target);
    }
    else
    {
      for (size_t j = 0; j < blocks.size(); ++j)
      {
        Block* prev = j == 0 ? NULL : blocks[j-1];
        Block* next = j == blocks.size() - 1 ? NULL : blocks[j+1];
        updateSegment(prev, blocks[j], next, sequence,
                      genome, globalStart, globalEnd, target);
      }
    }
    for (size_t j = 0; j < blocks.size(); ++j)
    {
      delete blocks[j];
    }
  }
}

void SGBuilder::updateSegment(Block* prevBlock,
                              Block* block,
                              Block* nextBlock,
                              const Sequence* srcSequence,
                              const Genome* srcGenome,
                              hal_index_t globalStart, hal_index_t globalEnd,
                              const Genome* tgtGenome)
{
  // handle insertion (source sequence not mapped to target)
  hal_index_t prevSrcPos = prevBlock != NULL ? prevBlock->_srcEnd : 0;
  hal_index_t srcPos = block != NULL ? block->_srcStart :
     globalEnd - srcSequence->getEndPosition();
  assert(srcPos >= prevSrcPos);
  if (srcPos > prevSrcPos)
  {

  }

}

void SGBuilder::fragmentsToBlock(const vector<MappedSegmentConstPtr>& fragments,
                                 Block& block) const
{
  block._tgtStart = min(min(fragments.front()->getStartPosition(),
                            fragments.front()->getEndPosition()),
                        min(fragments.back()->getStartPosition(),
                            fragments.back()->getEndPosition()));
  block._tgtEnd = max(max(fragments.front()->getStartPosition(),
                          fragments.front()->getEndPosition()),
                      max(fragments.back()->getStartPosition(),
                          fragments.back()->getEndPosition()));
  block._tgtSeq = fragments.front()->getSequence();

  SlicedSegmentConstPtr srcFront = fragments.front()->getSource();
  SlicedSegmentConstPtr srcBack = fragments.back()->getSource();

  block._srcStart =  min(min(srcFront->getStartPosition(),
                             srcFront->getEndPosition()),
                         min(srcBack->getStartPosition(),
                             srcBack->getEndPosition()));
  block._srcEnd = max(max(srcFront->getStartPosition(),
                          srcFront->getEndPosition()),
                      max(srcBack->getStartPosition(),
                          srcBack->getEndPosition()));
  block._srcSeq = srcFront->getSequence();

  // convert to segment level;
  block._tgtStart -= block._tgtSeq->getStartPosition();
  block._tgtEnd -= block._tgtSeq->getStartPosition();
  block._srcStart -= block._srcSeq->getStartPosition();
  block._srcEnd -= block._srcSeq->getStartPosition();

  block._reversed = srcFront->getReversed() != fragments.front()->getReversed();
}
<commit_msg>name new sequences.  stub for insert.  up next adding all joins<commit_after>/*
 * Copyright (C) 2015 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */

#include <sstream>

#include "sgbuilder.h"
#include "halBlockMapper.h"

using namespace std;
using namespace hal;

SGBuilder::SGBuilder() : _sg(0), _root(0), _lookup(0), _mapMrca(0)
{

}

SGBuilder::~SGBuilder()
{
  clear();
}

void SGBuilder::init(AlignmentConstPtr alignment, const Genome* root)
{
  clear();
  _alignment = alignment;
  _sg = new SideGraph();
  _root = root;
}

void SGBuilder::clear()
{
  delete _sg;
  _sg = NULL;
  _alignment = AlignmentConstPtr();
  for (GenomeLUMap::iterator i = _luMap.begin(); i != _luMap.end(); ++i)
  {
    delete i->second;
  }
  _luMap.clear();
  _lookup = NULL;
  _seqMapBack.clear();
  _mapPath.clear();
  _mapMrca = NULL;
}

const SideGraph* SGBuilder::getSideGraph() const
{
  return _sg;
}

void SGBuilder::addGenome(const Genome* genome,
                          const Sequence* sequence,
                          hal_index_t start,
                          hal_index_t length)
{
  assert(_luMap.find(genome->getName()) == _luMap.end());

  start = std::max((hal_index_t)0, start);
  if (length <= 0)
  {
    if (sequence == NULL)
    {
      length = genome->getSequenceLength() - start;
    }
    else
    {
      length = sequence->getSequenceLength() - start;
    }
  }

  // Add genomes sequences to the lookup structure
  vector<string> seqNames;
  if (sequence != NULL)
  {
    seqNames.push_back(sequence->getName());
  }
  else
  {
    SequenceIteratorConstPtr si = genome->getSequenceIterator();
    SequenceIteratorConstPtr sie = genome->getSequenceEndIterator();
    const Sequence* curSequence = si->getSequence();
    for (; si != sie; si->toNext())
    {
      if (start <= curSequence->getEndPosition() &&
          (start + length-1) >= curSequence->getStartPosition())
      {
        seqNames.push_back(curSequence->getName());
      }
    }
  }
  _lookup = new SGLookup();
  _lookup->init(seqNames);
  _luMap.insert(pair<string, SGLookup*>(genome->getName(), _lookup));

  // If sequence is not NULL, start in sequence coordinates and
  // need to be converted
  if (sequence != NULL)
  {
    start += sequence->getStartPosition();
  }

  // Compute the target
  const Genome* target = getTarget(genome);
  // Update the mapping structures.  Should verify with Joel what
  // these new parameters mean.
  if (target != NULL)
  {
    set<const Genome*> inputSet;
    inputSet.insert(genome);
    inputSet.insert(target);
    _mapMrca = getLowestCommonAncestor(inputSet);
    inputSet.clear();
    inputSet.insert(_root);
    inputSet.insert(target);
    getGenomesInSpanningTree(inputSet, _mapPath);
  }

  // Convert sequence by sequence
  for (size_t i = 0; i < seqNames.size(); ++i)
  {
    const Sequence* curSequence = genome->getSequence(seqNames[i]);
    hal_index_t endPos = start + length - 1;
    hal_index_t curStart = std::max(start, curSequence->getStartPosition());
    hal_index_t curEnd = std::min(endPos, curSequence->getEndPosition());

    // note all coordinates global
    mapSequence(curSequence, curStart, curEnd, target);
  }
}

const Genome* SGBuilder::getTarget(const Genome* genome)
{
  // This code may be too dumb to be any more than a placeholder, but
  // have no short term designs on huge trees...

  // find the nearest genome in our hal tree that's already been added
  // to the lookup structure.
  size_t dist = numeric_limits<size_t>::max();
  const Genome* best = NULL;
  for (GenomeLUMap::const_iterator i = _luMap.begin(); i != _luMap.end(); ++i)
  {
    const Genome* candidate = _alignment->openGenome(i->first);
    size_t cdist = getGenomeDistance(candidate, genome);
    if (cdist > 0 && cdist < dist)
    {
      dist = cdist;
      best = candidate;
    }
  }
  return best;
}

SGSequence* SGBuilder::createSGSequence(const Sequence* sequence,
                                        hal_index_t startOffset,
                                        hal_index_t length)
{
  // make a new Side Graph Sequence
  SGSequence* sgSeq = new SGSequence();
  sgSeq->_length = length;
  stringstream name;
  name << sequence->getFullName();
  if (length < sequence->getSequenceLength())
  {
    name << "_" << startOffset << ":" << length;
  }
  sgSeq->_name = name.str();

  // add to the Side Graph
  _sg->addSequence(sgSeq);
  // keep record of where it came from
  _seqMapBack.insert(pair<SGSequence*, pair<const Sequence*, hal_index_t> >(
                       sgSeq,
                       pair<const Sequence*, hal_index_t>(sequence,
                                                          startOffset)));
  return sgSeq;
}

void SGBuilder::mapSequence(const Sequence* sequence,
                            hal_index_t globalStart,
                            hal_index_t globalEnd,
                            const Genome* target)
{
  //easy case: add sequences without any joins because we are doing root
  //and everything is empty (same logic for empty sequence)
  const Genome* genome = sequence->getGenome();
  if ((target == NULL && genome == _root) || globalEnd == globalStart)
  {
    createSGSequence(sequence, globalStart - sequence->getStartPosition(),
                     globalEnd - globalStart + 1);
  }
  else
  {
    if (target == NULL)
    {
      // map to self
      target = genome;
      _mapMrca = genome;
    }

    // block mapping logic below largely taken from halBlockLiftover.cpp
    SegmentIteratorConstPtr refSeg;
    hal_index_t lastIndex;
    if (genome->getNumTopSegments() > 0)
    {
      refSeg = genome->getTopSegmentIterator();
      lastIndex = (hal_index_t)genome->getNumTopSegments();
    }
    else
    {
      refSeg = genome->getBottomSegmentIterator();
      lastIndex = (hal_index_t)genome->getNumBottomSegments();
    }

    refSeg->toSite(globalStart, false);
    hal_offset_t startOffset = globalStart - refSeg->getStartPosition();
    hal_offset_t endOffset = 0;
    if (globalEnd <= refSeg->getEndPosition())
    {
      endOffset = refSeg->getEndPosition() - globalEnd;
    }
    refSeg->slice(startOffset, endOffset);

    assert(refSeg->getStartPosition() ==  globalStart);
    assert(refSeg->getEndPosition() <= globalEnd);

    set<MappedSegmentConstPtr> mappedSegments;

    cout << "Mapping " << sequence->getFullName() << " to "
         << target->getName()
         << "; MRC = " << _mapMrca->getName()
         << "; ROOT = " << _root->getName()
         << "; PATH = ";
    for (set<const Genome*>::iterator i = _mapPath.begin();
         i != _mapPath.end(); ++i)
    {
       cout << (*i)->getName() << ", ";
    }
    cout << endl;

    while (refSeg->getArrayIndex() < lastIndex &&
           refSeg->getStartPosition() <= globalEnd)
    {
      refSeg->getMappedSegments(mappedSegments, target, &_mapPath,
                                true, 0, _root, _mapMrca);
      refSeg->toRight(globalEnd);
    }

    vector<Block*> blocks;
    blocks.reserve(mappedSegments.size());

    vector<MappedSegmentConstPtr> fragments;
    BlockMapper::MSSet emptySet;
    set<hal_index_t> queryCutSet;
    set<hal_index_t> targetCutSet;
    for (set<MappedSegmentConstPtr>::iterator i = mappedSegments.begin();
         i != mappedSegments.end(); ++i)
    {
      BlockMapper::extractSegment(i, emptySet, fragments, &mappedSegments,
                                  targetCutSet, queryCutSet);
      Block* block = new Block();
      fragmentsToBlock(fragments, *block);
      blocks.push_back(block);
    }
    // extractSegment() method above works in sorted order by target.
    // we need sorted order by source (to detect insertions, for example).
    sort(blocks.begin(), blocks.end(), BlockPtrLess());

    if (blocks.empty() == true)
    {
      // case with zero mapped blocks.  entire segment will be insertion.
      updateSegment(NULL, NULL, NULL, sequence,
                    genome, globalStart, globalEnd, target);
    }
    else
    {
      for (size_t j = 0; j < blocks.size(); ++j)
      {
        Block* prev = j == 0 ? NULL : blocks[j-1];
        Block* next = j == blocks.size() - 1 ? NULL : blocks[j+1];
        updateSegment(prev, blocks[j], next, sequence,
                      genome, globalStart, globalEnd, target);
      }
    }
    for (size_t j = 0; j < blocks.size(); ++j)
    {
      delete blocks[j];
    }
  }
}

void SGBuilder::updateSegment(Block* prevBlock,
                              Block* block,
                              Block* nextBlock,
                              const Sequence* srcSequence,
                              const Genome* srcGenome,
                              hal_index_t globalStart, hal_index_t globalEnd,
                              const Genome* tgtGenome)
{
  // handle insertion (source sequence not mapped to target)
  hal_index_t prevSrcPos = prevBlock != NULL ? prevBlock->_srcEnd : 0;
  hal_index_t srcPos = block != NULL ? block->_srcStart :
     globalEnd - srcSequence->getEndPosition();
  if (srcPos > prevSrcPos)
  {
    // insert new sequence
    SGSequence* insertedSeq = createSGSequence(srcSequence, srcPos,
                                              srcPos - prevSrcPos);
  }

}

void SGBuilder::fragmentsToBlock(const vector<MappedSegmentConstPtr>& fragments,
                                 Block& block) const
{
  block._tgtStart = min(min(fragments.front()->getStartPosition(),
                            fragments.front()->getEndPosition()),
                        min(fragments.back()->getStartPosition(),
                            fragments.back()->getEndPosition()));
  block._tgtEnd = max(max(fragments.front()->getStartPosition(),
                          fragments.front()->getEndPosition()),
                      max(fragments.back()->getStartPosition(),
                          fragments.back()->getEndPosition()));
  block._tgtSeq = fragments.front()->getSequence();

  SlicedSegmentConstPtr srcFront = fragments.front()->getSource();
  SlicedSegmentConstPtr srcBack = fragments.back()->getSource();

  block._srcStart =  min(min(srcFront->getStartPosition(),
                             srcFront->getEndPosition()),
                         min(srcBack->getStartPosition(),
                             srcBack->getEndPosition()));
  block._srcEnd = max(max(srcFront->getStartPosition(),
                          srcFront->getEndPosition()),
                      max(srcBack->getStartPosition(),
                          srcBack->getEndPosition()));
  block._srcSeq = srcFront->getSequence();

  // convert to segment level;
  block._tgtStart -= block._tgtSeq->getStartPosition();
  block._tgtEnd -= block._tgtSeq->getStartPosition();
  block._srcStart -= block._srcSeq->getStartPosition();
  block._srcEnd -= block._srcSeq->getStartPosition();

  block._reversed = srcFront->getReversed() != fragments.front()->getReversed();
}
<|endoftext|>


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

#include <assert.h>
#include <boost/program_options.hpp>
#include <iostream>
#include <map>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

enum TokenType : int8_t
{
    TOK_LABEL,
    TOK_REF,
    TOK_U8,
    TOK_U16,
    TOK_U32
};

struct Stream
{
    std::string name;
    std::vector<TokenType> tokenTypes;
    std::vector<uint32_t> tokenValues;
    std::vector<std::string> tokenComments;
};

Stream stringStream;
std::vector<Stream> streams;
std::map<std::string, int> streamIndex;
std::vector<int> streamStack;

std::vector<int> labels;
std::vector<std::string> labelNames;
std::map<std::string, int> labelIndex;

std::vector<std::string> preText, postText;

const char *skipWhitespace(const char *p)
{
    if (p == nullptr)
        return "";
    while (*p == ' ' || *p == '\t')
        p++;
    return p;
}

int main(int argc, char **argv)
{
    bool debug = false;
    bool verbose = false;
    bool bigEndian = false;
    bool writeC = false;
    char buffer[512];

    namespace po = boost::program_options;
    po::positional_options_description pos;
    po::options_description options("Allowed options");
    options.add_options()("v", "verbose output");
    options.add_options()("d", "debug output");
    options.add_options()("b", "big endian");
    options.add_options()("c", "write c strings");
    options.add_options()("files", po::value<std::vector<std::string>>(), "file parameters");
    pos.add("files", -1);

    po::variables_map vm;
    try {
        po::parsed_options parsed = po::command_line_parser(argc, argv).options(options).positional(pos).run();

        po::store(parsed, vm);

        po::notify(vm);
    } catch (std::exception &e) {
        std::cout << e.what() << "\n";
        return 1;
    }
    if (vm.count("v"))
        verbose = true;
    if (vm.count("d"))
        debug = true;
    if (vm.count("b"))
        bigEndian = true;
    if (vm.count("c"))
        writeC = true;

    if (vm.count("files") == 0) {
        printf("File parameters are mandatory\n");
        exit(-1);
    }
    std::vector<std::string> files = vm["files"].as<std::vector<std::string>>();
    if (files.size() != 2) {
        printf("Input and output parameters must be set\n");
        exit(-1);
    }

    FILE *fileIn = fopen(files.at(0).c_str(), "rt");
    assert(fileIn != nullptr);

    FILE *fileOut = fopen(files.at(1).c_str(), writeC ? "wt" : "wb");
    assert(fileOut != nullptr);

    while (fgets(buffer, 512, fileIn) != nullptr) {
        std::string cmd = strtok(buffer, " \t\r\n");

        if (cmd == "pre") {
            const char *p = skipWhitespace(strtok(nullptr, "\r\n"));
            preText.push_back(p);
            continue;
        }

        if (cmd == "post") {
            const char *p = skipWhitespace(strtok(nullptr, "\r\n"));
            postText.push_back(p);
            continue;
        }

        if (cmd == "push") {
            const char *p = strtok(nullptr, " \t\r\n");
            if (streamIndex.count(p) == 0) {
                streamIndex[p] = streams.size();
                streams.resize(streams.size() + 1);
                streams.back().name = p;
            }
            streamStack.push_back(streamIndex.at(p));
            continue;
        }

        if (cmd == "pop") {
            streamStack.pop_back();
            continue;
        }

        if (cmd == "label" || cmd == "ref") {
            const char *label = strtok(nullptr, " \t\r\n");
            const char *comment = skipWhitespace(strtok(nullptr, "\r\n"));
            Stream &s = streams.at(streamStack.back());
            if (labelIndex.count(label) == 0) {
                labelIndex[label] = labels.size();
                if (debug)
                    labelNames.push_back(label);
                labels.push_back(-1);
            }
            s.tokenTypes.push_back(cmd == "label" ? TOK_LABEL : TOK_REF);
            s.tokenValues.push_back(labelIndex.at(label));
            if (debug)
                s.tokenComments.push_back(comment);
            continue;
        }

        if (cmd == "u8" || cmd == "u16" || cmd == "u32") {
            const char *value = strtok(nullptr, " \t\r\n");
            const char *comment = skipWhitespace(strtok(nullptr, "\r\n"));
            Stream &s = streams.at(streamStack.back());
            s.tokenTypes.push_back(cmd == "u8" ? TOK_U8 : cmd == "u16" ? TOK_U16 : TOK_U32);
            s.tokenValues.push_back(atoll(value));
            if (debug)
                s.tokenComments.push_back(comment);
            continue;
        }

        if (cmd == "str") {
            const char *value = skipWhitespace(strtok(nullptr, "\r\n"));
            assert(*value != 0);
            char *end = strchr((char *)value + 1, *value);
            *end = 0;
            value += 1;
            const char *comment = skipWhitespace(strtok(end+1, "\r\n"));
            std::string label = std::string("str:") + value;
            Stream &s = streams.at(streamStack.back());
            if (labelIndex.count(label) == 0) {
                labelIndex[label] = labels.size();
                if (debug)
                    labelNames.push_back(label);
                labels.push_back(-1);
            }
            s.tokenTypes.push_back(TOK_REF);
            s.tokenValues.push_back(labelIndex.at(label));
            if (debug)
                s.tokenComments.push_back(comment);
            stringStream.tokenTypes.push_back(TOK_LABEL);
            stringStream.tokenValues.push_back(labelIndex.at(label));
            stringStream.tokenComments.push_back("");
            while (1) {
                stringStream.tokenTypes.push_back(TOK_U8);
                stringStream.tokenValues.push_back(*value);
                if (debug) {
                    char char_comment[4] = {'\'', *value, '\'', 0};
                    if (*value < 32 || *value >= 127)
                        char_comment[0] = 0;
                    stringStream.tokenComments.push_back(char_comment);
                }
                if (*value == 0)
                    break;
                value++;
            }
            continue;
        }

        assert(0);
    }

    if (verbose) {
        printf("Constructed %d streams:\n", int(streams.size()));
        for (auto &s : streams)
            printf("    stream '%s' with %d tokens\n", s.name.c_str(), int(s.tokenTypes.size()));
    }

    assert(!streams.empty());
    assert(streamStack.empty());
    streams.push_back(Stream());
    streams.back().name = "strings";
    streams.back().tokenTypes.swap(stringStream.tokenTypes);
    streams.back().tokenValues.swap(stringStream.tokenValues);
    streams.back().tokenComments.swap(stringStream.tokenComments);

    int cursor = 0;
    for (auto &s : streams) {
        for (int i = 0; i < int(s.tokenTypes.size()); i++) {
            switch (s.tokenTypes[i]) {
            case TOK_LABEL:
                labels[s.tokenValues[i]] = cursor;
                break;
            case TOK_REF:
                cursor += 4;
                break;
            case TOK_U8:
                cursor += 1;
                break;
            case TOK_U16:
                assert(cursor % 2 == 0);
                cursor += 2;
                break;
            case TOK_U32:
                assert(cursor % 4 == 0);
                cursor += 4;
                break;
            default:
                assert(0);
            }
        }
    }

    if (verbose) {
        printf("resolved positions for %d labels.\n", int(labels.size()));
        printf("total data (including strings): %.2f MB\n", double(cursor) / (1024 * 1024));
    }

    std::vector<uint8_t> data(cursor);

    cursor = 0;
    for (auto &s : streams) {
        if (debug)
            printf("-- %s --\n", s.name.c_str());

        for (int i = 0; i < int(s.tokenTypes.size()); i++) {
            uint32_t value = s.tokenValues[i];
            int numBytes = 0;

            switch (s.tokenTypes[i]) {
            case TOK_LABEL:
                break;
            case TOK_REF:
                value = labels[value] - cursor;
                numBytes = 4;
                break;
            case TOK_U8:
                numBytes = 1;
                break;
            case TOK_U16:
                numBytes = 2;
                break;
            case TOK_U32:
                numBytes = 4;
                break;
            default:
                assert(0);
            }

            if (bigEndian) {
                switch (numBytes) {
                case 4:
                    data[cursor++] = value >> 24;
                    data[cursor++] = value >> 16;
                /* fall-through */
                case 2:
                    data[cursor++] = value >> 8;
                /* fall-through */
                case 1:
                    data[cursor++] = value;
                /* fall-through */
                case 0:
                    break;
                default:
                    assert(0);
                }
            } else {
                switch (numBytes) {
                case 4:
                    data[cursor + 3] = value >> 24;
                    data[cursor + 2] = value >> 16;
                /* fall-through */
                case 2:
                    data[cursor + 1] = value >> 8;
                /* fall-through */
                case 1:
                    data[cursor] = value;
                /* fall-through */
                case 0:
                    break;
                default:
                    assert(0);
                }
                cursor += numBytes;
            }

            if (debug) {
                printf("%08x ", cursor - numBytes);
                for (int k = cursor - numBytes; k < cursor; k++)
                    printf("%02x ", data[k]);
                for (int k = numBytes; k < 4; k++)
                    printf("   ");

                unsigned long long v = s.tokenValues[i];

                switch (s.tokenTypes[i]) {
                case TOK_LABEL:
                    if (s.tokenComments[i].empty())
                        printf("label %s\n", labelNames[v].c_str());
                    else
                        printf("label %-24s %s\n", labelNames[v].c_str(), s.tokenComments[i].c_str());
                    break;
                case TOK_REF:
                    if (s.tokenComments[i].empty())
                        printf("ref %s\n", labelNames[v].c_str());
                    else
                        printf("ref %-26s %s\n", labelNames[v].c_str(), s.tokenComments[i].c_str());
                    break;
                case TOK_U8:
                    if (s.tokenComments[i].empty())
                        printf("u8 %llu\n", v);
                    else
                        printf("u8 %-27llu %s\n", v, s.tokenComments[i].c_str());
                    break;
                case TOK_U16:
                    if (s.tokenComments[i].empty())
                        printf("u16 %-26llu\n", v);
                    else
                        printf("u16 %-26llu %s\n", v, s.tokenComments[i].c_str());
                    break;
                case TOK_U32:
                    if (s.tokenComments[i].empty())
                        printf("u32 %-26llu\n", v);
                    else
                        printf("u32 %-26llu %s\n", v, s.tokenComments[i].c_str());
                    break;
                default:
                    assert(0);
                }
            }
        }
    }

    assert(cursor == int(data.size()));

    if (writeC) {
        for (auto &s : preText)
            fprintf(fileOut, "%s\n", s.c_str());

        fprintf(fileOut, "const char %s[%d] =\n\"", streams[0].name.c_str(), int(data.size()) + 1);

        cursor = 1;
        for (int i = 0; i < int(data.size()); i++) {
            auto d = data[i];
            if (cursor > 70) {
                fputc('\"', fileOut);
                fputc('\n', fileOut);
                cursor = 0;
            }
            if (cursor == 0) {
                fputc('\"', fileOut);
                cursor = 1;
            }
            if (d < 32 || d >= 127) {
                if (i + 1 < int(data.size()) && (data[i + 1] < '0' || '9' < data[i + 1]))
                    cursor += fprintf(fileOut, "\\%o", int(d));
                else
                    cursor += fprintf(fileOut, "\\%03o", int(d));
            } else if (d == '\"' || d == '\'' || d == '\\') {
                fputc('\\', fileOut);
                fputc(d, fileOut);
                cursor += 2;
            } else {
                fputc(d, fileOut);
                cursor++;
            }
        }

        fprintf(fileOut, "\";\n");

        for (auto &s : postText)
            fprintf(fileOut, "%s\n", s.c_str());
    } else {
        fwrite(data.data(), int(data.size()), 1, fileOut);
    }

    return 0;
}
<commit_msg>Improvements in bbasm<commit_after>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <assert.h>
#include <boost/program_options.hpp>
#include <iostream>
#include <map>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

enum TokenType : int8_t
{
    TOK_LABEL,
    TOK_REF,
    TOK_U8,
    TOK_U16,
    TOK_U32
};

struct Stream
{
    std::string name;
    std::vector<TokenType> tokenTypes;
    std::vector<uint32_t> tokenValues;
    std::vector<std::string> tokenComments;
};

Stream stringStream;
std::vector<Stream> streams;
std::map<std::string, int> streamIndex;
std::vector<int> streamStack;

std::vector<int> labels;
std::vector<std::string> labelNames;
std::map<std::string, int> labelIndex;

std::vector<std::string> preText, postText;

const char *skipWhitespace(const char *p)
{
    if (p == nullptr)
        return "";
    while (*p == ' ' || *p == '\t')
        p++;
    return p;
}

int main(int argc, char **argv)
{
    bool debug = false;
    bool verbose = false;
    bool bigEndian = false;
    bool writeC = false;
    char buffer[512];

    namespace po = boost::program_options;
    po::positional_options_description pos;
    po::options_description options("Allowed options");
    options.add_options()("help,h", "verbose output");
    options.add_options()("verbose,v", "verbose output");
    options.add_options()("debug,d", "debug output");
    options.add_options()("be,b", "big endian");
    options.add_options()("c,c", "write c strings");
    options.add_options()("files", po::value<std::vector<std::string>>(), "file parameters");
    pos.add("files", -1);

    po::variables_map vm;
    try {
        po::parsed_options parsed = po::command_line_parser(argc, argv).options(options).positional(pos).run();

        po::store(parsed, vm);

        po::notify(vm);
    } catch (std::exception &e) {
        std::cout << e.what() << "\n";
        return 1;
    }
    if (vm.count("help")) {
        std::cout << options;
        return 0;
    }
    if (vm.count("verbose"))
        verbose = true;
    if (vm.count("debug"))
        debug = true;
    if (vm.count("be"))
        bigEndian = true;
    if (vm.count("c"))
        writeC = true;

    if (vm.count("files") == 0) {
        printf("File parameters are mandatory\n");
        exit(-1);
    }
    std::vector<std::string> files = vm["files"].as<std::vector<std::string>>();
    if (files.size() != 2) {
        printf("Input and output parameters must be set\n");
        exit(-1);
    }

    FILE *fileIn = fopen(files.at(0).c_str(), "rt");
    assert(fileIn != nullptr);

    FILE *fileOut = fopen(files.at(1).c_str(), writeC ? "wt" : "wb");
    assert(fileOut != nullptr);

    while (fgets(buffer, 512, fileIn) != nullptr) {
        std::string cmd = strtok(buffer, " \t\r\n");

        if (cmd == "pre") {
            const char *p = skipWhitespace(strtok(nullptr, "\r\n"));
            preText.push_back(p);
            continue;
        }

        if (cmd == "post") {
            const char *p = skipWhitespace(strtok(nullptr, "\r\n"));
            postText.push_back(p);
            continue;
        }

        if (cmd == "push") {
            const char *p = strtok(nullptr, " \t\r\n");
            if (streamIndex.count(p) == 0) {
                streamIndex[p] = streams.size();
                streams.resize(streams.size() + 1);
                streams.back().name = p;
            }
            streamStack.push_back(streamIndex.at(p));
            continue;
        }

        if (cmd == "pop") {
            streamStack.pop_back();
            continue;
        }

        if (cmd == "label" || cmd == "ref") {
            const char *label = strtok(nullptr, " \t\r\n");
            const char *comment = skipWhitespace(strtok(nullptr, "\r\n"));
            Stream &s = streams.at(streamStack.back());
            if (labelIndex.count(label) == 0) {
                labelIndex[label] = labels.size();
                if (debug)
                    labelNames.push_back(label);
                labels.push_back(-1);
            }
            s.tokenTypes.push_back(cmd == "label" ? TOK_LABEL : TOK_REF);
            s.tokenValues.push_back(labelIndex.at(label));
            if (debug)
                s.tokenComments.push_back(comment);
            continue;
        }

        if (cmd == "u8" || cmd == "u16" || cmd == "u32") {
            const char *value = strtok(nullptr, " \t\r\n");
            const char *comment = skipWhitespace(strtok(nullptr, "\r\n"));
            Stream &s = streams.at(streamStack.back());
            s.tokenTypes.push_back(cmd == "u8" ? TOK_U8 : cmd == "u16" ? TOK_U16 : TOK_U32);
            s.tokenValues.push_back(atoll(value));
            if (debug)
                s.tokenComments.push_back(comment);
            continue;
        }

        if (cmd == "str") {
            const char *value = skipWhitespace(strtok(nullptr, "\r\n"));
            assert(*value != 0);
            char *end = strchr((char *)value + 1, *value);
            assert(end != nullptr);
            *end = 0;
            value += 1;
            const char *comment = skipWhitespace(strtok(end+1, "\r\n"));
            std::string label = std::string("str:") + value;
            Stream &s = streams.at(streamStack.back());
            if (labelIndex.count(label) == 0) {
                labelIndex[label] = labels.size();
                if (debug)
                    labelNames.push_back(label);
                labels.push_back(-1);
            }
            s.tokenTypes.push_back(TOK_REF);
            s.tokenValues.push_back(labelIndex.at(label));
            if (debug)
                s.tokenComments.push_back(comment);
            stringStream.tokenTypes.push_back(TOK_LABEL);
            stringStream.tokenValues.push_back(labelIndex.at(label));
            stringStream.tokenComments.push_back("");
            while (1) {
                stringStream.tokenTypes.push_back(TOK_U8);
                stringStream.tokenValues.push_back(*value);
                if (debug) {
                    char char_comment[4] = {'\'', *value, '\'', 0};
                    if (*value < 32 || *value >= 127)
                        char_comment[0] = 0;
                    stringStream.tokenComments.push_back(char_comment);
                }
                if (*value == 0)
                    break;
                value++;
            }
            continue;
        }

        assert(0);
    }

    if (verbose) {
        printf("Constructed %d streams:\n", int(streams.size()));
        for (auto &s : streams)
            printf("    stream '%s' with %d tokens\n", s.name.c_str(), int(s.tokenTypes.size()));
    }

    assert(!streams.empty());
    assert(streamStack.empty());
    streams.push_back(Stream());
    streams.back().name = "strings";
    streams.back().tokenTypes.swap(stringStream.tokenTypes);
    streams.back().tokenValues.swap(stringStream.tokenValues);
    streams.back().tokenComments.swap(stringStream.tokenComments);

    int cursor = 0;
    for (auto &s : streams) {
        for (int i = 0; i < int(s.tokenTypes.size()); i++) {
            switch (s.tokenTypes[i]) {
            case TOK_LABEL:
                labels[s.tokenValues[i]] = cursor;
                break;
            case TOK_REF:
                cursor += 4;
                break;
            case TOK_U8:
                cursor += 1;
                break;
            case TOK_U16:
                assert(cursor % 2 == 0);
                cursor += 2;
                break;
            case TOK_U32:
                assert(cursor % 4 == 0);
                cursor += 4;
                break;
            default:
                assert(0);
            }
        }
    }

    if (verbose) {
        printf("resolved positions for %d labels.\n", int(labels.size()));
        printf("total data (including strings): %.2f MB\n", double(cursor) / (1024 * 1024));
    }

    std::vector<uint8_t> data(cursor);

    cursor = 0;
    for (auto &s : streams) {
        if (debug)
            printf("-- %s --\n", s.name.c_str());

        for (int i = 0; i < int(s.tokenTypes.size()); i++) {
            uint32_t value = s.tokenValues[i];
            int numBytes = 0;

            switch (s.tokenTypes[i]) {
            case TOK_LABEL:
                break;
            case TOK_REF:
                value = labels[value] - cursor;
                numBytes = 4;
                break;
            case TOK_U8:
                numBytes = 1;
                break;
            case TOK_U16:
                numBytes = 2;
                break;
            case TOK_U32:
                numBytes = 4;
                break;
            default:
                assert(0);
            }

            if (bigEndian) {
                switch (numBytes) {
                case 4:
                    data[cursor++] = value >> 24;
                    data[cursor++] = value >> 16;
                /* fall-through */
                case 2:
                    data[cursor++] = value >> 8;
                /* fall-through */
                case 1:
                    data[cursor++] = value;
                /* fall-through */
                case 0:
                    break;
                default:
                    assert(0);
                }
            } else {
                switch (numBytes) {
                case 4:
                    data[cursor + 3] = value >> 24;
                    data[cursor + 2] = value >> 16;
                /* fall-through */
                case 2:
                    data[cursor + 1] = value >> 8;
                /* fall-through */
                case 1:
                    data[cursor] = value;
                /* fall-through */
                case 0:
                    break;
                default:
                    assert(0);
                }
                cursor += numBytes;
            }

            if (debug) {
                printf("%08x ", cursor - numBytes);
                for (int k = cursor - numBytes; k < cursor; k++)
                    printf("%02x ", data[k]);
                for (int k = numBytes; k < 4; k++)
                    printf("   ");

                unsigned long long v = s.tokenValues[i];

                switch (s.tokenTypes[i]) {
                case TOK_LABEL:
                    if (s.tokenComments[i].empty())
                        printf("label %s\n", labelNames[v].c_str());
                    else
                        printf("label %-24s %s\n", labelNames[v].c_str(), s.tokenComments[i].c_str());
                    break;
                case TOK_REF:
                    if (s.tokenComments[i].empty())
                        printf("ref %s\n", labelNames[v].c_str());
                    else
                        printf("ref %-26s %s\n", labelNames[v].c_str(), s.tokenComments[i].c_str());
                    break;
                case TOK_U8:
                    if (s.tokenComments[i].empty())
                        printf("u8 %llu\n", v);
                    else
                        printf("u8 %-27llu %s\n", v, s.tokenComments[i].c_str());
                    break;
                case TOK_U16:
                    if (s.tokenComments[i].empty())
                        printf("u16 %-26llu\n", v);
                    else
                        printf("u16 %-26llu %s\n", v, s.tokenComments[i].c_str());
                    break;
                case TOK_U32:
                    if (s.tokenComments[i].empty())
                        printf("u32 %-26llu\n", v);
                    else
                        printf("u32 %-26llu %s\n", v, s.tokenComments[i].c_str());
                    break;
                default:
                    assert(0);
                }
            }
        }
    }

    assert(cursor == int(data.size()));

    if (writeC) {
        for (auto &s : preText)
            fprintf(fileOut, "%s\n", s.c_str());

        fprintf(fileOut, "const char %s[%d] =\n\"", streams[0].name.c_str(), int(data.size()) + 1);

        cursor = 1;
        for (int i = 0; i < int(data.size()); i++) {
            auto d = data[i];
            if (cursor > 70) {
                fputc('\"', fileOut);
                fputc('\n', fileOut);
                cursor = 0;
            }
            if (cursor == 0) {
                fputc('\"', fileOut);
                cursor = 1;
            }
            if (d < 32 || d >= 127) {
                if (i + 1 < int(data.size()) && (data[i + 1] < '0' || '9' < data[i + 1]))
                    cursor += fprintf(fileOut, "\\%o", int(d));
                else
                    cursor += fprintf(fileOut, "\\%03o", int(d));
            } else if (d == '\"' || d == '\'' || d == '\\') {
                fputc('\\', fileOut);
                fputc(d, fileOut);
                cursor += 2;
            } else {
                fputc(d, fileOut);
                cursor++;
            }
        }

        fprintf(fileOut, "\";\n");

        for (auto &s : postText)
            fprintf(fileOut, "%s\n", s.c_str());
    } else {
        fwrite(data.data(), int(data.size()), 1, fileOut);
    }

    return 0;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/
#ifndef GUARD_MIOPEN_DATATYPE_HPP
#define GUARD_MIOPEN_DATATYPE_HPP

#include <string>
#include <limits>

namespace miopen {

inline std::string GetDataType(miopenDataType_t type)
{
    std::string type_str;
    switch(type)
    {
    case miopenFloat: { type_str = "float";
    }
    break;
    case miopenHalf: { type_str = "half";
    }
    break;
    case miopenBFloat16: { type_str = "bfloat16";
    }
    break;
    case miopenInt8x4:
    case miopenInt8: { type_str = "int8_t";
    }
    break;
    case miopenInt32: { type_str = "int";
    }
    break;
    }
    return type_str;
}

inline std::size_t get_data_size(miopenDataType_t) { MIOPEN_THROW("not implemented"); }

inline std::size_t get_data_size(miopenIndexType_t index_type)
{
    switch(index_type)
    {
    case miopenIndexUint8: { return sizeof(uint8_t);
    }
    case miopenIndexUint16: { return sizeof(uint16_t);
    }
    case miopenIndexUint32: { return sizeof(uint32_t);
    }
    case miopenIndexUint64: { return sizeof(uint64_t);
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::size_t get_index_max(miopenIndexType_t index_type)
{
    // Basically, constants defined in cl.h, like CL_UCHAR_MAX, shall be used here.
    //    However, these are not available for HIP backend.
    switch(index_type)
    {
    case miopenIndexUint8: { return std::numeric_limits<uint8_t>::max();
    }
    case miopenIndexUint16: { return std::numeric_limits<uint16_t>::max();
    }
    case miopenIndexUint32: { return std::numeric_limits<uint32_t>::max();
    }
    case miopenIndexUint64: { return std::numeric_limits<uint64_t>::max();
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::string GetDataTypeKernelParams(miopenDataType_t type)
{
    // values for MIOPEN_USE_ macros
    int use_fp16               = 0;
    int use_fp32               = 0;
    int use_int8               = 0;
    int use_int8x4             = 0;
    int use_int32              = 0;
    int use_bfp16              = 0;
    const int use_rne_bfloat16 = MIOPEN_USE_RNE_BFLOAT16;

    switch(type)
    {
    case miopenHalf: use_fp16      = 1; break;
    case miopenFloat: use_fp32     = 1; break;
    case miopenInt8: use_int8      = 1; break;
    case miopenInt8x4: use_int8x4  = 1; break;
    case miopenBFloat16: use_bfp16 = 1; break;
    case miopenInt32: use_int32    = 1; break;
    default:
        MIOPEN_THROW("Only float, half, bfloat16, int8, int8x4 data type is supported.");
        break;
    }

    std::ostringstream ss;
    ss << " -DMIOPEN_USE_FP16=" << use_fp16;
    ss << " -DMIOPEN_USE_FP32=" << use_fp32;
    ss << " -DMIOPEN_USE_INT8=" << use_int8;
    ss << " -DMIOPEN_USE_INT8x4=" << use_int8x4;
    ss << " -DMIOPEN_USE_BFP16=" << use_bfp16;
    ss << " -DMIOPEN_USE_INT32=" << use_int32;
    ss << " -DMIOPEN_USE_RNE_BFLOAT16=" << use_rne_bfloat16;
    return ss.str();
}

} // namespace miopen

#endif // GUARD_MIOPEN_DATATYPE_HPP
<commit_msg>Added missing sstream include. (#1907)<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/
#ifndef GUARD_MIOPEN_DATATYPE_HPP
#define GUARD_MIOPEN_DATATYPE_HPP

#include <sstream>
#include <string>
#include <limits>

namespace miopen {

inline std::string GetDataType(miopenDataType_t type)
{
    std::string type_str;
    switch(type)
    {
    case miopenFloat: { type_str = "float";
    }
    break;
    case miopenHalf: { type_str = "half";
    }
    break;
    case miopenBFloat16: { type_str = "bfloat16";
    }
    break;
    case miopenInt8x4:
    case miopenInt8: { type_str = "int8_t";
    }
    break;
    case miopenInt32: { type_str = "int";
    }
    break;
    }
    return type_str;
}

inline std::size_t get_data_size(miopenDataType_t) { MIOPEN_THROW("not implemented"); }

inline std::size_t get_data_size(miopenIndexType_t index_type)
{
    switch(index_type)
    {
    case miopenIndexUint8: { return sizeof(uint8_t);
    }
    case miopenIndexUint16: { return sizeof(uint16_t);
    }
    case miopenIndexUint32: { return sizeof(uint32_t);
    }
    case miopenIndexUint64: { return sizeof(uint64_t);
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::size_t get_index_max(miopenIndexType_t index_type)
{
    // Basically, constants defined in cl.h, like CL_UCHAR_MAX, shall be used here.
    //    However, these are not available for HIP backend.
    switch(index_type)
    {
    case miopenIndexUint8: { return std::numeric_limits<uint8_t>::max();
    }
    case miopenIndexUint16: { return std::numeric_limits<uint16_t>::max();
    }
    case miopenIndexUint32: { return std::numeric_limits<uint32_t>::max();
    }
    case miopenIndexUint64: { return std::numeric_limits<uint64_t>::max();
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::string GetDataTypeKernelParams(miopenDataType_t type)
{
    // values for MIOPEN_USE_ macros
    int use_fp16               = 0;
    int use_fp32               = 0;
    int use_int8               = 0;
    int use_int8x4             = 0;
    int use_int32              = 0;
    int use_bfp16              = 0;
    const int use_rne_bfloat16 = MIOPEN_USE_RNE_BFLOAT16;

    switch(type)
    {
    case miopenHalf: use_fp16      = 1; break;
    case miopenFloat: use_fp32     = 1; break;
    case miopenInt8: use_int8      = 1; break;
    case miopenInt8x4: use_int8x4  = 1; break;
    case miopenBFloat16: use_bfp16 = 1; break;
    case miopenInt32: use_int32    = 1; break;
    default:
        MIOPEN_THROW("Only float, half, bfloat16, int8, int8x4 data type is supported.");
        break;
    }

    std::ostringstream ss;
    ss << " -DMIOPEN_USE_FP16=" << use_fp16;
    ss << " -DMIOPEN_USE_FP32=" << use_fp32;
    ss << " -DMIOPEN_USE_INT8=" << use_int8;
    ss << " -DMIOPEN_USE_INT8x4=" << use_int8x4;
    ss << " -DMIOPEN_USE_BFP16=" << use_bfp16;
    ss << " -DMIOPEN_USE_INT32=" << use_int32;
    ss << " -DMIOPEN_USE_RNE_BFLOAT16=" << use_rne_bfloat16;
    return ss.str();
}

} // namespace miopen

#endif // GUARD_MIOPEN_DATATYPE_HPP
<|endoftext|>


<commit_before>// $Id: error_vector.C,v 1.14 2006-12-08 16:50:04 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <limits>

// Local includes
#include "elem.h"
#include "error_vector.h"
#include "libmesh_logging.h"
#include "mesh_base.h"

#include "dof_map.h"
#include "equation_systems.h"
#include "explicit_system.h"
#include "mesh.h"
#include "numeric_vector.h"
#include "gmv_io.h"
#include "tecplot_io.h"

// ------------------------------------------------------------
// ErrorVector class member functions
ErrorVectorReal ErrorVector::minimum() const
{
  START_LOG ("minimum()", "ErrorVector");

  const unsigned int n = this->size();
  ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max();

  for (unsigned int i=0; i<n; i++)
    {
      // Only positive (or zero) values in the error vector
      assert((*this)[i] >= 0.);
      if (this->is_active_elem(i))
        min = std::min (min, (*this)[i]);
    }
  STOP_LOG ("minimum()", "ErrorVector");

  // ErrorVectors are for positive values
  assert (min >= 0.);

  return min;
}

Real ErrorVector::mean() const
{
  START_LOG ("mean()", "ErrorVector");

  const unsigned int n = this->size();

  Real mean  = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	mean += ( static_cast<Real>((*this)[i]) - mean ) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("mean()", "ErrorVector");

  return mean;
}

Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;

  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}

Real ErrorVector::median() const
{
  ErrorVector ev = (*this);

  return ev.median();
}

Real ErrorVector::variance(const Real mean) const
{
  const unsigned int n   = this->size();

  START_LOG ("variance()", "ErrorVector");

  Real variance = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	const Real delta = ( static_cast<Real>((*this)[i]) - mean );
	variance += (delta * delta - variance) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("variance()", "ErrorVector");

  return variance;
}

std::vector<unsigned int> ErrorVector::cut_below(Real cut) const
{
  START_LOG ("cut_below()", "ErrorVector");

  const unsigned int n = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] < cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_below()", "ErrorVector");

  return cut_indices;
}

std::vector<unsigned int> ErrorVector::cut_above(Real cut) const
{
  START_LOG ("cut_above()", "ErrorVector");

  const unsigned int n   = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] > cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_above()", "ErrorVector");

  return cut_indices;
}

bool ErrorVector::is_active_elem (unsigned int i) const
{
  assert (i < this->size());

  if (_mesh)
    {
      assert(_mesh->elem(i));
      return _mesh->elem(i)->active();
    }
  else
    return ((*this)[i] != 0.);
}

void ErrorVector::plot_error(std::string filename, Mesh& oldmesh) const
{
  Mesh mesh(oldmesh);
  EquationSystems temp_es (mesh);
  ExplicitSystem& error_system
    = temp_es.add_system<ExplicitSystem> ("Error");
  error_system.add_variable("e", CONSTANT, MONOMIAL);
  temp_es.init();

  const DofMap& error_dof_map = error_system.get_dof_map();

  MeshBase::const_element_iterator       el     =
    mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el =
    mesh.active_local_elements_end();
  std::vector<unsigned int> dof_indices;

  for ( ; el != end_el; ++el)
  {
    Elem* elem = *el;

    error_dof_map.dof_indices(elem, dof_indices);

    const unsigned int elem_id = elem->id();

    //0 for the monomial basis
    const unsigned int solution_index = dof_indices[0];
    // std::cout << "elem_number=" << elem_number << std::endl;
    assert (elem_id < (*this).size());
//  We may have zero error values in special circumstances
//    assert ((*this)[elem_id] > 0.);
    error_system.solution->set(solution_index, (*this)[elem_id]);
  }

  if (filename.rfind(".gmv") < filename.size())
    {
      GMVIO(mesh).write_equation_systems(filename,
                                         temp_es);
// write_discontinuous_gmv doesn't work on second order meshes??
// [RHS]
//      GMVIO(mesh).write_discontinuous_gmv(filename,
//                                          temp_es, false);
    }
  else if (filename.rfind(".plt") < filename.size())
    {
      TecplotIO (mesh).write_equation_systems
        (filename, temp_es);
    }
  else
    {
      here();
      std::cerr << "Warning: ErrorVector::plot_error currently only"
                << " supports .gmv and .plt output;" << std::endl;
      std::cerr << "Could not recognize filename: " << filename
                << std::endl;
    }
}

<commit_msg>Added workaround to make it always possible to plot error vectors discontinuously<commit_after>// $Id: error_vector.C,v 1.15 2006-12-12 23:29:12 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <limits>

// Local includes
#include "elem.h"
#include "error_vector.h"
#include "libmesh_logging.h"
#include "mesh_base.h"

#include "dof_map.h"
#include "equation_systems.h"
#include "explicit_system.h"
#include "mesh.h"
#include "numeric_vector.h"
#include "gmv_io.h"
#include "tecplot_io.h"

// ------------------------------------------------------------
// ErrorVector class member functions
ErrorVectorReal ErrorVector::minimum() const
{
  START_LOG ("minimum()", "ErrorVector");

  const unsigned int n = this->size();
  ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max();

  for (unsigned int i=0; i<n; i++)
    {
      // Only positive (or zero) values in the error vector
      assert((*this)[i] >= 0.);
      if (this->is_active_elem(i))
        min = std::min (min, (*this)[i]);
    }
  STOP_LOG ("minimum()", "ErrorVector");

  // ErrorVectors are for positive values
  assert (min >= 0.);

  return min;
}

Real ErrorVector::mean() const
{
  START_LOG ("mean()", "ErrorVector");

  const unsigned int n = this->size();

  Real mean  = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	mean += ( static_cast<Real>((*this)[i]) - mean ) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("mean()", "ErrorVector");

  return mean;
}

Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;

  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}

Real ErrorVector::median() const
{
  ErrorVector ev = (*this);

  return ev.median();
}

Real ErrorVector::variance(const Real mean) const
{
  const unsigned int n   = this->size();

  START_LOG ("variance()", "ErrorVector");

  Real variance = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	const Real delta = ( static_cast<Real>((*this)[i]) - mean );
	variance += (delta * delta - variance) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("variance()", "ErrorVector");

  return variance;
}

std::vector<unsigned int> ErrorVector::cut_below(Real cut) const
{
  START_LOG ("cut_below()", "ErrorVector");

  const unsigned int n = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] < cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_below()", "ErrorVector");

  return cut_indices;
}

std::vector<unsigned int> ErrorVector::cut_above(Real cut) const
{
  START_LOG ("cut_above()", "ErrorVector");

  const unsigned int n   = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] > cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_above()", "ErrorVector");

  return cut_indices;
}

bool ErrorVector::is_active_elem (unsigned int i) const
{
  assert (i < this->size());

  if (_mesh)
    {
      assert(_mesh->elem(i));
      return _mesh->elem(i)->active();
    }
  else
    return ((*this)[i] != 0.);
}

void ErrorVector::plot_error(std::string filename, Mesh& oldmesh) const
{
  Mesh mesh(oldmesh);
  mesh.all_first_order();
  EquationSystems temp_es (mesh);
  ExplicitSystem& error_system
    = temp_es.add_system<ExplicitSystem> ("Error");
  error_system.add_variable("e", CONSTANT, MONOMIAL);
  temp_es.init();

  const DofMap& error_dof_map = error_system.get_dof_map();

  MeshBase::const_element_iterator       el     =
    mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el =
    mesh.active_local_elements_end();
  std::vector<unsigned int> dof_indices;

  for ( ; el != end_el; ++el)
  {
    Elem* elem = *el;

    error_dof_map.dof_indices(elem, dof_indices);

    const unsigned int elem_id = elem->id();

    //0 for the monomial basis
    const unsigned int solution_index = dof_indices[0];
    // std::cout << "elem_number=" << elem_number << std::endl;
    assert (elem_id < (*this).size());
//  We may have zero error values in special circumstances
//    assert ((*this)[elem_id] > 0.);
    error_system.solution->set(solution_index, (*this)[elem_id]);
  }

  if (filename.rfind(".gmv") < filename.size())
    {
//      GMVIO(mesh).write_equation_systems(filename,
//                                         temp_es);
// write_discontinuous_gmv doesn't work on second order meshes??
// [RHS]
      GMVIO(mesh).write_discontinuous_gmv(filename,
                                          temp_es, false);
    }
  else if (filename.rfind(".plt") < filename.size())
    {
      TecplotIO (mesh).write_equation_systems
        (filename, temp_es);
    }
  else
    {
      here();
      std::cerr << "Warning: ErrorVector::plot_error currently only"
                << " supports .gmv and .plt output;" << std::endl;
      std::cerr << "Could not recognize filename: " << filename
                << std::endl;
    }
}

<|endoftext|>


<commit_before><commit_msg>[VecOps][NFC] Remove unused include<commit_after><|endoftext|>