<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "Exif.hxx"

Exif::Exif() :
    maOrientation(TOP_LEFT),
    mbExifPresent(false)
{}

Exif::~Exif()
{}

Orientation Exif::getOrientation() {
    return maOrientation;
}

void Exif::setOrientation(Orientation aOrientation) {
    maOrientation = aOrientation;
}

Orientation Exif::convertToOrientation(sal_Int32 value)
{
    switch(value) {
        case 1: return TOP_LEFT;
        case 2: return TOP_RIGHT;
        case 3: return BOTTOM_RIGHT;
        case 4: return BOTTOM_LEFT;
        case 5: return LEFT_TOP;
        case 6: return RIGHT_TOP;
        case 7: return RIGHT_BOTTOM;
        case 8: return LEFT_BOTTOM;
    }
    return TOP_LEFT;
}

sal_Int32 Exif::getRotation()
{
    switch(maOrientation) {
        case TOP_LEFT:
            return 0;
        case BOTTOM_RIGHT:
            return 1800;
        case RIGHT_TOP:
            return 2700;
        case LEFT_BOTTOM:
            return 900;
        default:
            break;
    }
    return 0;
}

bool Exif::hasExif()
{
    return mbExifPresent;
}

bool Exif::read(SvStream& rStream)
{
    sal_Int32 nStreamPosition = rStream.Tell();
    bool result = processJpeg(rStream, false);
    rStream.Seek( nStreamPosition );

    return result;
}

bool Exif::write(SvStream& rStream)
{
    sal_Int32 nStreamPosition = rStream.Tell();
    bool result = processJpeg(rStream, true);
    rStream.Seek( nStreamPosition );

    return result;
}

bool Exif::processJpeg(SvStream& rStream, bool bSetValue)
{
    sal_uInt16  aMagic16;
    sal_uInt16  aLength;

    rStream.Seek(STREAM_SEEK_TO_END);
    sal_uInt32 aSize = rStream.Tell();
    rStream.Seek(STREAM_SEEK_TO_BEGIN);

    rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
    rStream >> aMagic16;

    // Compare JPEG magic bytes
    if( 0xFFD8 != aMagic16 )
    {
        return false;
    }

    sal_uInt32 aPreviousPosition = STREAM_SEEK_TO_BEGIN;

    while(true)
    {
        sal_uInt8 aMarker = 0xD9;
        sal_Int32 aCount;

        for (aCount = 0; aCount < 7; aCount++)
        {
            rStream >> aMarker;
            if (aMarker != 0xFF)
            {
                break;
            }
            if (aCount >= 6)
            {
                return false;
            }
        }

        rStream >> aLength;

        if (aLength < 8)
        {
            return false;
        }

        if (aMarker == 0xE1)
        {
            return processExif(rStream, aLength, bSetValue);
        }
        else if (aMarker == 0xD9)
        {
            return false;
        }
        else
        {
            sal_uInt32 aCurrentPosition = rStream.SeekRel(aLength-1);
            if (aCurrentPosition == aPreviousPosition || aCurrentPosition > aSize)
            {
                return false;
            }
            aPreviousPosition = aCurrentPosition;
        }
    }
    return false;
}

bool Exif::processIFD(sal_uInt8* pExifData, sal_uInt16 aLength, sal_uInt16 aOffset, sal_uInt16 aNumberOfTags, bool bSetValue, bool bMoto)
{
    ExifIFD* ifd = NULL;

    while (aOffset <= aLength - 12 && aNumberOfTags > 0)
    {
        ifd = (ExifIFD*) &pExifData[aOffset];
        sal_uInt16 tag = ifd->tag;
        if (bMoto)
        {
            tag = OSL_SWAPWORD(ifd->tag);
        }

        if (tag == ORIENTATION)
        {
            if(bSetValue)
            {
                ifd->tag = ORIENTATION;
                ifd->type = 3;
                ifd->count = 1;
                ifd->offset = maOrientation;
                if (bMoto)
                {
                    ifd->tag = OSL_SWAPWORD(ifd->tag);
                    ifd->offset = OSL_SWAPWORD(ifd->offset);
                }
            }
            else
            {
                sal_uInt32 nIfdOffset = ifd->offset;
                if (bMoto)
                    nIfdOffset = OSL_SWAPWORD(ifd->offset);
                maOrientation = convertToOrientation(nIfdOffset);
            }
        }

        aNumberOfTags--;
        aOffset += 12;
    }
    return true;
}

bool Exif::processExif(SvStream& rStream, sal_uInt16 aSectionLength, bool bSetValue)
{
    sal_uInt32  aMagic32;
    sal_uInt16  aMagic16;

    rStream >> aMagic32;
    rStream >> aMagic16;

    // Compare EXIF magic bytes
    if( 0x45786966 != aMagic32 || 0x0000 != aMagic16)
    {
        return false;
    }

    sal_uInt16 aLength = aSectionLength - 6; // Length = Section - Header

    sal_uInt8* aExifData = new sal_uInt8[aLength];
    sal_uInt32 aExifDataBeginPosition = rStream.Tell();

    rStream.Read(aExifData, aLength);

    // Exif detected
    mbExifPresent = true;

    TiffHeader* aTiffHeader = (TiffHeader*) &aExifData[0];

    if(!(
        (0x4949 == aTiffHeader->byteOrder && 0x2A00 != aTiffHeader->tagAlign ) || // Intel format
        ( 0x4D4D == aTiffHeader->byteOrder && 0x002A != aTiffHeader->tagAlign ) // Motorola format
        )
      )
    {
        delete[] aExifData;
        return false;
    }

    bool bMoto = true; // Motorola, big-endian by default

    if (aTiffHeader->byteOrder == 0x4949)
    {
        bMoto = false; // little-endian
    }

    sal_uInt16 aOffset = 0;
    aOffset = aTiffHeader->offset;
    if (bMoto)
    {
        aOffset = OSL_SWAPDWORD(aTiffHeader->offset);
    }

    sal_uInt16 aNumberOfTags = aExifData[aOffset];
    if (bMoto)
    {
        aNumberOfTags = ((aExifData[aOffset] << 8) | aExifData[aOffset+1]);
    }

    processIFD(aExifData, aLength, aOffset+2, aNumberOfTags, bSetValue, bMoto);

    if (bSetValue)
    {
        rStream.Seek(aExifDataBeginPosition);
        rStream.Write(aExifData, aLength);
    }

    delete[] aExifData;
    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>swap if the host endianness doesn't match the file formats<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "Exif.hxx"

Exif::Exif() :
    maOrientation(TOP_LEFT),
    mbExifPresent(false)
{}

Exif::~Exif()
{}

Orientation Exif::getOrientation() {
    return maOrientation;
}

void Exif::setOrientation(Orientation aOrientation) {
    maOrientation = aOrientation;
}

Orientation Exif::convertToOrientation(sal_Int32 value)
{
    switch(value) {
        case 1: return TOP_LEFT;
        case 2: return TOP_RIGHT;
        case 3: return BOTTOM_RIGHT;
        case 4: return BOTTOM_LEFT;
        case 5: return LEFT_TOP;
        case 6: return RIGHT_TOP;
        case 7: return RIGHT_BOTTOM;
        case 8: return LEFT_BOTTOM;
    }
    return TOP_LEFT;
}

sal_Int32 Exif::getRotation()
{
    switch(maOrientation) {
        case TOP_LEFT:
            return 0;
        case BOTTOM_RIGHT:
            return 1800;
        case RIGHT_TOP:
            return 2700;
        case LEFT_BOTTOM:
            return 900;
        default:
            break;
    }
    return 0;
}

bool Exif::hasExif()
{
    return mbExifPresent;
}

bool Exif::read(SvStream& rStream)
{
    sal_Int32 nStreamPosition = rStream.Tell();
    bool result = processJpeg(rStream, false);
    rStream.Seek( nStreamPosition );

    return result;
}

bool Exif::write(SvStream& rStream)
{
    sal_Int32 nStreamPosition = rStream.Tell();
    bool result = processJpeg(rStream, true);
    rStream.Seek( nStreamPosition );

    return result;
}

bool Exif::processJpeg(SvStream& rStream, bool bSetValue)
{
    sal_uInt16  aMagic16;
    sal_uInt16  aLength;

    rStream.Seek(STREAM_SEEK_TO_END);
    sal_uInt32 aSize = rStream.Tell();
    rStream.Seek(STREAM_SEEK_TO_BEGIN);

    rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
    rStream >> aMagic16;

    // Compare JPEG magic bytes
    if( 0xFFD8 != aMagic16 )
    {
        return false;
    }

    sal_uInt32 aPreviousPosition = STREAM_SEEK_TO_BEGIN;

    while(true)
    {
        sal_uInt8 aMarker = 0xD9;
        sal_Int32 aCount;

        for (aCount = 0; aCount < 7; aCount++)
        {
            rStream >> aMarker;
            if (aMarker != 0xFF)
            {
                break;
            }
            if (aCount >= 6)
            {
                return false;
            }
        }

        rStream >> aLength;

        if (aLength < 8)
        {
            return false;
        }

        if (aMarker == 0xE1)
        {
            return processExif(rStream, aLength, bSetValue);
        }
        else if (aMarker == 0xD9)
        {
            return false;
        }
        else
        {
            sal_uInt32 aCurrentPosition = rStream.SeekRel(aLength-1);
            if (aCurrentPosition == aPreviousPosition || aCurrentPosition > aSize)
            {
                return false;
            }
            aPreviousPosition = aCurrentPosition;
        }
    }
    return false;
}

bool Exif::processIFD(sal_uInt8* pExifData, sal_uInt16 aLength, sal_uInt16 aOffset, sal_uInt16 aNumberOfTags, bool bSetValue, bool bSwap)
{
    ExifIFD* ifd = NULL;

    while (aOffset <= aLength - 12 && aNumberOfTags > 0)
    {
        ifd = (ExifIFD*) &pExifData[aOffset];
        sal_uInt16 tag = ifd->tag;
        if (bSwap)
        {
            tag = OSL_SWAPWORD(ifd->tag);
        }

        if (tag == ORIENTATION)
        {
            if(bSetValue)
            {
                ifd->tag = ORIENTATION;
                ifd->type = 3;
                ifd->count = 1;
                ifd->offset = maOrientation;
                if (bSwap)
                {
                    ifd->tag = OSL_SWAPWORD(ifd->tag);
                    ifd->offset = OSL_SWAPWORD(ifd->offset);
                }
            }
            else
            {
                sal_uInt32 nIfdOffset = ifd->offset;
                if (bSwap)
                    nIfdOffset = OSL_SWAPWORD(ifd->offset);
                maOrientation = convertToOrientation(nIfdOffset);
            }
        }

        aNumberOfTags--;
        aOffset += 12;
    }
    return true;
}

bool Exif::processExif(SvStream& rStream, sal_uInt16 aSectionLength, bool bSetValue)
{
    sal_uInt32  aMagic32;
    sal_uInt16  aMagic16;

    rStream >> aMagic32;
    rStream >> aMagic16;

    // Compare EXIF magic bytes
    if( 0x45786966 != aMagic32 || 0x0000 != aMagic16)
    {
        return false;
    }

    sal_uInt16 aLength = aSectionLength - 6; // Length = Section - Header

    sal_uInt8* aExifData = new sal_uInt8[aLength];
    sal_uInt32 aExifDataBeginPosition = rStream.Tell();

    rStream.Read(aExifData, aLength);

    // Exif detected
    mbExifPresent = true;

    TiffHeader* aTiffHeader = (TiffHeader*) &aExifData[0];

    bool bIntel = aTiffHeader->byteOrder == 0x4949;      //big-endian
    bool bMotorola = aTiffHeader->byteOrder == 0x4D4D;   //little-endian

    if (!bIntel && !bMotorola)
    {
        delete[] aExifData;
        return false;
    }

    bool bSwap = false;

#ifdef OSL_BIGENDIAN
    if (bIntel)
        bSwap = true;
#else
    if (bMotorola)
        bSwap = true;
#endif

    if (bSwap)
    {
        aTiffHeader->tagAlign = OSL_SWAPWORD(aTiffHeader->tagAlign);
        aTiffHeader->offset = OSL_SWAPDWORD(aTiffHeader->offset);
    }

    if (aTiffHeader->tagAlign != 0x002A) // TIFF tag
    {
        delete[] aExifData;
        return false;
    }

    sal_uInt16 aOffset = aTiffHeader->offset;

    sal_uInt16 aNumberOfTags = aExifData[aOffset];
    if (bSwap)
    {
        aNumberOfTags = ((aExifData[aOffset] << 8) | aExifData[aOffset+1]);
    }

    processIFD(aExifData, aLength, aOffset+2, aNumberOfTags, bSetValue, bSwap);

    if (bSetValue)
    {
        rStream.Seek(aExifDataBeginPosition);
        rStream.Write(aExifData, aLength);
    }

    delete[] aExifData;
    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005 by Andrei Alexandrescu
// Copyright (c) 2006 Peter Kmmel
// Code covered by the MIT License
//
// 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.
////////////////////////////////////////////////////////////////////////////////

// $Id$

#include <loki/SafeFormat.h>

namespace Loki
{

    // Crude writing method: writes straight to the file, unbuffered
    // Must be combined with a buffer to work properly (and efficiently)

    void write(std::FILE* f, const char* from, const char* to) {
        assert(from <= to);
        ::std::fwrite(from, 1, to - from, f);
    }

    // Write to a string

    void write(std::string& s, const char* from, const char* to) {
        assert(from <= to);
        const size_t addCount = to - from;
        if ( s.capacity() <= s.size() + addCount )
        {
            s.reserve( 2 * s.size() + addCount );
        }
        s.append(from, to);
    }

    // Write to a stream

    void write(std::ostream& f, const char* from, const char* to) {
        assert(from <= to);
        f.write(from, std::streamsize(to - from));
    }

    ////////////////////////////////////////////////////////////////////////////////
    // PrintfState class template
    // Holds the formatting state, and implements operator() to format stuff
    // Todo: make sure errors are handled properly
    ////////////////////////////////////////////////////////////////////////////////

    PrintfState<std::FILE*, char> Printf(const char* format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), stdout );
        PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( stdout );
        return printState2;
    }

    PrintfState<std::FILE*, char> Printf(const std::string& format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format.c_str() );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), stdout );
        PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( stdout );
        return printState2;
    }

    PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const char* format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), f );
        PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( f );
        return printState2;
    }

    PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const std::string& format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format.c_str() );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), f );
        PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( f );
        return printState2;
    }

    PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const char* format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format );
        f.write( buffer.c_str(), buffer.size() );
        PrintfState< ::std::ostream &, char > printState2 = state1.ChangeDevice< ::std::ostream & >( f );
        return printState2;
    }

    PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const std::string& format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format.c_str() );
        f.write( buffer.c_str(), buffer.size() );
        PrintfState< std::ostream &, char > printState2 = state1.ChangeDevice< ::std::ostream & >( f );
        return printState2;
    }

    PrintfState<std::string&, char> SPrintf(std::string& s, const char* format) {
        const size_t estimate = ::strlen( format ) + 128;
        s.reserve( estimate );
        return PrintfState<std::string&, char>(s, format);
    }

    PrintfState<std::string&, char> SPrintf(std::string& s, const std::string& format) {
        const size_t estimate = format.size() + 128;
        s.reserve( estimate );
        return PrintfState<std::string&, char>(s, format.c_str());
    }

} // end namespace Loki

<commit_msg>Added lines to make type of stdout clear to compiler.<commit_after>////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005 by Andrei Alexandrescu
// Copyright (c) 2006 Peter Kmmel
// Code covered by the MIT License
//
// 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.
////////////////////////////////////////////////////////////////////////////////

// $Id$

#include <loki/SafeFormat.h>

namespace Loki
{

    // Crude writing method: writes straight to the file, unbuffered
    // Must be combined with a buffer to work properly (and efficiently)

    void write(std::FILE* f, const char* from, const char* to) {
        assert(from <= to);
        ::std::fwrite(from, 1, to - from, f);
    }

    // Write to a string

    void write(std::string& s, const char* from, const char* to) {
        assert(from <= to);
        const size_t addCount = to - from;
        if ( s.capacity() <= s.size() + addCount )
        {
            s.reserve( 2 * s.size() + addCount );
        }
        s.append(from, to);
    }

    // Write to a stream

    void write(std::ostream& f, const char* from, const char* to) {
        assert(from <= to);
        f.write(from, std::streamsize(to - from));
    }

    ////////////////////////////////////////////////////////////////////////////////
    // PrintfState class template
    // Holds the formatting state, and implements operator() to format stuff
    // Todo: make sure errors are handled properly
    ////////////////////////////////////////////////////////////////////////////////

    PrintfState<std::FILE*, char> Printf(const char* format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), stdout );
        ::std::FILE * f = stdout;
        PrintfState< std::FILE *, char > printState2( state1.ChangeDevice( f ) );
        return printState2;
    }

    PrintfState<std::FILE*, char> Printf(const std::string& format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format.c_str() );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), stdout );
        ::std::FILE * f = stdout;
        PrintfState< std::FILE *, char > printState2( state1.ChangeDevice( f ) );
        return printState2;
    }

    PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const char* format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), f );
        PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( f );
        return printState2;
    }

    PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const std::string& format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format.c_str() );
        ::std::fwrite( buffer.c_str(), 1, buffer.size(), f );
        PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( f );
        return printState2;
    }

    PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const char* format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format );
        f.write( buffer.c_str(), buffer.size() );
        PrintfState< ::std::ostream &, char > printState2 = state1.ChangeDevice< ::std::ostream & >( f );
        return printState2;
    }

    PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const std::string& format) {
        ::std::string buffer;
        const PrintfState< ::std::string &, char > state1( buffer, format.c_str() );
        f.write( buffer.c_str(), buffer.size() );
        PrintfState< std::ostream &, char > printState2 = state1.ChangeDevice< ::std::ostream & >( f );
        return printState2;
    }

    PrintfState<std::string&, char> SPrintf(std::string& s, const char* format) {
        const size_t estimate = ::strlen( format ) + 128;
        s.reserve( estimate );
        return PrintfState<std::string&, char>(s, format);
    }

    PrintfState<std::string&, char> SPrintf(std::string& s, const std::string& format) {
        const size_t estimate = format.size() + 128;
        s.reserve( estimate );
        return PrintfState<std::string&, char>(s, format.c_str());
    }

} // end namespace Loki

<|endoftext|>


<commit_before>#ifndef VIENNAGRID_STORAGE_INSERTER_HPP
#define VIENNAGRID_STORAGE_INSERTER_HPP

/* =======================================================================
   Copyright (c) 2011-2013, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/storage/container_collection.hpp"
#include "viennagrid/storage/container_collection_element.hpp"

namespace viennagrid
{
    namespace storage
    {

        template<typename container_collection_type, typename change_counter_type, typename id_generator_type_>
        class physical_inserter_t
        {
        public:
            typedef container_collection_type physical_container_collection_type;
            typedef id_generator_type_ id_generator_type;

            physical_inserter_t() : collection(0), change_counter(0) {}
            physical_inserter_t(container_collection_type & _collection) : collection(&_collection), change_counter(0) {}
            physical_inserter_t(container_collection_type & _collection, id_generator_type id_generator_) : collection(&_collection), change_counter(0), id_generator(id_generator_) {}

            physical_inserter_t(container_collection_type & _collection, change_counter_type & change_counter_) :
                collection(&_collection), change_counter(&change_counter_) {}
            physical_inserter_t(container_collection_type & _collection, change_counter_type & change_counter_, id_generator_type id_generator_) :
                collection(&_collection), change_counter(&change_counter_), id_generator(id_generator_) {}

            void set_mesh_info(container_collection_type & _collection, change_counter_type & change_counter_)
            {
                collection = &_collection;
                change_counter = &change_counter_;
            }

            template<bool generate_id, bool call_callback, typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type,
                bool
            >
                    physical_insert( value_type element, inserter_type & inserter )
            {
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::iterator iterator;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type container_type;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_tag handle_tag;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type handle_type;

                container_type & container = viennagrid::storage::collection::get< value_type >( *collection );

                if ( generate_id && !container.is_present( element ) )
                    viennagrid::storage::id::set_id(element, id_generator( viennagrid::meta::tag<value_type>() ) );

                if (!generate_id)
                  id_generator.set_max_id( element.id() );

                std::pair<handle_type, bool> ret = container.insert( element );
                if (change_counter) ++(*change_counter);

                if (call_callback)
                    viennagrid::storage::container_collection_element::insert_callback(
                        container.dereference_handle(ret.first),
                        ret.second,
                        inserter);

                inserter.handle_insert( ret.first, viennagrid::meta::tag<value_type>() );

                return ret;
            }

            template<typename handle_type, typename value_type>
            void handle_insert( handle_type, viennagrid::meta::tag<value_type> ) {}

            template<bool generate_id, bool call_callback, typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type,
                bool
            >
                insert( const value_type & element )
            {
                return physical_insert<generate_id, call_callback>( element, *this );
            }

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type,
                bool
            >
                operator()( const value_type & element )
            {
                return insert<true, true>( element );
            }

            container_collection_type & get_physical_container_collection() { return *collection; }
            container_collection_type const & get_physical_container_collection() const { return *collection; }

            id_generator_type & get_id_generator() { return id_generator; }
            id_generator_type const & get_id_generator() const { return id_generator; }

        private:
            container_collection_type * collection;
            change_counter_type * change_counter;

            id_generator_type id_generator;
        };

        template<typename view_collection_type, typename change_counter_type, typename dependend_inserter_type>
        class recursive_inserter_t
        {
        public:
            recursive_inserter_t() : view_collection(0), change_counter(0), dependend_inserter(0) {}
            recursive_inserter_t(view_collection_type & collection_) : view_collection(&collection_), change_counter(0), dependend_inserter(0) {}

            recursive_inserter_t(view_collection_type & _collection, change_counter_type & change_counter_) :
                view_collection(&_collection), change_counter(&change_counter_) {}
            recursive_inserter_t(view_collection_type & _collection, dependend_inserter_type & dependend_inserter_) :
                view_collection(&_collection), change_counter(0), dependend_inserter(&dependend_inserter_) {}

            recursive_inserter_t(view_collection_type & _collection, change_counter_type & change_counter_, dependend_inserter_type & dependend_inserter_) :
                view_collection(&_collection), change_counter(&change_counter_), dependend_inserter(&dependend_inserter_) {}

//             recursive_inserter_t(view_collection_type & collection_, dependend_inserter_type & dependend_inserter_) :
//                view_collection(&collection_), dependend_inserter(&dependend_inserter_) {}

            void set_mesh_info(view_collection_type & _collection, change_counter_type & change_counter_)
            {
                view_collection = &_collection;
                change_counter = &change_counter_;
            }

            template<typename handle_type, typename value_type>
            void handle_insert( handle_type ref, viennagrid::meta::tag<value_type> )
            {
                viennagrid::storage::container_collection::handle_or_ignore( *view_collection, ref, viennagrid::meta::tag<value_type>() );

                dependend_inserter->handle_insert( ref, viennagrid::meta::tag<value_type>() );
                if (change_counter) ++(*change_counter);
            }

            typedef typename dependend_inserter_type::physical_container_collection_type physical_container_collection_type;

            template<bool generate_id, bool call_callback, typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type,
                bool
            >
                physical_insert( const value_type & element, inserter_type & inserter )
            {
                return dependend_inserter->template physical_insert<generate_id, call_callback>( element, inserter );
            }

            template<bool generate_id, bool call_callback, typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type,
                bool
            >
                insert( const value_type & element )
            {
                return physical_insert<generate_id, call_callback>( element, *this );
            }

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type,
                bool
            >
                operator()( const value_type & element )
            {
                return insert<true, true>( element );
            }

            physical_container_collection_type & get_physical_container_collection() { return dependend_inserter->get_physical_container_collection(); }
            physical_container_collection_type const & get_physical_container_collection() const { return dependend_inserter->get_physical_container_collection(); }

            typedef typename dependend_inserter_type::id_generator_type id_generator_type;
            id_generator_type & get_id_generator() { return dependend_inserter->get_id_generator(); }
            id_generator_type const & get_id_generator() const { return dependend_inserter->get_id_generator(); }

        private:
            view_collection_type * view_collection;
            change_counter_type * change_counter;

            dependend_inserter_type * dependend_inserter;
        };

        namespace inserter
        {
            template<typename dependend_inserter_type, typename container_collection_type, typename change_counter_type>
            recursive_inserter_t<container_collection_type, dependend_inserter_type, change_counter_type> get_recursive(
                  dependend_inserter_type const & inserter,
                  container_collection_type & collection,
                  change_counter_type & change_counter)
            {
                return recursive_inserter_t<container_collection_type, dependend_inserter_type, change_counter_type>(inserter, change_counter, collection);
            }
        }

        namespace result_of
        {
            template<typename container_collection_type, typename change_counter_type, typename dependend_inserter_type>
            struct recursive_inserter
            {
                typedef recursive_inserter_t<container_collection_type, change_counter_type, dependend_inserter_type> type;
            };

            template<typename container_collection_type, typename change_counter_type, typename id_generator_type>
            struct physical_inserter
            {
                typedef physical_inserter_t<container_collection_type, change_counter_type, id_generator_type> type;
            };
        }

    }
}

#endif
<commit_msg>Fix: Removed unused code which caused a compilation failure on GCC 4.4<commit_after>#ifndef VIENNAGRID_STORAGE_INSERTER_HPP
#define VIENNAGRID_STORAGE_INSERTER_HPP

/* =======================================================================
   Copyright (c) 2011-2013, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/storage/container_collection.hpp"
#include "viennagrid/storage/container_collection_element.hpp"

namespace viennagrid
{
    namespace storage
    {

        template<typename container_collection_type, typename change_counter_type, typename id_generator_type_>
        class physical_inserter_t
        {
        public:
            typedef container_collection_type physical_container_collection_type;
            typedef id_generator_type_ id_generator_type;

            physical_inserter_t() : collection(0), change_counter(0) {}
            physical_inserter_t(container_collection_type & _collection) : collection(&_collection), change_counter(0) {}
            physical_inserter_t(container_collection_type & _collection, id_generator_type id_generator_) : collection(&_collection), change_counter(0), id_generator(id_generator_) {}

            physical_inserter_t(container_collection_type & _collection, change_counter_type & change_counter_) :
                collection(&_collection), change_counter(&change_counter_) {}
            physical_inserter_t(container_collection_type & _collection, change_counter_type & change_counter_, id_generator_type id_generator_) :
                collection(&_collection), change_counter(&change_counter_), id_generator(id_generator_) {}

            void set_mesh_info(container_collection_type & _collection, change_counter_type & change_counter_)
            {
                collection = &_collection;
                change_counter = &change_counter_;
            }

            template<bool generate_id, bool call_callback, typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type,
                bool
            >
                    physical_insert( value_type element, inserter_type & inserter )
            {
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::iterator iterator;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type container_type;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_tag handle_tag;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type handle_type;

                container_type & container = viennagrid::storage::collection::get< value_type >( *collection );

                if ( generate_id && !container.is_present( element ) )
                    viennagrid::storage::id::set_id(element, id_generator( viennagrid::meta::tag<value_type>() ) );

                if (!generate_id)
                  id_generator.set_max_id( element.id() );

                std::pair<handle_type, bool> ret = container.insert( element );
                if (change_counter) ++(*change_counter);

                if (call_callback)
                    viennagrid::storage::container_collection_element::insert_callback(
                        container.dereference_handle(ret.first),
                        ret.second,
                        inserter);

                inserter.handle_insert( ret.first, viennagrid::meta::tag<value_type>() );

                return ret;
            }

            template<typename handle_type, typename value_type>
            void handle_insert( handle_type, viennagrid::meta::tag<value_type> ) {}

            template<bool generate_id, bool call_callback, typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type,
                bool
            >
                insert( const value_type & element )
            {
                return physical_insert<generate_id, call_callback>( element, *this );
            }

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::handle_type,
                bool
            >
                operator()( const value_type & element )
            {
                return insert<true, true>( element );
            }

            container_collection_type & get_physical_container_collection() { return *collection; }
            container_collection_type const & get_physical_container_collection() const { return *collection; }

            id_generator_type & get_id_generator() { return id_generator; }
            id_generator_type const & get_id_generator() const { return id_generator; }

        private:
            container_collection_type * collection;
            change_counter_type * change_counter;

            id_generator_type id_generator;
        };

        template<typename view_collection_type, typename change_counter_type, typename dependend_inserter_type>
        class recursive_inserter_t
        {
        public:
            recursive_inserter_t() : view_collection(0), change_counter(0), dependend_inserter(0) {}
            recursive_inserter_t(view_collection_type & collection_) : view_collection(&collection_), change_counter(0), dependend_inserter(0) {}

            recursive_inserter_t(view_collection_type & _collection, change_counter_type & change_counter_) :
                view_collection(&_collection), change_counter(&change_counter_) {}
            recursive_inserter_t(view_collection_type & _collection, dependend_inserter_type & dependend_inserter_) :
                view_collection(&_collection), change_counter(0), dependend_inserter(&dependend_inserter_) {}

            recursive_inserter_t(view_collection_type & _collection, change_counter_type & change_counter_, dependend_inserter_type & dependend_inserter_) :
                view_collection(&_collection), change_counter(&change_counter_), dependend_inserter(&dependend_inserter_) {}

//             recursive_inserter_t(view_collection_type & collection_, dependend_inserter_type & dependend_inserter_) :
//                view_collection(&collection_), dependend_inserter(&dependend_inserter_) {}

            void set_mesh_info(view_collection_type & _collection, change_counter_type & change_counter_)
            {
                view_collection = &_collection;
                change_counter = &change_counter_;
            }

            template<typename handle_type, typename value_type>
            void handle_insert( handle_type ref, viennagrid::meta::tag<value_type> )
            {
                viennagrid::storage::container_collection::handle_or_ignore( *view_collection, ref, viennagrid::meta::tag<value_type>() );

                dependend_inserter->handle_insert( ref, viennagrid::meta::tag<value_type>() );
                if (change_counter) ++(*change_counter);
            }

            typedef typename dependend_inserter_type::physical_container_collection_type physical_container_collection_type;

            template<bool generate_id, bool call_callback, typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type,
                bool
            >
                physical_insert( const value_type & element, inserter_type & inserter )
            {
                return dependend_inserter->template physical_insert<generate_id, call_callback>( element, inserter );
            }

            template<bool generate_id, bool call_callback, typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type,
                bool
            >
                insert( const value_type & element )
            {
                return physical_insert<generate_id, call_callback>( element, *this );
            }

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type,
                bool
            >
                operator()( const value_type & element )
            {
                return insert<true, true>( element );
            }

            physical_container_collection_type & get_physical_container_collection() { return dependend_inserter->get_physical_container_collection(); }
            physical_container_collection_type const & get_physical_container_collection() const { return dependend_inserter->get_physical_container_collection(); }

            typedef typename dependend_inserter_type::id_generator_type id_generator_type;
            id_generator_type & get_id_generator() { return dependend_inserter->get_id_generator(); }
            id_generator_type const & get_id_generator() const { return dependend_inserter->get_id_generator(); }

        private:
            view_collection_type * view_collection;
            change_counter_type * change_counter;

            dependend_inserter_type * dependend_inserter;
        };

        namespace result_of
        {
            template<typename container_collection_type, typename change_counter_type, typename dependend_inserter_type>
            struct recursive_inserter
            {
                typedef recursive_inserter_t<container_collection_type, change_counter_type, dependend_inserter_type> type;
            };

            template<typename container_collection_type, typename change_counter_type, typename id_generator_type>
            struct physical_inserter
            {
                typedef physical_inserter_t<container_collection_type, change_counter_type, id_generator_type> type;
            };
        }

    }
}

#endif
<|endoftext|>


<commit_before>#include <mi/SystemInfo.hpp>
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
#include <sstream>
//macros
//http://d.hatena.ne.jp/torutk/20090420/p1
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)// Win32 API
#ifndef	OS_WINDOWS
#define	OS_WINDOWS 1
#endif	//OS_WINDOWS
#elif defined (__CYGWIN__)
#ifndef OS_CYGWIN
#define OS_CYGWIN 1
#endif//OS_CYGWIN
#else
#ifndef OS_UNIX
#define OS_UNIX 1
#endif//OS_UNIX
#if defined (__APPLE__)
#ifndef OS_MAC
#define OS_MAC 1
#endif//OS_MAC
#elif defined(__linux__)
#ifndef OS_LINUX
#define OS_LINUX 1
#endif//OS_LINUX
#else
#ifndef OS_UNKNOWN
#define OS_UNKNOWN 1
#endif//OS_UNKNOWN
#endif//if defined __APPLE__ __linux
#endif//if defined

#if defined OS_WINDOWS
#include <windows.h>
#include <process.h>
#include <intrin.h>
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")
#elif defined OS_CYGWIN
#include <ctime>
#include <sys/types.h>
#include <sys/resource.h>
#else
#include <ctime>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
#endif//

namespace mi
{
	namespace sys {
#ifdef OS_WINDOWS
		std::string get_cpu_name ( void ) {
			char CPUString[0x20];
			char CPUBrandString[0x40];
			int CPUInfo[4] = { -1};
			__cpuid ( CPUInfo, 0 );
			unsigned int nIds = CPUInfo[0];
			memset ( CPUString, 0, sizeof ( CPUString ) );
			* ( ( int* ) CPUString ) = CPUInfo[1];
			* ( ( int* ) ( CPUString + 4 ) ) = CPUInfo[3];
			* ( ( int* ) ( CPUString + 8 ) ) = CPUInfo[2];
			// Calling __cpuid with 0x80000000 as the InfoType argument
			// gets the number of valid extended IDs.
			__cpuid ( CPUInfo, 0x80000000 );
			unsigned int nExIds = CPUInfo[0];
			memset ( CPUBrandString, 0, sizeof ( CPUBrandString ) );

			// Get the information associated with each extended ID.
			for ( unsigned int i = 0x80000000; i <= nExIds; ++i ) {
				__cpuid ( CPUInfo, i );

				// Interpret CPU brand string and cache information.
				if  ( i == 0x80000002 ) {
					memcpy ( CPUBrandString, CPUInfo, sizeof ( CPUInfo ) );
				} else if  ( i == 0x80000003 ) {
					memcpy ( CPUBrandString + 16, CPUInfo, sizeof ( CPUInfo ) );
				} else if  ( i == 0x80000004 ) {
					memcpy ( CPUBrandString + 32, CPUInfo, sizeof ( CPUInfo ) );
				}
			}
			std::string name;

			if  ( nExIds >= 0x80000004 ) {
				name = std::string ( CPUBrandString );
			}

			return name;
		}

		double get_memory_size() {
			MEMORYSTATUSEX stat;
			stat.dwLength = sizeof ( MEMORYSTATUSEX );

			if ( GlobalMemoryStatusEx ( &stat ) == 0 ) {
				std::cerr << "error while calling GlobalMemoryStatusEx()" << std::endl;
				return 0;
			}

			/// @note The retrun value is somewhat smaller than actual size.
			return static_cast<double> ( stat.ullTotalPhys / 1024.0 / 1024 / 1024 ) ;
		}

		int get_num_cores(){
			SYSTEM_INFO sysinfo;
			GetSystemInfo ( &sysinfo );
			return static_cast<int> ( sysinfo.dwNumberOfProcessors );
		}

		std::string get_date() {
			SYSTEMTIME systime;
			GetLocalTime ( &systime );
			std::stringstream ss;
			ss << systime.wYear << "-" << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wMonth << "-"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wDay << "-"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wHour << ":"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wMinute << ":"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wSecond;
			return ss.str();
		}
		double get_peak_memory( void ) {
			double peakMemory = 0;
			PROCESS_MEMORY_COUNTERS pmc = { 0 };
			HANDLE hProcess = OpenProcess ( PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId() );
			if ( GetProcessMemoryInfo ( hProcess, &pmc, sizeof ( pmc ) ) ) {
				peakMemory = static_cast<double> ( pmc.PeakWorkingSetSize );
			}

			CloseHandle ( hProcess );
			return peakMemory;
		}
#elif defined (OS_CYGWIN)
		std::string get_cpu_name_cygwin ( void ) {
			std::string name;
			return name;
		}

		double get_memory_size_cygwin() {
			return static_cast<double> ( 0 ) ;
		}

		int get_num_core_cygwin(){
			return 0;
		}

		std::string get_date_cygwin() {
			SYSTEMTIME systime;
			GetLocalTime ( &systime );
			std::stringstream ss;
			ss << systime.wYear << "-" << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wMonth << "-"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wDay << "-"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wHour << ":"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wMinute << ":"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wSecond;
			return ss.str();
		}
		double get_peak_memory_cygwin( void ) {
			double peakMemory = 0;
			///@todo Add something here
			return peakMemory;
		}
#else // unix like system
		static std::string get_sysctl        ( const std::string&  key ) {
			char result[256];
			size_t size = 256;
			sysctlbyname ( key.c_str(), &result[0], &size, NULL, 0 );
			return std::string ( result );
		}
		static double      get_sysctl_double ( const std::string&  key ) {
			uint64_t result;
			size_t size = sizeof ( result );
			sysctlbyname ( key.c_str(), &result, &size, NULL, 0 );
			return static_cast<double> ( result );
		}

		static int         get_sysctl_int    ( const std::string&  key ) {
			int result;
			size_t size = sizeof ( result );
			sysctlbyname ( key.c_str(), &result, &size, NULL, 0 );
			return result;
		}
		double get_peak_memory_unix( void ) {
			double peakMemory = 0;
			struct rusage rusage;
			getrusage ( RUSAGE_SELF, &rusage );                ///@todo The result somewhat strange on Mac.
			peakMemory = static_cast<double> ( rusage.ru_maxrss );
			return peakMemory;
		}
#endif
	}

        std::string
        SystemInfo::getCpuName ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_cpu_name();
#elif defined OS_CYGWIN
		return mi::sys::get_cpu_time_cygwin();
#else
                return mi::sys::get_sysctl ( "machdep.cpu.brand_string" );
#endif
        }

        double
        SystemInfo::getMemorySize ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_memory_size();
#elif defined OS_CYGWIN
		return mi::sys::get_memory_size();
#else
                return mi::sys::get_sysctl_double ( "hw.memsize" ) * 1.0 / 1024.0 / 1024.0 / 1024.0;
#endif
        }

        int
        SystemInfo::getNumCores ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_num_cores();
#elif defined OS_CYGWIN
		return mi::sys::get_num_cores_cygwin();
#else
                return mi::sys::get_sysctl_int ( "machdep.cpu.core_count" );
#endif
        }

        std::string
        SystemInfo::getDate ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_date();
#elif defined OS_CYGWIN
		return mi::sys::get_date_cygwin();
#else
                time_t rawtime = std::time ( NULL );
                struct tm* timeinfo = localtime ( &rawtime );
                char buffer [80];
                strftime ( buffer, 80, "%F-%X", timeinfo );
                std::string result ( buffer );
                return result;
#endif
        }
        void
        SystemInfo::print ( std::ostream&  out )
        {
                out << "date: " << mi::SystemInfo::getDate() << std::endl;
                out << "cpu: " << mi::SystemInfo::getCpuName() << "(" << mi::SystemInfo::getNumCores() << "cores)" << std::endl;
                out << "memory:" << mi::SystemInfo::getMemorySize() << "[gb]" << std::endl;
        }

        double
        SystemInfo::getPeakMemorySize ( const SIZE_TYPE type )
        {
                double peakMemory = 0;
#if defined(OS_WINDOWS)
		peakMemory = mi::sys::get_peak_memory();
#elif defined OS_CYGWIN
		peakMemory = mi::sys::get_peak_memory_cygwin();
#else // MAC or Linux
		peakMemory = mi::sys::get_peak_memory_unix();
#endif // WIN32

                if ( type == MI_GIGA_BYTE ) {
                        peakMemory /= 1024 * 1024 * 1024 ;
                } else if ( type == MI_MEGA_BYTE ) {
                        peakMemory /= 1024 * 1024;
                } else if ( type == MI_KILO_BYTE ) {
                        peakMemory /= 1024;
                }
                return  peakMemory;
        }
}

<commit_msg>Cygwin confirmed (incomplete)<commit_after>#include <mi/SystemInfo.hpp>
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
#include <sstream>
//macros
//http://d.hatena.ne.jp/torutk/20090420/p1
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)// Win32 API
#ifndef	OS_WINDOWS
#define	OS_WINDOWS 1
#endif	//OS_WINDOWS
#elif defined (__CYGWIN__)
#ifndef OS_CYGWIN
#define OS_CYGWIN 1
#endif//OS_CYGWIN
#else
#ifndef OS_UNIX
#define OS_UNIX 1
#endif//OS_UNIX
#if defined (__APPLE__)
#ifndef OS_MAC
#define OS_MAC 1
#endif//OS_MAC
#elif defined(__linux__)
#ifndef OS_LINUX
#define OS_LINUX 1
#endif//OS_LINUX
#else
#ifndef OS_UNKNOWN
#define OS_UNKNOWN 1
#endif//OS_UNKNOWN
#endif//if defined __APPLE__ __linux
#endif//if defined

#if defined OS_WINDOWS
#include <windows.h>
#include <process.h>
#include <intrin.h>
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")
#elif defined OS_CYGWIN
#include <ctime>
#include <sys/types.h>
#include <sys/resource.h>
#else
#include <ctime>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
#endif//

namespace mi
{
	namespace sys {
#if defined OS_WINDOWS
		std::string get_cpu_name ( void ) {
			char CPUString[0x20];
			char CPUBrandString[0x40];
			int CPUInfo[4] = { -1};
			__cpuid ( CPUInfo, 0 );
			unsigned int nIds = CPUInfo[0];
			memset ( CPUString, 0, sizeof ( CPUString ) );
			* ( ( int* ) CPUString ) = CPUInfo[1];
			* ( ( int* ) ( CPUString + 4 ) ) = CPUInfo[3];
			* ( ( int* ) ( CPUString + 8 ) ) = CPUInfo[2];
			// Calling __cpuid with 0x80000000 as the InfoType argument
			// gets the number of valid extended IDs.
			__cpuid ( CPUInfo, 0x80000000 );
			unsigned int nExIds = CPUInfo[0];
			memset ( CPUBrandString, 0, sizeof ( CPUBrandString ) );

			// Get the information associated with each extended ID.
			for ( unsigned int i = 0x80000000; i <= nExIds; ++i ) {
				__cpuid ( CPUInfo, i );

				// Interpret CPU brand string and cache information.
				if  ( i == 0x80000002 ) {
					memcpy ( CPUBrandString, CPUInfo, sizeof ( CPUInfo ) );
				} else if  ( i == 0x80000003 ) {
					memcpy ( CPUBrandString + 16, CPUInfo, sizeof ( CPUInfo ) );
				} else if  ( i == 0x80000004 ) {
					memcpy ( CPUBrandString + 32, CPUInfo, sizeof ( CPUInfo ) );
				}
			}
			std::string name;

			if  ( nExIds >= 0x80000004 ) {
				name = std::string ( CPUBrandString );
			}

			return name;
		}

		double get_memory_size() {
			MEMORYSTATUSEX stat;
			stat.dwLength = sizeof ( MEMORYSTATUSEX );

			if ( GlobalMemoryStatusEx ( &stat ) == 0 ) {
				std::cerr << "error while calling GlobalMemoryStatusEx()" << std::endl;
				return 0;
			}

			/// @note The retrun value is somewhat smaller than actual size.
			return static_cast<double> ( stat.ullTotalPhys / 1024.0 / 1024 / 1024 ) ;
		}

		int get_num_cores(){
			SYSTEM_INFO sysinfo;
			GetSystemInfo ( &sysinfo );
			return static_cast<int> ( sysinfo.dwNumberOfProcessors );
		}

		std::string get_date() {
			SYSTEMTIME systime;
			GetLocalTime ( &systime );
			std::stringstream ss;
			ss << systime.wYear << "-" << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wMonth << "-"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wDay << "-"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wHour << ":"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wMinute << ":"
			   << std::setw ( 2 ) << std::setfill ( '0' ) << systime.wSecond;
			return ss.str();
		}
		double get_peak_memory( void ) {
			double peakMemory = 0;
			PROCESS_MEMORY_COUNTERS pmc = { 0 };
			HANDLE hProcess = OpenProcess ( PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId() );
			if ( GetProcessMemoryInfo ( hProcess, &pmc, sizeof ( pmc ) ) ) {
				peakMemory = static_cast<double> ( pmc.PeakWorkingSetSize );
			}

			CloseHandle ( hProcess );
			return peakMemory;
		}
#elif defined (OS_CYGWIN)
		std::string get_cpu_name_cygwin ( void ) {
			std::string name;
			return name;
		}

		double get_memory_size_cygwin() {
			return static_cast<double> ( 0 ) ;
		}

		int get_num_cores_cygwin(){
			return 0;
		}

		std::string get_date_cygwin() {
			return std::string();
		}
		double get_peak_memory_cygwin( void ) {
			double peakMemory = 0;
			///@todo Add something here
			return peakMemory;
		}
#else // unix like system
		static std::string get_sysctl        ( const std::string&  key ) {
			char result[256];
			size_t size = 256;
			sysctlbyname ( key.c_str(), &result[0], &size, NULL, 0 );
			return std::string ( result );
		}
		static double      get_sysctl_double ( const std::string&  key ) {
			uint64_t result;
			size_t size = sizeof ( result );
			sysctlbyname ( key.c_str(), &result, &size, NULL, 0 );
			return static_cast<double> ( result );
		}

		static int         get_sysctl_int    ( const std::string&  key ) {
			int result;
			size_t size = sizeof ( result );
			sysctlbyname ( key.c_str(), &result, &size, NULL, 0 );
			return result;
		}
		double get_peak_memory_unix( void ) {
			double peakMemory = 0;
			struct rusage rusage;
			getrusage ( RUSAGE_SELF, &rusage );                ///@todo The result somewhat strange on Mac.
			peakMemory = static_cast<double> ( rusage.ru_maxrss );
			return peakMemory;
		}
#endif
	}

        std::string
        SystemInfo::getCpuName ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_cpu_name();
#elif defined OS_CYGWIN
		return mi::sys::get_cpu_name_cygwin();
#else
                return mi::sys::get_sysctl ( "machdep.cpu.brand_string" );
#endif
        }

        double
        SystemInfo::getMemorySize ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_memory_size();
#elif defined OS_CYGWIN
		return mi::sys::get_memory_size_cygwin();
#else
                return mi::sys::get_sysctl_double ( "hw.memsize" ) * 1.0 / 1024.0 / 1024.0 / 1024.0;
#endif
        }

        int
        SystemInfo::getNumCores ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_num_cores();
#elif defined OS_CYGWIN
		return mi::sys::get_num_cores_cygwin();
#else
                return mi::sys::get_sysctl_int ( "machdep.cpu.core_count" );
#endif
        }

        std::string
        SystemInfo::getDate ( void )
        {
#ifdef OS_WINDOWS
		return mi::sys::get_date();
#else
                time_t rawtime = std::time ( NULL );
                struct tm* timeinfo = localtime ( &rawtime );
                char buffer [80];
                strftime ( buffer, 80, "%F-%X", timeinfo );
                std::string result ( buffer );
                return result;
#endif
        }
        void
        SystemInfo::print ( std::ostream&  out )
        {
                out << "date: " << mi::SystemInfo::getDate() << std::endl;
                out << "cpu: " << mi::SystemInfo::getCpuName() << "(" << mi::SystemInfo::getNumCores() << "cores)" << std::endl;
                out << "memory:" << mi::SystemInfo::getMemorySize() << "[gb]" << std::endl;
        }

        double
        SystemInfo::getPeakMemorySize ( const SIZE_TYPE type )
        {
                double peakMemory = 0;
#if defined(OS_WINDOWS)
		peakMemory = mi::sys::get_peak_memory();
#elif defined OS_CYGWIN
		peakMemory = mi::sys::get_peak_memory_cygwin();
#else // MAC or Linux
		peakMemory = mi::sys::get_peak_memory_unix();
#endif // WIN32

                if ( type == MI_GIGA_BYTE ) {
                        peakMemory /= 1024 * 1024 * 1024 ;
                } else if ( type == MI_MEGA_BYTE ) {
                        peakMemory /= 1024 * 1024;
                } else if ( type == MI_KILO_BYTE ) {
                        peakMemory /= 1024;
                }
                return  peakMemory;
        }
}

<|endoftext|>


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

#include <vector>
#include <iostream>
#include <exception>
#include <algorithm>
#include <iomanip>
#include <ctime>
#include <random>

#include <configuration.hpp>

#include <ArgumentList.hpp>
#include <InitializeOpenCL.hpp>
#include <Kernel.hpp>
#include <Triad.hpp>
#include <utils.hpp>
#include <Timer.hpp>
#include <Stats.hpp>

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< inputDataType > * A, cl::Buffer * A_d, std::vector< inputDataType > * B, cl::Buffer * B_d, cl::Buffer * C_d);

int main(int argc, char * argv[]) {
  bool reInit = true;
  unsigned int nrIterations = 0;
  unsigned int samplingFactor = 100;
  unsigned int clPlatformID = 0;
  unsigned int clDeviceID = 0;
  unsigned int vectorSize = 0;
  unsigned int maxThreads = 0;
  unsigned int maxItems = 0;
  unsigned int maxVector = 0;
  unsigned int inputSize = 0;

  try {
    isa::utils::ArgumentList args(argc, argv);

    clPlatformID = args.getSwitchArgument< unsigned int >("-opencl_platform");
    clDeviceID = args.getSwitchArgument< unsigned int >("-opencl_device");
    if ( args.getSwitch("-sampling") ) {
      samplingFactor = args.getSwitchArgument< unsigned int >("-factor");
    }
    nrIterations = args.getSwitchArgument< unsigned int >("-iterations");
    vectorSize = args.getSwitchArgument< unsigned int >("-vector");
    maxThreads = args.getSwitchArgument< unsigned int >("-max_threads");
    maxItems = args.getSwitchArgument< unsigned int >("-max_items");
    maxVector = args.getSwitchArgument< unsigned int >("-max_vector");
    inputSize = args.getSwitchArgument< unsigned int >("-input_size");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << argv[0] << " -opencl_platform ... -opencl_device ... [-sampling -factor ...] -iterations ... -vector ... -max_threads ... -max_items ... -max_vector ... -input_size ... " << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  cl::Context clContext;
  std::vector< cl::Platform > * clPlatforms = new std::vector< cl::Platform >();
  std::vector< cl::Device > * clDevices = new std::vector< cl::Device >();
  std::vector< std::vector< cl::CommandQueue > > * clQueues = 0;

  // Allocate host memory
  std::vector< inputDataType > A(inputSize), B(inputSize), C(inputSize), C_control(inputSize);
  cl::Buffer A_d, B_d, C_d;

  srand(time(0));
  for ( unsigned int item = 0; item < A.size(); item++ ) {
    A[item] = rand() % factor;
    B[item] = rand() % factor;
  }
  std::fill(C.begin(), C.end(), factor);
  std::fill(C_control.begin(), C_control.end(), factor);

  // Run the control
  TuneBench::triad(A, B, C_control, static_cast< inputDataType >(factor));

  // Generate tuning configurations
  std::vector<TuneBench::TriadConf> configurations;
  for ( unsigned int threads = vectorSize; threads <= maxThreads; threads += vectorSize ) {
    for ( unsigned int items = 1; items <= maxItems; items++ ) {
      for ( unsigned int vector = 1; vector <= maxVector; vector++ ) {
        if ( inputSize % (threads * items * vector) != 0 ) {
          continue;
        } else if ( items * vector > maxItems ) {
          break;
        }
        TuneBench::TriadConf configuration;
        configuration.setNrThreadsD0(threads);
        configuration.setNrItemsD0(items);
        configuration.setVector(vector);
        configurations.push_back(configuration);
      }
    }
  }

  std::cout << std::fixed << std::endl;
  std::cout << "# inputSize *configuration* GB/s time stdDeviation COV" << std::endl << std::endl;

  for ( auto configuration = configurations.begin(); configuration != configurations.end(); ++configuration ) {
    if ( samplingFactor < 100 ) {
      // Sample the configurations
      std::random_device randomDevice;
      std::default_random_engine randomEngine(randomDevice());
      std::uniform_int_distribution<unsigned int> uniformDistribution(0, 99);
      unsigned int randomValue = uniformDistribution(randomEngine);

      if ( randomValue >= samplingFactor ) {
        continue;
      }
    }
    // Generate kernel
    double gbytes = isa::utils::giga(static_cast< uint64_t >(inputSize) * sizeof(inputDataType) * 3.0);
    cl::Event clEvent;
    cl::Kernel * kernel;
    isa::utils::Timer timer;
    std::string * code = TuneBench::getTriadOpenCL(*configuration, inputDataName, factor);

    if ( reInit ) {
      delete clQueues;
      clQueues = new std::vector< std::vector< cl::CommandQueue > >();
      isa::OpenCL::initializeOpenCL(clPlatformID, 1, clPlatforms, &clContext, clDevices, clQueues);
      try {
        initializeDeviceMemory(clContext, &(clQueues->at(clDeviceID)[0]), &A, &A_d, &B, &B_d, &C_d);
      } catch ( cl::Error & err ) {
        return -1;
      }
      reInit = false;
    }
    try {
      kernel = isa::OpenCL::compile("triad", *code, "-cl-mad-enable -Werror", clContext, clDevices->at(clDeviceID));
    } catch ( isa::OpenCL::OpenCLError & err ) {
      std::cerr << err.what() << std::endl;
      delete code;
      break;
    }
    delete code;

    cl::NDRange global(inputSize / ((*configuration).getNrItemsD0() * (*configuration).getVector()));
    cl::NDRange local((*configuration).getNrThreadsD0());

    kernel->setArg(0, A_d);
    kernel->setArg(1, B_d);
    kernel->setArg(2, C_d);

    try {
      // Warm-up run
      clQueues->at(clDeviceID)[0].finish();
      clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &clEvent);
      clEvent.wait();
      // Tuning runs
      for ( unsigned int iteration = 0; iteration < nrIterations; iteration++ ) {
        timer.start();
        clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &clEvent);
        clEvent.wait();
        timer.stop();
      }
      clQueues->at(clDeviceID)[0].enqueueReadBuffer(C_d, CL_TRUE, 0, C.size() * sizeof(inputDataType), reinterpret_cast< void * >(C.data()), 0, &clEvent);
      clEvent.wait();
    } catch ( cl::Error & err ) {
      std::cerr << "OpenCL kernel execution error (";
      std::cerr << (*configuration).print();
      std::cerr << "), (";
      std::cerr << isa::utils::toString(inputSize / (*configuration).getNrItemsD0()) << "): ";
      std::cerr << isa::utils::toString(err.err()) << std::endl;
      delete kernel;
      if ( err.err() == -4 || err.err() == -61 ) {
        return -1;
      }
      reInit = true;
      break;
    }
    delete kernel;

    bool error = false;
    for ( unsigned int item = 0; item < C.size(); item++ ) {
      if ( !isa::utils::same(C[item], C_control[item]) ) {
        std::cerr << "Output error (" << (*configuration).print() << ")." << std::endl;
        error = true;
        break;
      }
    }
    if ( error ) {
      continue;
    }

    std::cout << inputSize << " ";
    std::cout << (*configuration).print() << " ";
    std::cout << std::setprecision(3);
    std::cout << gbytes / timer.getAverageTime() << " ";
    std::cout << std::setprecision(6);
    std::cout << timer.getAverageTime() << " " << timer.getStandardDeviation() << " " << timer.getCoefficientOfVariation() << std::endl;
  }
  std::cout << std::endl;

  return 0;
}

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< inputDataType > * A, cl::Buffer * A_d, std::vector< inputDataType > * B, cl::Buffer * B_d, cl::Buffer * C_d) {
  try {
    *A_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, A->size() * sizeof(inputDataType), 0, 0);
    *B_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, B->size() * sizeof(inputDataType), 0, 0);
    *C_d = cl::Buffer(clContext, CL_MEM_WRITE_ONLY, A->size() * sizeof(inputDataType), 0, 0);
    clQueue->enqueueWriteBuffer(*A_d, CL_FALSE, 0, A->size() * sizeof(inputDataType), reinterpret_cast< void * >(A->data()));
    clQueue->enqueueWriteBuffer(*B_d, CL_FALSE, 0, B->size() * sizeof(inputDataType), reinterpret_cast< void * >(B->data()));
    clQueue->finish();
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error (memory initialization): " << isa::utils::toString(err.err()) << "." << std::endl;
    throw;
  }
}

<commit_msg>Using a more C++ way for sampling. Also now we get the same number of configurations for every execution.<commit_after>// Copyright 2016 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <vector>
#include <iostream>
#include <exception>
#include <algorithm>
#include <iomanip>
#include <random>

#include <configuration.hpp>

#include <ArgumentList.hpp>
#include <InitializeOpenCL.hpp>
#include <Kernel.hpp>
#include <Triad.hpp>
#include <utils.hpp>
#include <Timer.hpp>
#include <Stats.hpp>

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< inputDataType > * A, cl::Buffer * A_d, std::vector< inputDataType > * B, cl::Buffer * B_d, cl::Buffer * C_d);

int main(int argc, char * argv[]) {
  bool reInit = true;
  unsigned int nrIterations = 0;
  unsigned int samplingFactor = 100;
  unsigned int clPlatformID = 0;
  unsigned int clDeviceID = 0;
  unsigned int vectorSize = 0;
  unsigned int maxThreads = 0;
  unsigned int maxItems = 0;
  unsigned int maxVector = 0;
  unsigned int inputSize = 0;
  // Random number generation
  std::random_device randomDevice;
  std::default_random_engine randomEngine(randomDevice());
  std::uniform_int_distribution<unsigned int> uniformDistribution(0, factor);

  try {
    isa::utils::ArgumentList args(argc, argv);

    clPlatformID = args.getSwitchArgument< unsigned int >("-opencl_platform");
    clDeviceID = args.getSwitchArgument< unsigned int >("-opencl_device");
    if ( args.getSwitch("-sampling") ) {
      samplingFactor = args.getSwitchArgument< unsigned int >("-factor");
    }
    nrIterations = args.getSwitchArgument< unsigned int >("-iterations");
    vectorSize = args.getSwitchArgument< unsigned int >("-vector");
    maxThreads = args.getSwitchArgument< unsigned int >("-max_threads");
    maxItems = args.getSwitchArgument< unsigned int >("-max_items");
    maxVector = args.getSwitchArgument< unsigned int >("-max_vector");
    inputSize = args.getSwitchArgument< unsigned int >("-input_size");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << argv[0] << " -opencl_platform ... -opencl_device ... [-sampling -factor ...] -iterations ... -vector ... -max_threads ... -max_items ... -max_vector ... -input_size ... " << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  cl::Context clContext;
  std::vector< cl::Platform > * clPlatforms = new std::vector< cl::Platform >();
  std::vector< cl::Device > * clDevices = new std::vector< cl::Device >();
  std::vector< std::vector< cl::CommandQueue > > * clQueues = 0;

  // Allocate host memory
  std::vector< inputDataType > A(inputSize), B(inputSize), C(inputSize), C_control(inputSize);
  cl::Buffer A_d, B_d, C_d;

  std::generate(A.begin(), A.end(), uniformDistribution(randomEngine));
  std::generate(B.begin(), B.end(), uniformDistribution(randomEngine));
  std::fill(C.begin(), C.end(), factor);
  std::fill(C_control.begin(), C_control.end(), factor);

  // Run the control
  TuneBench::triad(A, B, C_control, static_cast< inputDataType >(factor));

  // Generate tuning configurations
  std::vector<TuneBench::TriadConf> configurations;
  for ( unsigned int threads = vectorSize; threads <= maxThreads; threads += vectorSize ) {
    for ( unsigned int items = 1; items <= maxItems; items++ ) {
      for ( unsigned int vector = 1; vector <= maxVector; vector++ ) {
        if ( inputSize % (threads * items * vector) != 0 ) {
          continue;
        } else if ( items * vector > maxItems ) {
          break;
        }
        TuneBench::TriadConf configuration;
        configuration.setNrThreadsD0(threads);
        configuration.setNrItemsD0(items);
        configuration.setVector(vector);
        configurations.push_back(configuration);
      }
    }
  }
  if ( samplingFactor < 100 ) {
    unsigned int newSize = static_cast<unsigned int>((configurations.size() * samplingFactor) / 100.0);
    std::shuffle(configurations.begin(), configurations.end(), randomEngine);
    configuration.resize(newSize);
  }

  std::cout << std::fixed << std::endl;
  std::cout << "# inputSize *configuration* GB/s time stdDeviation COV" << std::endl << std::endl;

  for ( auto configuration = configurations.begin(); configuration != configurations.end(); ++configuration ) {
    // Generate kernel
    double gbytes = isa::utils::giga(static_cast< uint64_t >(inputSize) * sizeof(inputDataType) * 3.0);
    cl::Event clEvent;
    cl::Kernel * kernel;
    isa::utils::Timer timer;
    std::string * code = TuneBench::getTriadOpenCL(*configuration, inputDataName, factor);

    if ( reInit ) {
      delete clQueues;
      clQueues = new std::vector< std::vector< cl::CommandQueue > >();
      isa::OpenCL::initializeOpenCL(clPlatformID, 1, clPlatforms, &clContext, clDevices, clQueues);
      try {
        initializeDeviceMemory(clContext, &(clQueues->at(clDeviceID)[0]), &A, &A_d, &B, &B_d, &C_d);
      } catch ( cl::Error & err ) {
        return -1;
      }
      reInit = false;
    }
    try {
      kernel = isa::OpenCL::compile("triad", *code, "-cl-mad-enable -Werror", clContext, clDevices->at(clDeviceID));
    } catch ( isa::OpenCL::OpenCLError & err ) {
      std::cerr << err.what() << std::endl;
      delete code;
      break;
    }
    delete code;

    cl::NDRange global(inputSize / ((*configuration).getNrItemsD0() * (*configuration).getVector()));
    cl::NDRange local((*configuration).getNrThreadsD0());

    kernel->setArg(0, A_d);
    kernel->setArg(1, B_d);
    kernel->setArg(2, C_d);

    try {
      // Warm-up run
      clQueues->at(clDeviceID)[0].finish();
      clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &clEvent);
      clEvent.wait();
      // Tuning runs
      for ( unsigned int iteration = 0; iteration < nrIterations; iteration++ ) {
        timer.start();
        clQueues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local, 0, &clEvent);
        clEvent.wait();
        timer.stop();
      }
      clQueues->at(clDeviceID)[0].enqueueReadBuffer(C_d, CL_TRUE, 0, C.size() * sizeof(inputDataType), reinterpret_cast< void * >(C.data()), 0, &clEvent);
      clEvent.wait();
    } catch ( cl::Error & err ) {
      std::cerr << "OpenCL kernel execution error (";
      std::cerr << (*configuration).print();
      std::cerr << "), (";
      std::cerr << isa::utils::toString(inputSize / (*configuration).getNrItemsD0()) << "): ";
      std::cerr << isa::utils::toString(err.err()) << std::endl;
      delete kernel;
      if ( err.err() == -4 || err.err() == -61 ) {
        return -1;
      }
      reInit = true;
      break;
    }
    delete kernel;

    bool error = false;
    for ( unsigned int item = 0; item < C.size(); item++ ) {
      if ( !isa::utils::same(C[item], C_control[item]) ) {
        std::cerr << "Output error (" << (*configuration).print() << ")." << std::endl;
        error = true;
        break;
      }
    }
    if ( error ) {
      continue;
    }

    std::cout << inputSize << " ";
    std::cout << (*configuration).print() << " ";
    std::cout << std::setprecision(3);
    std::cout << gbytes / timer.getAverageTime() << " ";
    std::cout << std::setprecision(6);
    std::cout << timer.getAverageTime() << " " << timer.getStandardDeviation() << " " << timer.getCoefficientOfVariation() << std::endl;
  }
  std::cout << std::endl;

  return 0;
}

void initializeDeviceMemory(cl::Context & clContext, cl::CommandQueue * clQueue, std::vector< inputDataType > * A, cl::Buffer * A_d, std::vector< inputDataType > * B, cl::Buffer * B_d, cl::Buffer * C_d) {
  try {
    *A_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, A->size() * sizeof(inputDataType), 0, 0);
    *B_d = cl::Buffer(clContext, CL_MEM_READ_ONLY, B->size() * sizeof(inputDataType), 0, 0);
    *C_d = cl::Buffer(clContext, CL_MEM_WRITE_ONLY, A->size() * sizeof(inputDataType), 0, 0);
    clQueue->enqueueWriteBuffer(*A_d, CL_FALSE, 0, A->size() * sizeof(inputDataType), reinterpret_cast< void * >(A->data()));
    clQueue->enqueueWriteBuffer(*B_d, CL_FALSE, 0, B->size() * sizeof(inputDataType), reinterpret_cast< void * >(B->data()));
    clQueue->finish();
  } catch ( cl::Error & err ) {
    std::cerr << "OpenCL error (memory initialization): " << isa::utils::toString(err.err()) << "." << std::endl;
    throw;
  }
}

<|endoftext|>


<commit_before>#pragma once

#include <raindance/Core/GUI/Window.hh>
#include <raindance/Core/GUI/HUD.hh>

#include <graphiti/Entities/MVC.hh>

class GLWindow : public Window
{
public:
    GLWindow(const char* title, const int width, const int height, Root* parent = NULL)
    : Window(title, width, height)
    {
        m_ActiveVisualizer = 0;

        m_HUD = new HUD(getViewport());
        m_HUD->bind(parent->context());

        m_Parent = parent;
    }

    virtual ~GLWindow()
    {
        SAFE_DELETE(m_HUD);
    }

    virtual void draw(Context* context)
    {
        auto visualizer = getActiveVisualizer();
        if (visualizer)
        {
            if (visualizer->view() != NULL)
                visualizer->view()->draw();
            if (visualizer->controller() != NULL)
                visualizer->controller()->draw();
        }

        m_HUD->draw(context);
    }

    virtual void idle(Context* context)
    {
        (void) context;

        m_HUD->idle();

        for (auto visualizer : m_Visualizers)
        {
            if (visualizer->view() != NULL)
                visualizer->view()->idle();
            if (visualizer->controller() != NULL)
                visualizer->controller()->idle();
        }
    }

     // ----- TODO : VisualizerManager -----

    inline void addVisualizer(EntityVisualizer* visualizer)
    {
        m_Visualizers.push_back(visualizer);
    }

    inline EntityVisualizer* getActiveVisualizer()
    {
        if (m_Visualizers.empty())
            return NULL;
        return m_Visualizers[m_ActiveVisualizer];
    }

    inline void selectNextVisualizer()
    {
        if (!m_Visualizers.empty())
            m_ActiveVisualizer = (m_ActiveVisualizer + 1) % m_Visualizers.size();
    }

    // ----- Window Events -----

    void onWindowSize(int width, int height) override
    {
        m_HUD->reshape(getViewport());

        for (auto visualizer : m_Visualizers)
            if (visualizer->controller())
                visualizer->controller()->onWindowSize(width, height);
    }

    void onSetFramebufferSize(int width, int height) override
    {
         m_HUD->reshape(getViewport());

        for (auto visualizer : m_Visualizers)
            if (visualizer->controller())
                visualizer->controller()->onSetFramebufferSize(width, height);
    }

    void onCursorPos(double xpos, double ypos) override
    {
        m_HUD->onCursorPos(xpos, ypos);

        auto visualizer = getActiveVisualizer();
        if (visualizer)
            visualizer->controller()->onCursorPos(xpos, ypos);
    }

    void onMouseButton(int button, int action, int mods) override
    {
        m_HUD->onMouseButton(button, action, mods);

        if (m_HUD->getWidgetPick() == NULL)
        {
            auto visualizer = getActiveVisualizer();
            if (visualizer)
                visualizer->controller()->onMouseButton(button, action, mods);
        }
    }

    void onKey(int key, int scancode, int action, int mods) override
    {
         m_HUD->onKey(key, scancode, action, mods);

        if (key == GLFW_KEY_N && action == 1 /* DOWN */)
            selectNextVisualizer();
        else if (key == GLFW_KEY_M && action == 1 /* DOWN */)
        {
            Geometry::getMetrics().dump();
            Geometry::getMetrics().reset();
            ResourceManager::getInstance().dump();
        }
        else
        {
            auto visualizer = getActiveVisualizer();
            if (visualizer)
                visualizer->controller()->onKey(key, scancode, action, mods);
        }
    }

    void onScroll(double xoffset, double yoffset) override
    {
        auto visualizer = getActiveVisualizer();
        if (visualizer)
            visualizer->controller()->onScroll(xoffset, yoffset);
    }

    inline HUD* hud() { return m_HUD; }

    inline Root* getParent() { return m_Parent; }

private:
    Root* m_Parent;
    std::vector<EntityVisualizer*> m_Visualizers;
    int m_ActiveVisualizer;
    HUD* m_HUD;
};
<commit_msg>Fixed resizing bug<commit_after>#pragma once

#include <raindance/Core/GUI/Window.hh>
#include <raindance/Core/GUI/HUD.hh>

#include <graphiti/Entities/MVC.hh>

class GLWindow : public Window
{
public:
    GLWindow(const char* title, const int width, const int height, Root* parent = NULL)
    : Window(title, width, height)
    {
        m_ActiveVisualizer = 0;

        m_HUD = new HUD(getViewport());
        m_HUD->bind(parent->context());

        m_Parent = parent;
    }

    virtual ~GLWindow()
    {
        SAFE_DELETE(m_HUD);
    }

    virtual void draw(Context* context)
    {
        auto visualizer = getActiveVisualizer();
        if (visualizer)
        {
            if (visualizer->view() != NULL)
                visualizer->view()->draw();
            if (visualizer->controller() != NULL)
                visualizer->controller()->draw();
        }

        m_HUD->draw(context);
    }

    virtual void idle(Context* context)
    {
        (void) context;

        m_HUD->idle();

        for (auto visualizer : m_Visualizers)
        {
            if (visualizer->view() != NULL)
                visualizer->view()->idle();
            if (visualizer->controller() != NULL)
                visualizer->controller()->idle();
        }
    }

     // ----- TODO : VisualizerManager -----

    inline void addVisualizer(EntityVisualizer* visualizer)
    {
        m_Visualizers.push_back(visualizer);
    }

    inline EntityVisualizer* getActiveVisualizer()
    {
        if (m_Visualizers.empty())
            return NULL;
        return m_Visualizers[m_ActiveVisualizer];
    }

    inline void selectNextVisualizer()
    {
        if (!m_Visualizers.empty())
            m_ActiveVisualizer = (m_ActiveVisualizer + 1) % m_Visualizers.size();
    }

    // ----- Window Events -----

    void onWindowSize(int width, int height) override
    {
        m_HUD->reshape(getViewport());

        for (auto visualizer : m_Visualizers)
            if (visualizer->controller())
                visualizer->controller()->onWindowSize(width, height);
    }

    void onSetFramebufferSize(int width, int height) override
    {
        glViewport(0, 0, width, height);

        m_HUD->reshape(getViewport());

        for (auto visualizer : m_Visualizers)
            if (visualizer->controller())
                visualizer->controller()->onSetFramebufferSize(width, height);
    }

    void onCursorPos(double xpos, double ypos) override
    {
        m_HUD->onCursorPos(xpos, ypos);

        auto visualizer = getActiveVisualizer();
        if (visualizer)
            visualizer->controller()->onCursorPos(xpos, ypos);
    }

    void onMouseButton(int button, int action, int mods) override
    {
        m_HUD->onMouseButton(button, action, mods);

        if (m_HUD->getWidgetPick() == NULL)
        {
            auto visualizer = getActiveVisualizer();
            if (visualizer)
                visualizer->controller()->onMouseButton(button, action, mods);
        }
    }

    void onKey(int key, int scancode, int action, int mods) override
    {
         m_HUD->onKey(key, scancode, action, mods);

        if (key == GLFW_KEY_N && action == 1 /* DOWN */)
            selectNextVisualizer();
        else if (key == GLFW_KEY_M && action == 1 /* DOWN */)
        {
            Geometry::getMetrics().dump();
            Geometry::getMetrics().reset();
            ResourceManager::getInstance().dump();
        }
        else
        {
            auto visualizer = getActiveVisualizer();
            if (visualizer)
                visualizer->controller()->onKey(key, scancode, action, mods);
        }
    }

    void onScroll(double xoffset, double yoffset) override
    {
        auto visualizer = getActiveVisualizer();
        if (visualizer)
            visualizer->controller()->onScroll(xoffset, yoffset);
    }

    inline HUD* hud() { return m_HUD; }

    inline Root* getParent() { return m_Parent; }

private:
    Root* m_Parent;
    std::vector<EntityVisualizer*> m_Visualizers;
    int m_ActiveVisualizer;
    HUD* m_HUD;
};
<|endoftext|>