<commit_before>/*
 * "Main.cpp"
 *
 * libcutie - Validate your opponent's data to detect cheating.
 * Copyright (c) 2016 Ammon Smith, Auggie Balquin, Bradley Cai
 *
 * libcutie 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 of the License, or
 * (at your option) any later version.
 *
 * libcutie is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with libcutie.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>

#include "Cutie.hpp"
//#include "Main.hpp"

enum Move {
	ROCK,
	PAPER,
	SCISSORS
};

enum SessionType {
	JOIN,
	CREATE,
	INVALID
};

// void getPlayerTurn(enum Move & temp);
// void outputScore(int myScore, int theirScore);
// void updateScore(bool winner, int & myScore, int & theirScore);

//
SessionType choice()
{
	int res = 0;

	std::cout << "Would you like to create a game or join a game?\n";
	std::cout << "1: Join\n2:Create\n\n ";
	std::cin >> res;

	std::cin >> res;

	std::cin.clear();
	std::cin.ignore(256, '\n');
	switch (res) {
		case 1:
			return JOIN;
		case 2:
			return CREATE;
		default:
			return INVALID;
	}
}

void getPlayerTurn(Move& temp)
{
	int choice = 1;
	std::cout << "Please enter your move!" << std::endl;
	std::cout << "1: ROCK" << std::endl;
	std::cout << "2: PAPER" << std::endl;
	std::cout << "3: SCISSORS!" << std::endl;
	std::cin >> choice;

	if (choice == 1) {
		temp = ROCK;
	}
	else if (choice == 2) {
		temp =  PAPER;
	}
	else {
		temp = SCISSORS;
	}
}

void outputScore(int myScore, int theirScore)
{
	std::cout << "YOU: " << myScore << std::endl;
	std::cout << "OPPONENT: " << theirScore << std:: endl;
}

void updateScore(bool winner, int & myScore, int & theirScore)
{
	if (winner) {
		myScore++;
		return;
	}
	theirScore++;
	return;
}

bool compareTurn(Move myTurn, Move theirTurn){
	bool winner = false;
	if (myTurn == theirTurn) {
		winner = false;
	}
	else if (myTurn == ROCK) {
		winner = (theirTurn == SCISSORS)? true : false;
	}
	else if (myTurn == PAPER) {
		winner = (theirTurn == ROCK)? true : false;
	}
	else {
		winner = (theirTurn == PAPER)? true : false;
	}
	return winner;
}

void outputEndgame(bool winner) {

	if (winner) {
		std::cout << "Victory!" << std::endl;
		std::cout << "YOU WON" << std::endl;
	}
	else {
		std::cout << "Defeat!" << std::endl;
		std::cout << "YOU LOST" << std::endl;
	}
}

int main(int argc, char *argv[])
{
	SessionType type;
	std::string ipAddress;
	int port;

	do {
		type = choice();
		if (type == JOIN) {
			std::cout << "What is the address you want to connect to? \n\n";
			std::cin >> ipAddress;
			std::cout << "On what port? \n\n";
			std::cin >> port;
			std::cout<< "Looking for opponent...\n";

			if (cutie::joinSession(ipAddress.c_str(), port)) {
				std::cout << "Opponent found!\n";
			}
			else {
				perror("Join failed: ");
				type = INVALID;
			}
		}
		else if (type == CREATE) {
			std::cout << "Waiting for opponent to connect...\n";

			if (cutie::createSession(port)) {
				std::cout << "Opponent found!\n";
			}
			else {
				perror("Create failed: ");
				type = INVALID;
			}
		}
	}
	while (type != INVALID);

	//cutie::connect();

	//if(cutie::connect(address, timeout)) {

		bool gameStarted = true;//gameInit(0,0);
		bool gameActive = true;

		if (gameStarted) {
			int myScore = 0;
			int theirScore = 0;
			bool winner = false;
			Move myTurn = ROCK;
			Move theirTurn = ROCK;

			while (gameActive) {

				//Outputs Score
				outputScore(myScore, theirScore);
				//Prompts User for turn
				getPlayerTurn(myTurn);

				//theirTurn =  cutie::doTurn(myTurn);
				winner =  compareTurn(myTurn,theirTurn);

				updateScore(winner, myScore, theirScore);

				if (myScore == 5 || theirScore == 5) {
					gameActive = false;
					if (myScore == 5) {
						winner = true;
					}
					else {
						winner = false;
					}
				}

			}

			outputEndgame(winner);

		}

	cutie::endSession();
    return 0;
}
<commit_msg>Fixed input bug<commit_after>/*
 * "Main.cpp"
 *
 * libcutie - Validate your opponent's data to detect cheating.
 * Copyright (c) 2016 Ammon Smith, Auggie Balquin, Bradley Cai
 *
 * libcutie 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 of the License, or
 * (at your option) any later version.
 *
 * libcutie is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with libcutie.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>

#include "Cutie.hpp"
//#include "Main.hpp"

enum Move {
	ROCK,
	PAPER,
	SCISSORS
};

enum SessionType {
	JOIN,
	CREATE,
	INVALID
};

// void getPlayerTurn(enum Move & temp);
// void outputScore(int myScore, int theirScore);
// void updateScore(bool winner, int & myScore, int & theirScore);

//
SessionType choice()
{
	int res = 0;

	std::cout << "Would you like to create a game or join a game?\n";
	std::cout << "1: Join\n2:Create\n\n ";
	std::cin >> res;

	std::cin.clear();
	std::cin.ignore(256, '\n');
	switch (res) {
		case 1:
			return JOIN;
		case 2:
			return CREATE;
		default:
			return INVALID;
	}
}

void getPlayerTurn(Move& temp)
{
	int choice = 1;
	std::cout << "Please enter your move!" << std::endl;
	std::cout << "1: ROCK" << std::endl;
	std::cout << "2: PAPER" << std::endl;
	std::cout << "3: SCISSORS!" << std::endl;
	std::cin >> choice;

	if (choice == 1) {
		temp = ROCK;
	}
	else if (choice == 2) {
		temp =  PAPER;
	}
	else {
		temp = SCISSORS;
	}
}

void outputScore(int myScore, int theirScore)
{
	std::cout << "YOU: " << myScore << std::endl;
	std::cout << "OPPONENT: " << theirScore << std:: endl;
}

void updateScore(bool winner, int & myScore, int & theirScore)
{
	if (winner) {
		myScore++;
		return;
	}
	theirScore++;
	return;
}

bool compareTurn(Move myTurn, Move theirTurn){
	bool winner = false;
	if (myTurn == theirTurn) {
		winner = false;
	}
	else if (myTurn == ROCK) {
		winner = (theirTurn == SCISSORS)? true : false;
	}
	else if (myTurn == PAPER) {
		winner = (theirTurn == ROCK)? true : false;
	}
	else {
		winner = (theirTurn == PAPER)? true : false;
	}
	return winner;
}

void outputEndgame(bool winner) {

	if (winner) {
		std::cout << "Victory!" << std::endl;
		std::cout << "YOU WON" << std::endl;
	}
	else {
		std::cout << "Defeat!" << std::endl;
		std::cout << "YOU LOST" << std::endl;
	}
}

int main(int argc, char *argv[])
{
	SessionType type;
	std::string ipAddress;
	int port;

	do {
		type = choice();
		if (type == JOIN) {
			std::cout << "What is the address you want to connect to? \n\n";
			std::cin >> ipAddress;
			std::cout << "On what port? \n\n";
			std::cin >> port;
			std::cout<< "Looking for opponent...\n";

			if (cutie::joinSession(ipAddress.c_str(), port)) {
				std::cout << "Opponent found!\n";
			}
			else {
				perror("Join failed: ");
				type = INVALID;
			}
		}
		else if (type == CREATE) {
			std::cout << "Waiting for opponent to connect...\n";

			if (cutie::createSession(port)) {
				std::cout << "Opponent found!\n";
			}
			else {
				perror("Create failed: ");
				type = INVALID;
			}
		}
	}
	while (type != INVALID);

	//cutie::connect();

	//if(cutie::connect(address, timeout)) {

		bool gameStarted = true;//gameInit(0,0);
		bool gameActive = true;

		if (gameStarted) {
			int myScore = 0;
			int theirScore = 0;
			bool winner = false;
			Move myTurn = ROCK;
			Move theirTurn = ROCK;

			while (gameActive) {

				//Outputs Score
				outputScore(myScore, theirScore);
				//Prompts User for turn
				getPlayerTurn(myTurn);

				//theirTurn =  cutie::doTurn(myTurn);
				winner =  compareTurn(myTurn,theirTurn);

				updateScore(winner, myScore, theirScore);

				if (myScore == 5 || theirScore == 5) {
					gameActive = false;
					if (myScore == 5) {
						winner = true;
					}
					else {
						winner = false;
					}
				}

			}

			outputEndgame(winner);

		}

	cutie::endSession();
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ScrollView.h"

#include <algorithm>
#include "FloatRect.h"
#include "IntRect.h"
#include <windows.h>

using namespace std;

namespace WebCore {

class ScrollView::ScrollViewPrivate {
public:
    ScrollViewPrivate()
        : hasStaticBackground(false)
        , suppressScrollBars(false)
        , vScrollBarMode(ScrollBarAuto)
        , hScrollBarMode(ScrollBarAuto)
    {
    }
    IntPoint scrollPoint;
    IntSize contentsSize;
    bool hasStaticBackground;
    bool suppressScrollBars;
    ScrollBarMode vScrollBarMode;
    ScrollBarMode hScrollBarMode;
};

ScrollView::ScrollView()
    : m_data(new ScrollViewPrivate())
{
}

ScrollView::~ScrollView()
{
    delete m_data;
}

void ScrollView::updateContents(const IntRect& updateRect, bool now)
{
    RECT dirtyRect = RECT(updateRect);
    InvalidateRect(windowHandle(), &dirtyRect, true);
    if (now)
        UpdateWindow(windowHandle());
}

int ScrollView::visibleWidth() const
{
    RECT bounds;
    GetClientRect(windowHandle(), &bounds);
    return (bounds.right - bounds.left);
}

int ScrollView::visibleHeight() const
{
    RECT bounds;
    GetClientRect(windowHandle(), &bounds);
    return (bounds.bottom - bounds.top);
}

FloatRect ScrollView::visibleContentRect() const
{
    RECT bounds;
    GetClientRect(windowHandle(), &bounds);
    FloatRect contentRect = bounds;
    contentRect.move(m_data->scrollPoint);
    return contentRect;
}

void ScrollView::setContentsPos(int newX, int newY)
{
    int dx = newX - contentsX();
    int dy = newY - contentsY();
    scrollBy(dx, dy);
}

void ScrollView::resizeContents(int w,int h)
{
    IntSize newSize(w,h);
    if (m_data->contentsSize != newSize) {
        m_data->contentsSize = newSize;
        updateScrollBars();
    }
}

int ScrollView::contentsX() const
{
    return scrollXOffset();
}

int ScrollView::contentsY() const
{
    return scrollYOffset();
}

int ScrollView::contentsWidth() const
{
    return m_data->contentsSize.width();
}

int ScrollView::contentsHeight() const
{
    return m_data->contentsSize.height();
}

void ScrollView::viewportToContents(int x1, int y1, int& x2, int& y2)
{
    POINT point = {x1, y1};
    MapWindowPoints(GetAncestor(windowHandle(), GA_ROOT), windowHandle(), &point, 1);
    x2 = point.x + scrollXOffset();
    y2 = point.y + scrollYOffset();
}

void ScrollView::contentsToViewport(int x1, int y1, int& x2, int& y2)
{
    POINT point = {x1 - scrollXOffset(), y1 - scrollYOffset()};
    MapWindowPoints(windowHandle(), GetAncestor(windowHandle(), GA_ROOT), &point, 1);
    x2 = point.x;
    y2 = point.y;
}

int ScrollView::scrollXOffset() const
{
    return m_data->scrollPoint.x();
}

int ScrollView::scrollYOffset() const
{
    return m_data->scrollPoint.y();
}

static inline int clampToRange(int value, int min, int max)
{
    return max(min(value, max), min);
}

IntPoint ScrollView::maximumScroll() const
{
    const IntSize& docSize = m_data->contentsSize;
    const IntPoint& scrollPoint = m_data->scrollPoint;
    return IntPoint(max(docSize.width() - scrollPoint.x(), 0), max(docSize.height() - scrollPoint.y(), 0));
}

void ScrollView::scrollBy(int dx, int dy)
{
    IntPoint scrollPoint = m_data->scrollPoint;
    const IntPoint& maxScroll = maximumScroll();
    int newX = max(0, min(scrollPoint.x() + dx, maxScroll.x()));
    int newY = max(0, min(scrollPoint.y() + dy, maxScroll.y()));

    IntPoint newPoint(newX, newY);
    if (newPoint != scrollPoint) {
        m_data->scrollPoint = newPoint;
        updateScrollBars();
        // ScrollBar updates can fail, so we check the final delta before scrolling
        IntPoint scrollDelta = m_data->scrollPoint - scrollPoint;
        if (scrollDelta == IntPoint(0,0))
            return;
        if (!m_data->hasStaticBackground)
            // FIXME: This could be made more efficient by passing a valid clip rect for only the document content.
            ScrollWindowEx(windowHandle(), -scrollDelta.x(), -scrollDelta.y(), 0, 0, 0, 0, SW_INVALIDATE);
        else
            InvalidateRect(windowHandle(), 0, true);
    }
}

WebCore::ScrollBarMode ScrollView::hScrollBarMode() const
{
    return m_data->hScrollBarMode;
}

WebCore::ScrollBarMode ScrollView::vScrollBarMode() const
{
    return m_data->vScrollBarMode;
}

void ScrollView::suppressScrollBars(bool suppressed, bool repaintOnSuppress)
{
    m_data->suppressScrollBars = suppressed;
    if (repaintOnSuppress)
        updateScrollBars();
}

void ScrollView::setHScrollBarMode(ScrollBarMode newMode)
{
    if (m_data->hScrollBarMode != newMode) {
        m_data->hScrollBarMode = newMode;
        updateScrollBars();
    }
}

void ScrollView::setVScrollBarMode(ScrollBarMode newMode)
{
    if (m_data->vScrollBarMode != newMode) {
        m_data->vScrollBarMode = newMode;
        updateScrollBars();
    }
}

void ScrollView::setScrollBarsMode(ScrollBarMode newMode)
{
    m_data->hScrollBarMode = m_data->vScrollBarMode = newMode;
    updateScrollBars();
}

void ScrollView::setStaticBackground(bool flag)
{
    m_data->hasStaticBackground = flag;
}

int ScrollView::updateScrollInfo(short type, int current, int max, int pageSize)
{
    SCROLLINFO si;
    si.cbSize = sizeof(si);
    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
    si.nMin   = 0;
    si.nMax   = max;
    si.nPage  = pageSize;
    si.nPos   = current;
    SetScrollInfo(windowHandle(), type, &si, TRUE);
    GetScrollInfo(windowHandle(), type, &si);
    return si.nPos;
}

void ScrollView::updateScrollBars()
{
    const IntPoint& maxScroll = maximumScroll();

    int xScroll = max(0, min(scrollXOffset(), maxScroll.x()));
    xScroll = updateScrollInfo(SB_HORZ, xScroll, contentsWidth()-1, width());
    m_data->scrollPoint.setX(xScroll);

    int yScroll = max(0, min(scrollYOffset(), maxScroll.y()));
    yScroll = updateScrollInfo(SB_VERT, yScroll, contentsHeight()-1, height());
    m_data->scrollPoint.setY(yScroll);

    if (m_data->hScrollBarMode != ScrollBarAuto || m_data->suppressScrollBars)
        ShowScrollBar(windowHandle(), SB_HORZ, (m_data->hScrollBarMode != ScrollBarAlwaysOff) && !m_data->suppressScrollBars);
    if (m_data->vScrollBarMode != ScrollBarAuto || m_data->suppressScrollBars)
        ShowScrollBar(windowHandle(), SB_VERT, (m_data->vScrollBarMode != ScrollBarAlwaysOff) && !m_data->suppressScrollBars);
}

}
<commit_msg>Add some ifdefed out paint flashing code for Win32 to the scroll view's updateContents method.<commit_after>/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ScrollView.h"

#include <algorithm>
#include "FloatRect.h"
#include "IntRect.h"
#include <windows.h>

using namespace std;

namespace WebCore {

class ScrollView::ScrollViewPrivate {
public:
    ScrollViewPrivate()
        : hasStaticBackground(false)
        , suppressScrollBars(false)
        , vScrollBarMode(ScrollBarAuto)
        , hScrollBarMode(ScrollBarAuto)
    {
    }
    IntPoint scrollPoint;
    IntSize contentsSize;
    bool hasStaticBackground;
    bool suppressScrollBars;
    ScrollBarMode vScrollBarMode;
    ScrollBarMode hScrollBarMode;
};

ScrollView::ScrollView()
    : m_data(new ScrollViewPrivate())
{
}

ScrollView::~ScrollView()
{
    delete m_data;
}

void ScrollView::updateContents(const IntRect& updateRect, bool now)
{
    IntRect adjustedDirtyRect(updateRect);
    adjustedDirtyRect.move(-m_data->scrollPoint.x(), -m_data->scrollPoint.y());

    RECT dirtyRect = RECT(adjustedDirtyRect);
#if PAINT_FLASHING_DEBUG
    HDC dc = GetDC(windowHandle());
    FillRect(dc, &dirtyRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
    ReleaseDC(windowHandle(), dc);
#endif

    InvalidateRect(windowHandle(), &dirtyRect, true);
    if (now)
        UpdateWindow(windowHandle());
}

int ScrollView::visibleWidth() const
{
    RECT bounds;
    GetClientRect(windowHandle(), &bounds);
    return (bounds.right - bounds.left);
}

int ScrollView::visibleHeight() const
{
    RECT bounds;
    GetClientRect(windowHandle(), &bounds);
    return (bounds.bottom - bounds.top);
}

FloatRect ScrollView::visibleContentRect() const
{
    RECT bounds;
    GetClientRect(windowHandle(), &bounds);
    FloatRect contentRect = bounds;
    contentRect.move(m_data->scrollPoint);
    return contentRect;
}

void ScrollView::setContentsPos(int newX, int newY)
{
    int dx = newX - contentsX();
    int dy = newY - contentsY();
    scrollBy(dx, dy);
}

void ScrollView::resizeContents(int w,int h)
{
    IntSize newSize(w,h);
    if (m_data->contentsSize != newSize) {
        m_data->contentsSize = newSize;
        updateScrollBars();
    }
}

int ScrollView::contentsX() const
{
    return scrollXOffset();
}

int ScrollView::contentsY() const
{
    return scrollYOffset();
}

int ScrollView::contentsWidth() const
{
    return m_data->contentsSize.width();
}

int ScrollView::contentsHeight() const
{
    return m_data->contentsSize.height();
}

void ScrollView::viewportToContents(int x1, int y1, int& x2, int& y2)
{
    POINT point = {x1, y1};
    MapWindowPoints(GetAncestor(windowHandle(), GA_ROOT), windowHandle(), &point, 1);
    x2 = point.x + scrollXOffset();
    y2 = point.y + scrollYOffset();
}

void ScrollView::contentsToViewport(int x1, int y1, int& x2, int& y2)
{
    POINT point = {x1 - scrollXOffset(), y1 - scrollYOffset()};
    MapWindowPoints(windowHandle(), GetAncestor(windowHandle(), GA_ROOT), &point, 1);
    x2 = point.x;
    y2 = point.y;
}

int ScrollView::scrollXOffset() const
{
    return m_data->scrollPoint.x();
}

int ScrollView::scrollYOffset() const
{
    return m_data->scrollPoint.y();
}

static inline int clampToRange(int value, int min, int max)
{
    return max(min(value, max), min);
}

IntPoint ScrollView::maximumScroll() const
{
    const IntSize& docSize = m_data->contentsSize;
    const IntPoint& scrollPoint = m_data->scrollPoint;
    return IntPoint(max(docSize.width() - scrollPoint.x(), 0), max(docSize.height() - scrollPoint.y(), 0));
}

void ScrollView::scrollBy(int dx, int dy)
{
    IntPoint scrollPoint = m_data->scrollPoint;
    const IntPoint& maxScroll = maximumScroll();
    int newX = max(0, min(scrollPoint.x() + dx, maxScroll.x()));
    int newY = max(0, min(scrollPoint.y() + dy, maxScroll.y()));

    IntPoint newPoint(newX, newY);
    if (newPoint != scrollPoint) {
        m_data->scrollPoint = newPoint;
        updateScrollBars();
        // ScrollBar updates can fail, so we check the final delta before scrolling
        IntPoint scrollDelta = m_data->scrollPoint - scrollPoint;
        if (scrollDelta == IntPoint(0,0))
            return;
        if (!m_data->hasStaticBackground)
            // FIXME: This could be made more efficient by passing a valid clip rect for only the document content.
            ScrollWindowEx(windowHandle(), -scrollDelta.x(), -scrollDelta.y(), 0, 0, 0, 0, SW_INVALIDATE);
        else
            InvalidateRect(windowHandle(), 0, true);
    }
}

WebCore::ScrollBarMode ScrollView::hScrollBarMode() const
{
    return m_data->hScrollBarMode;
}

WebCore::ScrollBarMode ScrollView::vScrollBarMode() const
{
    return m_data->vScrollBarMode;
}

void ScrollView::suppressScrollBars(bool suppressed, bool repaintOnSuppress)
{
    m_data->suppressScrollBars = suppressed;
    if (repaintOnSuppress)
        updateScrollBars();
}

void ScrollView::setHScrollBarMode(ScrollBarMode newMode)
{
    if (m_data->hScrollBarMode != newMode) {
        m_data->hScrollBarMode = newMode;
        updateScrollBars();
    }
}

void ScrollView::setVScrollBarMode(ScrollBarMode newMode)
{
    if (m_data->vScrollBarMode != newMode) {
        m_data->vScrollBarMode = newMode;
        updateScrollBars();
    }
}

void ScrollView::setScrollBarsMode(ScrollBarMode newMode)
{
    m_data->hScrollBarMode = m_data->vScrollBarMode = newMode;
    updateScrollBars();
}

void ScrollView::setStaticBackground(bool flag)
{
    m_data->hasStaticBackground = flag;
}

int ScrollView::updateScrollInfo(short type, int current, int max, int pageSize)
{
    SCROLLINFO si;
    si.cbSize = sizeof(si);
    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
    si.nMin   = 0;
    si.nMax   = max;
    si.nPage  = pageSize;
    si.nPos   = current;
    SetScrollInfo(windowHandle(), type, &si, TRUE);
    GetScrollInfo(windowHandle(), type, &si);
    return si.nPos;
}

void ScrollView::updateScrollBars()
{
    const IntPoint& maxScroll = maximumScroll();

    int xScroll = max(0, min(scrollXOffset(), maxScroll.x()));
    xScroll = updateScrollInfo(SB_HORZ, xScroll, contentsWidth()-1, width());
    m_data->scrollPoint.setX(xScroll);

    int yScroll = max(0, min(scrollYOffset(), maxScroll.y()));
    yScroll = updateScrollInfo(SB_VERT, yScroll, contentsHeight()-1, height());
    m_data->scrollPoint.setY(yScroll);

    if (m_data->hScrollBarMode != ScrollBarAuto || m_data->suppressScrollBars)
        ShowScrollBar(windowHandle(), SB_HORZ, (m_data->hScrollBarMode != ScrollBarAlwaysOff) && !m_data->suppressScrollBars);
    if (m_data->vScrollBarMode != ScrollBarAuto || m_data->suppressScrollBars)
        ShowScrollBar(windowHandle(), SB_VERT, (m_data->vScrollBarMode != ScrollBarAlwaysOff) && !m_data->suppressScrollBars);
}

}
<|endoftext|>


<commit_before>/*
 *  Haxe Setup
 *  Copyright (c)2006 Nicolas Cannasse
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

// this is a small program that do basic Haxe setup on Windows
#include <windows.h>

static void Set( HKEY k, const char *name, DWORD t, const char *data ) {
	RegSetValueEx(k,name,0,t,(const BYTE*)data,(DWORD)strlen(data)+1);
}

int WINAPI WinMain( HINSTANCE inst, HINSTANCE prev, LPSTR lpCmdLine, int nCmdShow ) {
	char path[MAX_PATH];
	*path = '"';
	GetModuleFileName(NULL,path+1,MAX_PATH);

	// register .hxml extension
	char *s = strrchr(path,'\\') + 1;
	strcpy(s,"haxe.exe\" -prompt \"%1\"");
	HKEY k;
	RegCreateKey(HKEY_CLASSES_ROOT,".hxml\\shell\\Compile\\command",&k);
	RegSetValueEx(k,NULL,0,REG_SZ,(const BYTE*)path,(DWORD)(strlen(path)+1));
	*s = 0;

	// add %HAXEPATH% to PATH and set HAXEPATH to current path
	DWORD ktype;
	DWORD ksize = 16000;
	char *kdata = new char[16000];
	memset(kdata,0,ksize);
	RegOpenKey(HKEY_CURRENT_USER,"Environment",&k);
	RegQueryValueEx(k,"PATH",NULL,&ktype,(LPBYTE)kdata,&ksize);
	if( strstr(kdata,"%HAXEPATH%") == NULL ) {
		char *s = kdata + strlen(kdata);
		strcpy(s,";%HAXEPATH%");
		Set(k,"PATH",REG_EXPAND_SZ,kdata);
	}
	if( strstr(kdata,"%NEKO_INSTPATH%") == NULL ) {
		char *s = kdata + strlen(kdata);
		strcpy(s,";%NEKO_INSTPATH%");
		Set(k,"PATH",REG_EXPAND_SZ,kdata);
	}
	Set(k,"HAXEPATH",REG_SZ,path + 1);
	s[-1] = 0;
	strcpy(strrchr(path,'\\'),"\\neko");
	Set(k,"NEKO_INSTPATH",REG_SZ,path+1);
	RegCloseKey(k);

	// inform running apps of env changes (W2K/NT systems only ?)
	DWORD unused;
	SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &unused );

	delete kdata;
	// register
	if( strcmp(lpCmdLine,"-silent") != 0 )
		MessageBox(NULL,"Setup completed, you can start using Haxe now","haxesetup",MB_OK | MB_ICONINFORMATION);
	return 0;
}
<commit_msg>[installer] experimenting with global path instead of local (solves issues on multi-user machines)<commit_after>/*
 *  Haxe Setup
 *  Copyright (c)2006 Nicolas Cannasse
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

// this is a small program that do basic Haxe setup on Windows
#include <windows.h>

static void Set( HKEY k, const char *name, DWORD t, const char *data ) {
	RegSetValueEx(k,name,0,t,(const BYTE*)data,(DWORD)strlen(data)+1);
}

int WINAPI WinMain( HINSTANCE inst, HINSTANCE prev, LPSTR lpCmdLine, int nCmdShow ) {
	char path[MAX_PATH];
	*path = '"';
	GetModuleFileName(NULL,path+1,MAX_PATH);

	// register .hxml extension
	char *s = strrchr(path,'\\') + 1;
	strcpy(s,"haxe.exe\" -prompt \"%1\"");
	HKEY k;
	RegCreateKey(HKEY_CLASSES_ROOT,".hxml\\shell\\Compile\\command",&k);
	RegSetValueEx(k,NULL,0,REG_SZ,(const BYTE*)path,(DWORD)(strlen(path)+1));
	*s = 0;

	// add %HAXEPATH% to PATH and set HAXEPATH to current path
	DWORD ktype;
	DWORD ksize = 16000;
	char *kdata = new char[16000];
	memset(kdata,0,ksize);
	RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",&k);
	RegQueryValueEx(k,"PATH",NULL,&ktype,(LPBYTE)kdata,&ksize);
	if( strstr(kdata,"%HAXEPATH%") == NULL ) {
		char *s = kdata + strlen(kdata);
		strcpy(s,";%HAXEPATH%");
		Set(k,"PATH",REG_EXPAND_SZ,kdata);
	}
	if( strstr(kdata,"%NEKO_INSTPATH%") == NULL ) {
		char *s = kdata + strlen(kdata);
		strcpy(s,";%NEKO_INSTPATH%");
		Set(k,"PATH",REG_EXPAND_SZ,kdata);
	}
	Set(k,"HAXEPATH",REG_SZ,path + 1);
	s[-1] = 0;
	strcpy(strrchr(path,'\\'),"\\neko");
	Set(k,"NEKO_INSTPATH",REG_SZ,path+1);
	RegCloseKey(k);

	// inform running apps of env changes (W2K/NT systems only ?)
	DWORD unused;
	SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &unused );

	delete kdata;
	// register
	if( strcmp(lpCmdLine,"-silent") != 0 )
		MessageBox(NULL,"Setup completed, you can start using Haxe now","haxesetup",MB_OK | MB_ICONINFORMATION);
	return 0;
}
<|endoftext|>


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

#import <Realm/RLMConstants.h>
#import <Realm/RLMOptionalBase.h>
#import <objc/runtime.h>

#import <realm/array.hpp>
#import <realm/binary_data.hpp>
#import <realm/datetime.hpp>
#import <realm/string_data.hpp>
#import <realm/util/file.hpp>

@class RLMObjectSchema;
@class RLMProperty;
@class RLMRealm;
@class RLMSchema;
@protocol RLMFastEnumerable;

NSException *RLMException(NSString *message, NSDictionary *userInfo = nil);
NSException *RLMException(std::exception const& exception);

NSError *RLMMakeError(RLMError code, std::exception const& exception);
NSError *RLMMakeError(RLMError code, const realm::util::File::AccessError&);
NSError *RLMMakeError(NSException *exception);

void RLMSetErrorOrThrow(NSError *error, NSError **outError);

// returns if the object can be inserted as the given type
BOOL RLMIsObjectValidForProperty(id obj, RLMProperty *prop);

// gets default values for the given schema (+defaultPropertyValues)
// merges with native property defaults if Swift class
NSDictionary *RLMDefaultValuesForObjectSchema(RLMObjectSchema *objectSchema);

NSArray *RLMCollectionValueForKey(id<RLMFastEnumerable> collection, NSString *key);

void RLMCollectionSetValueForKey(id<RLMFastEnumerable> collection, NSString *key, id value);

BOOL RLMIsDebuggerAttached();

// C version of isKindOfClass
static inline BOOL RLMIsKindOfClass(Class class1, Class class2) {
    while (class1) {
        if (class1 == class2) return YES;
        class1 = class_getSuperclass(class1);
    }
    return NO;
}

// Returns whether the class is an indirect descendant of RLMObjectBase
BOOL RLMIsObjectSubclass(Class klass);

template<typename T>
static inline T *RLMDynamicCast(__unsafe_unretained id obj) {
    if ([obj isKindOfClass:[T class]]) {
        return obj;
    }
    return nil;
}

template<typename T>
static inline T *RLMCoerceToNil(T *obj) {
    if (static_cast<id>(obj) == NSNull.null) {
        return nil;
    }
    else if (RLMIsKindOfClass(object_getClass(obj), [RLMOptionalBase class])) {
        return [static_cast<RLMOptionalBase *>(obj) underlyingValue];
    }
    return obj;
}

// Translate an rlmtype to a string representation
static inline NSString *RLMTypeToString(RLMPropertyType type) {
    switch (type) {
        case RLMPropertyTypeString:
            return @"string";
        case RLMPropertyTypeInt:
            return @"int";
        case RLMPropertyTypeBool:
            return @"bool";
        case RLMPropertyTypeDate:
            return @"date";
        case RLMPropertyTypeData:
            return @"data";
        case RLMPropertyTypeDouble:
            return @"double";
        case RLMPropertyTypeFloat:
            return @"float";
        case RLMPropertyTypeAny:
            return @"any";
        case RLMPropertyTypeObject:
            return @"object";
        case RLMPropertyTypeArray:
            return @"array";
    }
    return @"Unknown";
}

// String conversion utilities
static inline NSString * RLMStringDataToNSString(realm::StringData stringData) {
    static_assert(sizeof(NSUInteger) >= sizeof(size_t),
                  "Need runtime overflow check for size_t to NSUInteger conversion");
    if (stringData.is_null()) {
        return nil;
    }
    else {
        return [[NSString alloc] initWithBytes:stringData.data()
                                        length:stringData.size()
                                      encoding:NSUTF8StringEncoding];
    }
}

static inline realm::StringData RLMStringDataWithNSString(__unsafe_unretained NSString *const string) {
    static_assert(sizeof(size_t) >= sizeof(NSUInteger),
                  "Need runtime overflow check for NSUInteger to size_t conversion");
    return realm::StringData(string.UTF8String,
                               [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
}

// Binary convertion utilities
static inline NSData *RLMBinaryDataToNSData(realm::BinaryData binaryData) {
    return binaryData ? [NSData dataWithBytes:binaryData.data() length:binaryData.size()] : nil;
}

static inline realm::BinaryData RLMBinaryDataForNSData(__unsafe_unretained NSData *const data) {
    // this is necessary to ensure that the empty NSData isn't treated by core as the null realm::BinaryData
    // because data.bytes == 0 when data.length == 0
    // the casting bit ensures that we create a data with a non-null pointer
    auto bytes = static_cast<const char *>(data.bytes) ?: static_cast<char *>((__bridge void *)data);
    return realm::BinaryData(bytes, data.length);
}

// Date convertion utilities
static inline NSDate *RLMDateTimeToNSDate(realm::DateTime dateTime) {
    return [NSDate dateWithTimeIntervalSince1970:dateTime.get_datetime()];
}

static inline realm::DateTime RLMDateTimeForNSDate(__unsafe_unretained NSDate *const date) {
    int64_t time = date.timeIntervalSince1970;
    return realm::DateTime(time);
}

static inline NSUInteger RLMConvertNotFound(size_t index) {
    return index == realm::not_found ? NSNotFound : index;
}
<commit_msg>[RLMUtil] Make DateTime casting explicit<commit_after>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2014 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

#import <Realm/RLMConstants.h>
#import <Realm/RLMOptionalBase.h>
#import <objc/runtime.h>

#import <realm/array.hpp>
#import <realm/binary_data.hpp>
#import <realm/datetime.hpp>
#import <realm/string_data.hpp>
#import <realm/util/file.hpp>

@class RLMObjectSchema;
@class RLMProperty;
@class RLMRealm;
@class RLMSchema;
@protocol RLMFastEnumerable;

NSException *RLMException(NSString *message, NSDictionary *userInfo = nil);
NSException *RLMException(std::exception const& exception);

NSError *RLMMakeError(RLMError code, std::exception const& exception);
NSError *RLMMakeError(RLMError code, const realm::util::File::AccessError&);
NSError *RLMMakeError(NSException *exception);

void RLMSetErrorOrThrow(NSError *error, NSError **outError);

// returns if the object can be inserted as the given type
BOOL RLMIsObjectValidForProperty(id obj, RLMProperty *prop);

// gets default values for the given schema (+defaultPropertyValues)
// merges with native property defaults if Swift class
NSDictionary *RLMDefaultValuesForObjectSchema(RLMObjectSchema *objectSchema);

NSArray *RLMCollectionValueForKey(id<RLMFastEnumerable> collection, NSString *key);

void RLMCollectionSetValueForKey(id<RLMFastEnumerable> collection, NSString *key, id value);

BOOL RLMIsDebuggerAttached();

// C version of isKindOfClass
static inline BOOL RLMIsKindOfClass(Class class1, Class class2) {
    while (class1) {
        if (class1 == class2) return YES;
        class1 = class_getSuperclass(class1);
    }
    return NO;
}

// Returns whether the class is an indirect descendant of RLMObjectBase
BOOL RLMIsObjectSubclass(Class klass);

template<typename T>
static inline T *RLMDynamicCast(__unsafe_unretained id obj) {
    if ([obj isKindOfClass:[T class]]) {
        return obj;
    }
    return nil;
}

template<typename T>
static inline T *RLMCoerceToNil(T *obj) {
    if (static_cast<id>(obj) == NSNull.null) {
        return nil;
    }
    else if (RLMIsKindOfClass(object_getClass(obj), [RLMOptionalBase class])) {
        return [static_cast<RLMOptionalBase *>(obj) underlyingValue];
    }
    return obj;
}

// Translate an rlmtype to a string representation
static inline NSString *RLMTypeToString(RLMPropertyType type) {
    switch (type) {
        case RLMPropertyTypeString:
            return @"string";
        case RLMPropertyTypeInt:
            return @"int";
        case RLMPropertyTypeBool:
            return @"bool";
        case RLMPropertyTypeDate:
            return @"date";
        case RLMPropertyTypeData:
            return @"data";
        case RLMPropertyTypeDouble:
            return @"double";
        case RLMPropertyTypeFloat:
            return @"float";
        case RLMPropertyTypeAny:
            return @"any";
        case RLMPropertyTypeObject:
            return @"object";
        case RLMPropertyTypeArray:
            return @"array";
    }
    return @"Unknown";
}

// String conversion utilities
static inline NSString * RLMStringDataToNSString(realm::StringData stringData) {
    static_assert(sizeof(NSUInteger) >= sizeof(size_t),
                  "Need runtime overflow check for size_t to NSUInteger conversion");
    if (stringData.is_null()) {
        return nil;
    }
    else {
        return [[NSString alloc] initWithBytes:stringData.data()
                                        length:stringData.size()
                                      encoding:NSUTF8StringEncoding];
    }
}

static inline realm::StringData RLMStringDataWithNSString(__unsafe_unretained NSString *const string) {
    static_assert(sizeof(size_t) >= sizeof(NSUInteger),
                  "Need runtime overflow check for NSUInteger to size_t conversion");
    return realm::StringData(string.UTF8String,
                               [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
}

// Binary convertion utilities
static inline NSData *RLMBinaryDataToNSData(realm::BinaryData binaryData) {
    return binaryData ? [NSData dataWithBytes:binaryData.data() length:binaryData.size()] : nil;
}

static inline realm::BinaryData RLMBinaryDataForNSData(__unsafe_unretained NSData *const data) {
    // this is necessary to ensure that the empty NSData isn't treated by core as the null realm::BinaryData
    // because data.bytes == 0 when data.length == 0
    // the casting bit ensures that we create a data with a non-null pointer
    auto bytes = static_cast<const char *>(data.bytes) ?: static_cast<char *>((__bridge void *)data);
    return realm::BinaryData(bytes, data.length);
}

// Date convertion utilities
static inline NSDate *RLMDateTimeToNSDate(realm::DateTime dateTime) {
    auto timeInterval = static_cast<NSTimeInterval>(dateTime.get_datetime());
    return [NSDate dateWithTimeIntervalSince1970:timeInterval];
}

static inline realm::DateTime RLMDateTimeForNSDate(__unsafe_unretained NSDate *const date) {
    auto time = static_cast<int64_t>(date.timeIntervalSince1970);
    return realm::DateTime(time);
}

static inline NSUInteger RLMConvertNotFound(size_t index) {
    return index == realm::not_found ? NSNotFound : index;
}
<|endoftext|>


<commit_before>/*
** Copyright (c) 2015 Boise Center Aerospace Laboratory
**
** Author: Kyle Shannon <kyle at pobox dot com>
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pulsereader.hpp"

#define MAX(a, b) (a)>(b)?(a):(b)

/*
** This program opens and reads a pulse waves file, and outputs pertinent
** information for each in/out waveform.  The output should be consumable by
** matlab.
*/

void Usage() {
    printf("pw input.pls output_prefix\n");
    exit(1);
}

int main(int argc, char *argv[]) {
    PULSEreadOpener pOpener;
    PULSEreader *pReader;
    WAVESsampling *sampling;
    int i, j, k;
    char *szPulseOut, *szWaveOut, *szWaveIn, *szBase;
    FILE *pout;
    FILE *wout;
    FILE **wins;
    int nwins = 1;

    /* start with one incoming file */
    wins = (FILE**)malloc(sizeof(FILE*) * nwins);

    if(argc < 3) {
        Usage();
    }
    pOpener.set_file_name(argv[1]);
    pReader = pOpener.open();
    if(pReader == 0)
    {
        printf("Could not open file\n");
        return 1;
    }

    /* Open n files for output */
    szPulseOut = (char*)calloc(8192, 1);
    szWaveIn = (char*)calloc(8192, 1);
    szWaveOut = (char*)calloc(8192, 1);
    szBase = argv[2];
    sprintf(szPulseOut, "%s_PULSE.csv", szBase);
    sprintf(szWaveIn, "%s_WAVE_IN.txt", szBase);
    sprintf(szWaveOut, "%s_WAVE_OUT.txt", szBase);

    pout = fopen(szPulseOut, "w");
    fprintf(pout, "id,");
    fprintf(pout, "gps,");
    fprintf(pout, "anchor_x,anchor_y,anchor_z,");
    fprintf(pout, "target_x,target_y,target_z,");
    fprintf(pout, "first_return_x,first_return_y,first_return_z,");
    fprintf(pout, "last_return_x,last_return_y,last_return_z,");
    fprintf(pout, "edge,scan_dir,"); /* bit, written as uint8 */
    fprintf(pout, "facet,"); /* 2 bit, written as uint8 */
    fprintf(pout, "intensity\n"); /* uint8 */

    const char szPulseFormat[] = "%lld," \
                                 "%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%d,%d," \
                                 "%d," \
                                 "%d\n";

    for(i = 0; i < nwins; i++) {
        sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, i);
        wins[i] = fopen(szWaveIn, "w");
    }
    wout = fopen(szWaveOut, "w");

    double gpsTime;
    double xa, ya, za;
    double xt, yt, zt;
    double dx, dy, dz;
    double xf, yf, zf;
    double xl, yl, zl;
    unsigned char edge;
    unsigned char scan_dir;
    unsigned char intensity;
    long long p = 0;
    int rc = 0;
    int fi = 0;
    int maxCount = 0;
    int totalPoints = 0;
    int returnCount = 0;
    double progress = 0.;
    /*
    ** Scan the files for the longest pulse, we may need to pad some records
    ** with zeroes.
    */
    printf("Scanning pulses to attain max pulse length\n");
    while(pReader->read_pulse())
    {
        totalPoints++;
        if(pReader->read_waves()) {
            for(i = 0; i < pReader->waves->get_number_of_samplings(); i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    continue;
                }
                for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                    if(maxCount < sampling->get_number_of_samples()) {
                        maxCount = sampling->get_number_of_samples();
                    }
                }
            }
        }
    }
    printf("Using max count of %d for sample length\n", maxCount);
    printf("Total Points: %d\n", totalPoints);
    printf("Reported pulse count: %lld\n", pReader->p_count);
    pReader->seek(0);
    while(pReader->read_pulse()) {
        /* Write line to pulse file */
        gpsTime = pReader->pulse.T * pReader->header.t_scale_factor + pReader->header.t_offset;
        xa = pReader->pulse.anchor_X * pReader->header.x_scale_factor + pReader->header.x_offset;
        ya = pReader->pulse.anchor_X * pReader->header.y_scale_factor + pReader->header.y_offset;
        za = pReader->pulse.anchor_X * pReader->header.z_scale_factor + pReader->header.z_offset;
        xt = pReader->pulse.target_X * pReader->header.x_scale_factor + pReader->header.x_offset;
        yt = pReader->pulse.target_X * pReader->header.y_scale_factor + pReader->header.y_offset;
        zt = pReader->pulse.target_X * pReader->header.z_scale_factor + pReader->header.z_offset;
        dx = (xt - xa) / 1000;
        dy = (yt - ya) / 1000;
        dz = (zt - za) / 1000;
        xf = xa + pReader->pulse.first_returning_sample * dx;
        yf = ya + pReader->pulse.first_returning_sample * dy;
        zf = za + pReader->pulse.first_returning_sample * dz;
        xl = xa + pReader->pulse.last_returning_sample * dx;
        yl = ya + pReader->pulse.last_returning_sample * dy;
        zl = za + pReader->pulse.last_returning_sample * dz;

        edge = pReader->pulse.edge_of_scan_line;
        scan_dir = pReader->pulse.scan_direction;
        intensity = pReader->pulse.intensity;
        rc = fprintf(pout, szPulseFormat, p,
                                          gpsTime,
                                          xa, ya, za,
                                          xt, yt, zt,
                                          xf, yf, zf,
                                          xl, yl, zl,
                                          edge, scan_dir,
                                          pReader->pulse.mirror_facet,
                                          intensity);

        if(pReader->read_waves()) {
            returnCount = 0;
            for(i = 0; i < pReader->waves->get_number_of_samplings() && returnCount < 1; i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    fprintf(wout, "%lld ", p);
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        fi = 0;
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wout, "%u ", 0);
                            } else {
                                fprintf(wout, "%u ", sampling->get_sample(k));
                            }
                        }
                    }
                    fprintf(wout, "\n");
                } else if(sampling->get_type() == PULSEWAVES_RETURNING) {
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        /* Need new file? */
                        if(j >= nwins) {
                            wins = (FILE**)realloc(wins, sizeof(FILE*) * ++nwins);
                            sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, nwins-1);
                            wins[j] = fopen(szWaveIn, "w");
                        }
                        fprintf(wins[j], "%lld ", p);
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wins[j], "%u ", 0);
                            } else {
                                fprintf(wins[j], "%u ", sampling->get_sample(k));
                            }
                        }
                        fprintf(wins[j], "\n");
                        returnCount++;
                    }
                } else {
                    printf("Unknown type: %d\n", sampling->get_type());
                }
            }
        } else {
            /* No data??? */
            printf("NO DATA!\n");
        }
        p++;
        if(p % 1000 == 0) {
            progress = ((double)p / (double)totalPoints) * 100.;
            printf("\r%d%% done...", (int)progress);
        }
    }
    printf("\r100%% done.\n");

    free(szPulseOut);
    free(szWaveIn);
    free(szWaveOut);
    pReader->close();
    delete pReader;

    fclose(pout);
    fclose(wout);
    for(i = 0; i < nwins; i++) {
        fclose(wins[i]);
    }
    free(wins);
    printf("Created %d incoming wave files\n", nwins);
    printf("Total points processed: %lld\n", p);

    return 0;
}

<commit_msg>change X values to Y and Z<commit_after>/*
** Copyright (c) 2015 Boise Center Aerospace Laboratory
**
** Author: Kyle Shannon <kyle at pobox dot com>
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pulsereader.hpp"

#define MAX(a, b) (a)>(b)?(a):(b)

/*
** This program opens and reads a pulse waves file, and outputs pertinent
** information for each in/out waveform.  The output should be consumable by
** matlab.
*/

void Usage() {
    printf("pw input.pls output_prefix\n");
    exit(1);
}

int main(int argc, char *argv[]) {
    PULSEreadOpener pOpener;
    PULSEreader *pReader;
    WAVESsampling *sampling;
    int i, j, k;
    char *szPulseOut, *szWaveOut, *szWaveIn, *szBase;
    FILE *pout;
    FILE *wout;
    FILE **wins;
    int nwins = 1;

    /* start with one incoming file */
    wins = (FILE**)malloc(sizeof(FILE*) * nwins);

    if(argc < 3) {
        Usage();
    }
    pOpener.set_file_name(argv[1]);
    pReader = pOpener.open();
    if(pReader == 0)
    {
        printf("Could not open file\n");
        return 1;
    }

    /* Open n files for output */
    szPulseOut = (char*)calloc(8192, 1);
    szWaveIn = (char*)calloc(8192, 1);
    szWaveOut = (char*)calloc(8192, 1);
    szBase = argv[2];
    sprintf(szPulseOut, "%s_PULSE.csv", szBase);
    sprintf(szWaveIn, "%s_WAVE_IN.txt", szBase);
    sprintf(szWaveOut, "%s_WAVE_OUT.txt", szBase);

    pout = fopen(szPulseOut, "w");
    fprintf(pout, "id,");
    fprintf(pout, "gps,");
    fprintf(pout, "anchor_x,anchor_y,anchor_z,");
    fprintf(pout, "target_x,target_y,target_z,");
    fprintf(pout, "first_return_x,first_return_y,first_return_z,");
    fprintf(pout, "last_return_x,last_return_y,last_return_z,");
    fprintf(pout, "edge,scan_dir,"); /* bit, written as uint8 */
    fprintf(pout, "facet,"); /* 2 bit, written as uint8 */
    fprintf(pout, "intensity\n"); /* uint8 */

    const char szPulseFormat[] = "%lld," \
                                 "%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%d,%d," \
                                 "%d," \
                                 "%d\n";

    for(i = 0; i < nwins; i++) {
        sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, i);
        wins[i] = fopen(szWaveIn, "w");
    }
    wout = fopen(szWaveOut, "w");

    double gpsTime;
    double xa, ya, za;
    double xt, yt, zt;
    double dx, dy, dz;
    double xf, yf, zf;
    double xl, yl, zl;
    unsigned char edge;
    unsigned char scan_dir;
    unsigned char intensity;
    long long p = 0;
    int rc = 0;
    int fi = 0;
    int maxCount = 0;
    int totalPoints = 0;
    int returnCount = 0;
    double progress = 0.;
    /*
    ** Scan the files for the longest pulse, we may need to pad some records
    ** with zeroes.
    */
    printf("Scanning pulses to attain max pulse length\n");
    while(pReader->read_pulse())
    {
        totalPoints++;
        if(pReader->read_waves()) {
            for(i = 0; i < pReader->waves->get_number_of_samplings(); i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    continue;
                }
                for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                    if(maxCount < sampling->get_number_of_samples()) {
                        maxCount = sampling->get_number_of_samples();
                    }
                }
            }
        }
    }
    printf("Using max count of %d for sample length\n", maxCount);
    printf("Total Points: %d\n", totalPoints);
    printf("Reported pulse count: %lld\n", pReader->p_count);
    pReader->seek(0);
    while(pReader->read_pulse()) {
        /* Write line to pulse file */
        gpsTime = pReader->pulse.T * pReader->header.t_scale_factor + pReader->header.t_offset;
        xa = pReader->pulse.anchor_X * pReader->header.x_scale_factor + pReader->header.x_offset;
        ya = pReader->pulse.anchor_Y * pReader->header.y_scale_factor + pReader->header.y_offset;
        za = pReader->pulse.anchor_Z * pReader->header.z_scale_factor + pReader->header.z_offset;
        xt = pReader->pulse.target_X * pReader->header.x_scale_factor + pReader->header.x_offset;
        yt = pReader->pulse.target_Y * pReader->header.y_scale_factor + pReader->header.y_offset;
        zt = pReader->pulse.target_Z * pReader->header.z_scale_factor + pReader->header.z_offset;
        dx = (xt - xa) / 1000;
        dy = (yt - ya) / 1000;
        dz = (zt - za) / 1000;
        xf = xa + pReader->pulse.first_returning_sample * dx;
        yf = ya + pReader->pulse.first_returning_sample * dy;
        zf = za + pReader->pulse.first_returning_sample * dz;
        xl = xa + pReader->pulse.last_returning_sample * dx;
        yl = ya + pReader->pulse.last_returning_sample * dy;
        zl = za + pReader->pulse.last_returning_sample * dz;

        edge = pReader->pulse.edge_of_scan_line;
        scan_dir = pReader->pulse.scan_direction;
        intensity = pReader->pulse.intensity;
        rc = fprintf(pout, szPulseFormat, p,
                                          gpsTime,
                                          xa, ya, za,
                                          xt, yt, zt,
                                          xf, yf, zf,
                                          xl, yl, zl,
                                          edge, scan_dir,
                                          pReader->pulse.mirror_facet,
                                          intensity);

        if(pReader->read_waves()) {
            returnCount = 0;
            for(i = 0; i < pReader->waves->get_number_of_samplings() && returnCount < 1; i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    fprintf(wout, "%lld ", p);
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        fi = 0;
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wout, "%u ", 0);
                            } else {
                                fprintf(wout, "%u ", sampling->get_sample(k));
                            }
                        }
                    }
                    fprintf(wout, "\n");
                } else if(sampling->get_type() == PULSEWAVES_RETURNING) {
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        /* Need new file? */
                        if(j >= nwins) {
                            wins = (FILE**)realloc(wins, sizeof(FILE*) * ++nwins);
                            sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, nwins-1);
                            wins[j] = fopen(szWaveIn, "w");
                        }
                        fprintf(wins[j], "%lld ", p);
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wins[j], "%u ", 0);
                            } else {
                                fprintf(wins[j], "%u ", sampling->get_sample(k));
                            }
                        }
                        fprintf(wins[j], "\n");
                        returnCount++;
                    }
                } else {
                    printf("Unknown type: %d\n", sampling->get_type());
                }
            }
        } else {
            /* No data??? */
            printf("NO DATA!\n");
        }
        p++;
        if(p % 1000 == 0) {
            progress = ((double)p / (double)totalPoints) * 100.;
            printf("\r%d%% done...", (int)progress);
        }
    }
    printf("\r100%% done.\n");

    free(szPulseOut);
    free(szWaveIn);
    free(szWaveOut);
    pReader->close();
    delete pReader;

    fclose(pout);
    fclose(wout);
    for(i = 0; i < nwins; i++) {
        fclose(wins[i]);
    }
    free(wins);
    printf("Created %d incoming wave files\n", nwins);
    printf("Total points processed: %lld\n", p);

    return 0;
}

<|endoftext|>


<commit_before>/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/operators/mlu/mlu_baseop.h"
#include "paddle/phi/kernels/funcs/pooling.h"

namespace paddle {
namespace operators {

namespace {

cnnlPoolingMode_t ToCnnlPoolingMode(const std::string &pooling_type,
                                    bool exclusive,
                                    bool adaptive) {
  cnnlPoolingMode_t pooling_mode;
  if (pooling_type == "max") {
    pooling_mode = CNNL_POOLING_MAX;
  } else if (pooling_type == "avg") {
    if (exclusive && !adaptive) {
      pooling_mode = CNNL_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING;
    } else {
      pooling_mode = CNNL_POOLING_AVERAGE_COUNT_INCLUDE_PADDING;
    }
  } else {
    PADDLE_THROW(platform::errors::InvalidArgument("Unknown pooling_type: %s",
                                                   pooling_type));
  }
  return pooling_mode;
}
}  // namespace

template <typename T>
class MLUPoolOpKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext &ctx) const override {
    auto &dev_ctx = ctx.template device_context<platform::MLUDeviceContext>();
    const Tensor *in_x = ctx.Input<Tensor>("X");
    Tensor *out = ctx.Output<Tensor>("Out");
    out->mutable_data<T>(ctx.GetPlace());

    std::string pooling_type = ctx.Attr<std::string>("pooling_type");
    std::vector<int> ksize = ctx.Attr<std::vector<int>>("ksize");
    std::vector<int> strides = ctx.Attr<std::vector<int>>("strides");
    std::vector<int> paddings = ctx.Attr<std::vector<int>>("paddings");
    std::string data_format = ctx.Attr<std::string>("data_format");

    bool global_pooling = ctx.Attr<bool>("global_pooling");
    bool ceil_mode = ctx.Attr<bool>("ceil_mode");
    bool exclusive = ctx.Attr<bool>("exclusive");
    bool adaptive = ctx.Attr<bool>("adaptive");
    std::string padding_algorithm = ctx.Attr<std::string>("padding_algorithm");

    PADDLE_ENFORCE_EQ(in_x->dims().size(),
                      4,
                      platform::errors::InvalidArgument(
                          "Only support 4-dims for mlu pool2d kernel."));

    const bool channel_last = data_format == "NHWC";
    // default
    cnnlTensorLayout_t cnnl_layout = CNNL_LAYOUT_NCHW;
    auto out_dims = out->dims();
    int64_t out_h = out_dims[2];
    int64_t out_w = out_dims[3];
    auto in_x_dims = in_x->dims();
    framework::DDim data_dims = phi::slice_ddim(in_x_dims, 2, in_x_dims.size());

    if (channel_last) {
      cnnl_layout = CNNL_LAYOUT_NHWC;
      out_h = out_dims[1];
      out_w = out_dims[2];
      data_dims = phi::slice_ddim(in_x_dims, 1, in_x_dims.size() - 1);
    }

    phi::funcs::UpdatePadding(&paddings,
                              global_pooling,
                              adaptive,
                              padding_algorithm,
                              data_dims,
                              strides,
                              ksize);
    if (global_pooling) {
      phi::funcs::UpdateKernelSize(&ksize, data_dims);
    }

    MLUCnnlTensorDesc in_x_desc(*in_x, cnnl_layout, ToCnnlDataType<T>());
    MLUCnnlTensorDesc out_desc(*out, cnnl_layout, ToCnnlDataType<T>());

    cnnlPoolingMode_t pool_mode =
        ToCnnlPoolingMode(pooling_type, exclusive, adaptive);

    if (!adaptive) {
      MLUCnnlPoolingDesc pool_desc(pool_mode,
                                   CNNL_NOT_PROPAGATE_NAN,
                                   ksize[0],
                                   ksize[1],
                                   paddings[0],
                                   paddings[1],
                                   paddings[2],
                                   paddings[3],
                                   strides[0],
                                   strides[1],
                                   1 /*row_dilation*/,
                                   1 /*col_dilation*/,
                                   ceil_mode);

      size_t extra_input_size = 0;
      cnnlHandle_t handle =
          ctx.template device_context<MLUDeviceContext>().cnnl_handle();
      cnnlGetPoolingExtraInputSize(
          handle, pool_mode, out_w, out_h, &extra_input_size);

      if (extra_input_size > 0) {
        phi::CPUContext cpu_ctx;
        framework::Tensor extra_host_tensor =
            ctx.AllocateTmpTensor<int8_t, phi::CPUContext>(
                {static_cast<int64_t>(extra_input_size)}, cpu_ctx);
        cnnlInitPoolingExtraInput(handle,
                                  pool_desc.get(),
                                  in_x_desc.get(),
                                  out_desc.get(),
                                  GetBasePtr(&extra_host_tensor));
        framework::Tensor extra_device_tensor =
            ctx.AllocateTmpTensor<int8_t, MLUDeviceContext>(
                {static_cast<int64_t>(extra_input_size)}, dev_ctx);
        framework::TensorCopy(
            extra_host_tensor, ctx.GetPlace(), &extra_device_tensor);
        // Increase extra_host_tensor holder_ reference count until copy
        // complete.
        auto increase_ref_count = [extra_host_tensor]() {
          VLOG(4) << "Finished copying extra_host_tensor["
                  << GetBasePtr(&extra_host_tensor)
                  << "] in mlu pooling kernel.";
        };
        dev_ctx.AddStreamCallback(increase_ref_count);
        MLUCnnl::PoolingForward(
            ctx,
            pool_mode,
            out_h,
            out_w,
            pool_desc.get(),
            nullptr /*alpha*/,
            in_x_desc.get(),
            GetBasePtr(in_x),
            nullptr /*beta*/,
            GetBasePtr(&extra_device_tensor) /*params_shape_ptr*/,
            out_desc.get(),
            GetBasePtr(out));
      } else {
        MLUCnnl::PoolingForward(ctx,
                                pool_mode,
                                out_h,
                                out_w,
                                pool_desc.get(),
                                nullptr /*alpha*/,
                                in_x_desc.get(),
                                GetBasePtr(in_x),
                                nullptr /*beta*/,
                                nullptr /*params_shape_ptr*/,
                                out_desc.get(),
                                GetBasePtr(out));
      }
    } else {
      // cnnl Adaptive pooling only support NHWC layout
      framework::Tensor trans_in_x;
      framework::Tensor trans_out;
      if (channel_last) {
        trans_in_x = *in_x;
        trans_out = *out;
      } else {
        std::vector<int> perm{0, 2, 3, 1};
        TransposeFromMLUTensor<T>(
            ctx, perm, in_x, &trans_in_x, true /*need_reshape_or_alloc*/);
        trans_out = ctx.AllocateTmpTensor<T, MLUDeviceContext>(
            {out_dims[0], out_dims[2], out_dims[3], out_dims[1]}, dev_ctx);
      }
      MLUCnnlTensorDesc trans_in_x_desc(
          trans_in_x, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
      MLUCnnlTensorDesc trans_out_desc(
          trans_out, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
      MLUCnnl::AdaptivePoolingForward(ctx,
                                      pool_mode,
                                      trans_in_x_desc.get(),
                                      GetBasePtr(&trans_in_x),
                                      trans_out_desc.get(),
                                      GetBasePtr(&trans_out),
                                      nullptr,
                                      nullptr);
      if (!channel_last) {
        std::vector<int> perm{0, 3, 1, 2};
        TransposeFromMLUTensor<T>(
            ctx, perm, &trans_out, out, false /*need_reshape_or_alloc*/);
      }
    }
  }
};

template <typename T, typename IDX_T>
class MLUPoolGradOpKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext &ctx) const override {
    auto &dev_ctx = ctx.template device_context<platform::MLUDeviceContext>();
    const Tensor *in_x = ctx.Input<Tensor>("X");
    const Tensor *out = ctx.Input<Tensor>("Out");
    const Tensor *out_grad = ctx.Input<Tensor>(framework::GradVarName("Out"));
    Tensor *in_x_grad = ctx.Output<Tensor>(framework::GradVarName("X"));
    in_x_grad->mutable_data<T>(ctx.GetPlace());

    std::string pooling_type = ctx.Attr<std::string>("pooling_type");
    std::vector<int> ksize = ctx.Attr<std::vector<int>>("ksize");
    std::vector<int> strides = ctx.Attr<std::vector<int>>("strides");
    std::vector<int> paddings = ctx.Attr<std::vector<int>>("paddings");
    bool ceil_mode = ctx.Attr<bool>("ceil_mode");
    bool exclusive = ctx.Attr<bool>("exclusive");
    bool adaptive = ctx.Attr<bool>("adaptive");
    std::string data_format = ctx.Attr<std::string>("data_format");
    bool global_pooling = ctx.Attr<bool>("global_pooling");
    std::string padding_algorithm = ctx.Attr<std::string>("padding_algorithm");

    const bool channel_last = data_format == "NHWC";

    auto in_x_dims = in_x->dims();
    framework::DDim data_dims = phi::slice_ddim(in_x_dims, 2, in_x_dims.size());
    if (channel_last) {
      data_dims = phi::slice_ddim(in_x_dims, 1, in_x_dims.size() - 1);
    }

    phi::funcs::UpdatePadding(&paddings,
                              global_pooling,
                              adaptive,
                              padding_algorithm,
                              data_dims,
                              strides,
                              ksize);
    if (global_pooling) {
      phi::funcs::UpdateKernelSize(&ksize, data_dims);
    }

    // inputs need with NHWC layout
    framework::Tensor trans_in_x;
    framework::Tensor trans_out;
    framework::Tensor trans_out_grad;
    framework::Tensor trans_in_x_grad;
    if (channel_last) {
      trans_in_x = *in_x;
      trans_out = *out;
      trans_out_grad = *out_grad;
      trans_in_x_grad = *in_x_grad;
    } else {
      std::vector<int> perm{0, 2, 3, 1};
      TransposeFromMLUTensor<T>(
          ctx, perm, in_x, &trans_in_x, true /*need_reshape_or_alloc*/);
      TransposeFromMLUTensor<T>(
          ctx, perm, out, &trans_out, true /*need_reshape_or_alloc*/);
      TransposeFromMLUTensor<T>(
          ctx, perm, out_grad, &trans_out_grad, true /*need_reshape_or_alloc*/);
      auto in_x_grad_dims = in_x_grad->dims();
      trans_in_x_grad =
          ctx.AllocateTmpTensor<T, MLUDeviceContext>({in_x_grad_dims[0],
                                                      in_x_grad_dims[2],
                                                      in_x_grad_dims[3],
                                                      in_x_grad_dims[1]},
                                                     dev_ctx);
    }
    MLUCnnlTensorDesc trans_in_x_desc(
        trans_in_x, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_out_desc(
        trans_out, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_out_grad_desc(
        trans_out_grad, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_in_x_grad_desc(
        trans_in_x_grad, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());

    cnnlPoolingMode_t pool_mode =
        ToCnnlPoolingMode(pooling_type, exclusive, adaptive);
    MLUCnnlPoolingDesc pool_desc(pool_mode,
                                 CNNL_NOT_PROPAGATE_NAN,
                                 ksize[0],
                                 ksize[1],
                                 paddings[0],
                                 paddings[1],
                                 paddings[2],
                                 paddings[3],
                                 strides[0],
                                 strides[1],
                                 1 /*row_dilation*/,
                                 1 /*col_dilation*/,
                                 ceil_mode);

    if (pooling_type == "max") {
      framework::Tensor index_tensor =
          ctx.AllocateTmpTensor<IDX_T, MLUDeviceContext>(trans_out_grad.dims(),
                                                         dev_ctx);
      MLUCnnlTensorDesc index_tensor_desc(
          index_tensor, CNNL_LAYOUT_NHWC, ToCnnlDataType<IDX_T>());
      MLUCnnl::PoolingIndex(ctx,
                            pool_desc.get(),
                            trans_in_x_desc.get(),
                            GetBasePtr(&trans_in_x),
                            index_tensor_desc.get(),
                            GetBasePtr(&index_tensor));
      if (adaptive) {
        MLUCnnl::AdaptivePoolingBackward(ctx,
                                         pool_mode,
                                         trans_out_grad_desc.get(),
                                         GetBasePtr(&trans_out_grad),
                                         index_tensor_desc.get(),
                                         GetBasePtr(&index_tensor),
                                         trans_in_x_grad_desc.get(),
                                         GetBasePtr(&trans_in_x_grad));
      } else {
        MLUCnnl::PoolingBackward(ctx,
                                 pool_desc.get(),
                                 nullptr /*alpha*/,
                                 index_tensor_desc.get(),
                                 GetBasePtr(&index_tensor),
                                 trans_out_grad_desc.get(),
                                 GetBasePtr(&trans_out_grad),
                                 trans_in_x_desc.get(),
                                 GetBasePtr(&trans_in_x),
                                 nullptr /*beta*/,
                                 trans_in_x_grad_desc.get(),
                                 GetBasePtr(&trans_in_x_grad));
      }
    } else {
      if (adaptive) {
        MLUCnnl::AdaptivePoolingBackward(ctx,
                                         pool_mode,
                                         trans_out_grad_desc.get(),
                                         GetBasePtr(&trans_out_grad),
                                         nullptr /*index_tensor_desc.get()*/,
                                         nullptr /*GetBasePtr(&index_tensor)*/,
                                         trans_in_x_grad_desc.get(),
                                         GetBasePtr(&trans_in_x_grad));
      } else {
        MLUCnnl::PoolingBackward(ctx,
                                 pool_desc.get(),
                                 nullptr /*alpha*/,
                                 nullptr,
                                 nullptr,
                                 trans_out_grad_desc.get(),
                                 GetBasePtr(&trans_out_grad),
                                 nullptr,
                                 nullptr,
                                 nullptr /*beta*/,
                                 trans_in_x_grad_desc.get(),
                                 GetBasePtr(&trans_in_x_grad));
      }
    }
    if (!channel_last) {
      std::vector<int> perm{0, 3, 1, 2};
      TransposeFromMLUTensor<T>(ctx,
                                perm,
                                &trans_in_x_grad,
                                in_x_grad,
                                false /*need_reshape_or_alloc*/);
    }
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
namespace plat = paddle::platform;
REGISTER_OP_MLU_KERNEL(pool2d,
                       ops::MLUPoolOpKernel<float>,
                       ops::MLUPoolOpKernel<plat::float16>);
REGISTER_OP_MLU_KERNEL(pool2d_grad,
                       ops::MLUPoolGradOpKernel<float, int>,
                       ops::MLUPoolGradOpKernel<plat::float16, int16_t>);
<commit_msg>[MLU] transpose avg_pool2d to NHWC for better performance. (#44475)<commit_after>/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/operators/mlu/mlu_baseop.h"
#include "paddle/phi/kernels/funcs/pooling.h"

namespace paddle {
namespace operators {

namespace {

cnnlPoolingMode_t ToCnnlPoolingMode(const std::string &pooling_type,
                                    bool exclusive,
                                    bool adaptive) {
  cnnlPoolingMode_t pooling_mode;
  if (pooling_type == "max") {
    pooling_mode = CNNL_POOLING_MAX;
  } else if (pooling_type == "avg") {
    if (exclusive && !adaptive) {
      pooling_mode = CNNL_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING;
    } else {
      pooling_mode = CNNL_POOLING_AVERAGE_COUNT_INCLUDE_PADDING;
    }
  } else {
    PADDLE_THROW(platform::errors::InvalidArgument("Unknown pooling_type: %s",
                                                   pooling_type));
  }
  return pooling_mode;
}
}  // namespace

template <typename T>
class MLUPoolOpKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext &ctx) const override {
    auto &dev_ctx = ctx.template device_context<platform::MLUDeviceContext>();
    const Tensor *in_x = ctx.Input<Tensor>("X");
    Tensor *out = ctx.Output<Tensor>("Out");
    out->mutable_data<T>(ctx.GetPlace());

    std::string pooling_type = ctx.Attr<std::string>("pooling_type");
    std::vector<int> ksize = ctx.Attr<std::vector<int>>("ksize");
    std::vector<int> strides = ctx.Attr<std::vector<int>>("strides");
    std::vector<int> paddings = ctx.Attr<std::vector<int>>("paddings");
    std::string data_format = ctx.Attr<std::string>("data_format");

    bool global_pooling = ctx.Attr<bool>("global_pooling");
    bool ceil_mode = ctx.Attr<bool>("ceil_mode");
    bool exclusive = ctx.Attr<bool>("exclusive");
    bool adaptive = ctx.Attr<bool>("adaptive");
    std::string padding_algorithm = ctx.Attr<std::string>("padding_algorithm");

    PADDLE_ENFORCE_EQ(in_x->dims().size(),
                      4,
                      platform::errors::InvalidArgument(
                          "Only support 4-dims for mlu pool2d kernel."));

    const bool channel_last = data_format == "NHWC";
    // default
    cnnlTensorLayout_t cnnl_layout = CNNL_LAYOUT_NCHW;
    auto out_dims = out->dims();
    int64_t out_h = out_dims[2];
    int64_t out_w = out_dims[3];
    auto in_x_dims = in_x->dims();
    framework::DDim data_dims = phi::slice_ddim(in_x_dims, 2, in_x_dims.size());

    if (channel_last) {
      cnnl_layout = CNNL_LAYOUT_NHWC;
      out_h = out_dims[1];
      out_w = out_dims[2];
      data_dims = phi::slice_ddim(in_x_dims, 1, in_x_dims.size() - 1);
    }

    phi::funcs::UpdatePadding(&paddings,
                              global_pooling,
                              adaptive,
                              padding_algorithm,
                              data_dims,
                              strides,
                              ksize);
    if (global_pooling) {
      phi::funcs::UpdateKernelSize(&ksize, data_dims);
    }

    MLUCnnlTensorDesc in_x_desc(*in_x, cnnl_layout, ToCnnlDataType<T>());
    MLUCnnlTensorDesc out_desc(*out, cnnl_layout, ToCnnlDataType<T>());

    cnnlPoolingMode_t pool_mode =
        ToCnnlPoolingMode(pooling_type, exclusive, adaptive);

    // transpose NCHW to NHWC since cnnl pool2d has worse performance in that
    // layout.
    framework::Tensor trans_in_x;
    framework::Tensor trans_out;
    if (channel_last) {
      trans_in_x = *in_x;
      trans_out = *out;
    } else {
      std::vector<int> perm{0, 2, 3, 1};
      TransposeFromMLUTensor<T>(
          ctx, perm, in_x, &trans_in_x, true /*need_reshape_or_alloc*/);
      trans_out = ctx.AllocateTmpTensor<T, MLUDeviceContext>(
          {out_dims[0], out_dims[2], out_dims[3], out_dims[1]}, dev_ctx);
    }
    MLUCnnlTensorDesc trans_in_x_desc(
        trans_in_x, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_out_desc(
        trans_out, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());

    if (!adaptive) {
      MLUCnnlPoolingDesc pool_desc(pool_mode,
                                   CNNL_NOT_PROPAGATE_NAN,
                                   ksize[0],
                                   ksize[1],
                                   paddings[0],
                                   paddings[1],
                                   paddings[2],
                                   paddings[3],
                                   strides[0],
                                   strides[1],
                                   1 /*row_dilation*/,
                                   1 /*col_dilation*/,
                                   ceil_mode);

      size_t extra_input_size = 0;
      cnnlHandle_t handle =
          ctx.template device_context<MLUDeviceContext>().cnnl_handle();
      cnnlGetPoolingExtraInputSize(
          handle, pool_mode, out_w, out_h, &extra_input_size);

      if (extra_input_size > 0) {
        phi::CPUContext cpu_ctx;
        framework::Tensor extra_host_tensor =
            ctx.AllocateTmpTensor<int8_t, phi::CPUContext>(
                {static_cast<int64_t>(extra_input_size)}, cpu_ctx);
        cnnlInitPoolingExtraInput(handle,
                                  pool_desc.get(),
                                  trans_in_x_desc.get(),
                                  trans_out_desc.get(),
                                  GetBasePtr(&extra_host_tensor));
        framework::Tensor extra_device_tensor =
            ctx.AllocateTmpTensor<int8_t, MLUDeviceContext>(
                {static_cast<int64_t>(extra_input_size)}, dev_ctx);
        framework::TensorCopy(
            extra_host_tensor, ctx.GetPlace(), &extra_device_tensor);
        // Increase extra_host_tensor holder_ reference count until copy
        // complete.
        auto increase_ref_count = [extra_host_tensor]() {
          VLOG(4) << "Finished copying extra_host_tensor["
                  << GetBasePtr(&extra_host_tensor)
                  << "] in mlu pooling kernel.";
        };
        dev_ctx.AddStreamCallback(increase_ref_count);
        MLUCnnl::PoolingForward(
            ctx,
            pool_mode,
            out_h,
            out_w,
            pool_desc.get(),
            nullptr /*alpha*/,
            trans_in_x_desc.get(),
            GetBasePtr(&trans_in_x),
            nullptr /*beta*/,
            GetBasePtr(&extra_device_tensor) /*params_shape_ptr*/,
            trans_out_desc.get(),
            GetBasePtr(&trans_out));
      } else {
        MLUCnnl::PoolingForward(ctx,
                                pool_mode,
                                out_h,
                                out_w,
                                pool_desc.get(),
                                nullptr /*alpha*/,
                                trans_in_x_desc.get(),
                                GetBasePtr(&trans_in_x),
                                nullptr /*beta*/,
                                nullptr /*params_shape_ptr*/,
                                trans_out_desc.get(),
                                GetBasePtr(&trans_out));
      }
    } else {
      MLUCnnl::AdaptivePoolingForward(ctx,
                                      pool_mode,
                                      trans_in_x_desc.get(),
                                      GetBasePtr(&trans_in_x),
                                      trans_out_desc.get(),
                                      GetBasePtr(&trans_out),
                                      nullptr,
                                      nullptr);
    }
    if (!channel_last) {
      std::vector<int> perm{0, 3, 1, 2};
      TransposeFromMLUTensor<T>(
          ctx, perm, &trans_out, out, false /*need_reshape_or_alloc*/);
    }
  }
};

template <typename T, typename IDX_T>
class MLUPoolGradOpKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext &ctx) const override {
    auto &dev_ctx = ctx.template device_context<platform::MLUDeviceContext>();
    const Tensor *in_x = ctx.Input<Tensor>("X");
    const Tensor *out = ctx.Input<Tensor>("Out");
    const Tensor *out_grad = ctx.Input<Tensor>(framework::GradVarName("Out"));
    Tensor *in_x_grad = ctx.Output<Tensor>(framework::GradVarName("X"));
    in_x_grad->mutable_data<T>(ctx.GetPlace());

    std::string pooling_type = ctx.Attr<std::string>("pooling_type");
    std::vector<int> ksize = ctx.Attr<std::vector<int>>("ksize");
    std::vector<int> strides = ctx.Attr<std::vector<int>>("strides");
    std::vector<int> paddings = ctx.Attr<std::vector<int>>("paddings");
    bool ceil_mode = ctx.Attr<bool>("ceil_mode");
    bool exclusive = ctx.Attr<bool>("exclusive");
    bool adaptive = ctx.Attr<bool>("adaptive");
    std::string data_format = ctx.Attr<std::string>("data_format");
    bool global_pooling = ctx.Attr<bool>("global_pooling");
    std::string padding_algorithm = ctx.Attr<std::string>("padding_algorithm");

    const bool channel_last = data_format == "NHWC";

    auto in_x_dims = in_x->dims();
    framework::DDim data_dims = phi::slice_ddim(in_x_dims, 2, in_x_dims.size());
    if (channel_last) {
      data_dims = phi::slice_ddim(in_x_dims, 1, in_x_dims.size() - 1);
    }

    phi::funcs::UpdatePadding(&paddings,
                              global_pooling,
                              adaptive,
                              padding_algorithm,
                              data_dims,
                              strides,
                              ksize);
    if (global_pooling) {
      phi::funcs::UpdateKernelSize(&ksize, data_dims);
    }

    // inputs need with NHWC layout
    framework::Tensor trans_in_x;
    framework::Tensor trans_out;
    framework::Tensor trans_out_grad;
    framework::Tensor trans_in_x_grad;
    if (channel_last) {
      trans_in_x = *in_x;
      trans_out = *out;
      trans_out_grad = *out_grad;
      trans_in_x_grad = *in_x_grad;
    } else {
      std::vector<int> perm{0, 2, 3, 1};
      TransposeFromMLUTensor<T>(
          ctx, perm, in_x, &trans_in_x, true /*need_reshape_or_alloc*/);
      TransposeFromMLUTensor<T>(
          ctx, perm, out, &trans_out, true /*need_reshape_or_alloc*/);
      TransposeFromMLUTensor<T>(
          ctx, perm, out_grad, &trans_out_grad, true /*need_reshape_or_alloc*/);
      auto in_x_grad_dims = in_x_grad->dims();
      trans_in_x_grad =
          ctx.AllocateTmpTensor<T, MLUDeviceContext>({in_x_grad_dims[0],
                                                      in_x_grad_dims[2],
                                                      in_x_grad_dims[3],
                                                      in_x_grad_dims[1]},
                                                     dev_ctx);
    }
    MLUCnnlTensorDesc trans_in_x_desc(
        trans_in_x, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_out_desc(
        trans_out, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_out_grad_desc(
        trans_out_grad, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());
    MLUCnnlTensorDesc trans_in_x_grad_desc(
        trans_in_x_grad, CNNL_LAYOUT_NHWC, ToCnnlDataType<T>());

    cnnlPoolingMode_t pool_mode =
        ToCnnlPoolingMode(pooling_type, exclusive, adaptive);
    MLUCnnlPoolingDesc pool_desc(pool_mode,
                                 CNNL_NOT_PROPAGATE_NAN,
                                 ksize[0],
                                 ksize[1],
                                 paddings[0],
                                 paddings[1],
                                 paddings[2],
                                 paddings[3],
                                 strides[0],
                                 strides[1],
                                 1 /*row_dilation*/,
                                 1 /*col_dilation*/,
                                 ceil_mode);

    if (pooling_type == "max") {
      framework::Tensor index_tensor =
          ctx.AllocateTmpTensor<IDX_T, MLUDeviceContext>(trans_out_grad.dims(),
                                                         dev_ctx);
      MLUCnnlTensorDesc index_tensor_desc(
          index_tensor, CNNL_LAYOUT_NHWC, ToCnnlDataType<IDX_T>());
      MLUCnnl::PoolingIndex(ctx,
                            pool_desc.get(),
                            trans_in_x_desc.get(),
                            GetBasePtr(&trans_in_x),
                            index_tensor_desc.get(),
                            GetBasePtr(&index_tensor));
      if (adaptive) {
        MLUCnnl::AdaptivePoolingBackward(ctx,
                                         pool_mode,
                                         trans_out_grad_desc.get(),
                                         GetBasePtr(&trans_out_grad),
                                         index_tensor_desc.get(),
                                         GetBasePtr(&index_tensor),
                                         trans_in_x_grad_desc.get(),
                                         GetBasePtr(&trans_in_x_grad));
      } else {
        MLUCnnl::PoolingBackward(ctx,
                                 pool_desc.get(),
                                 nullptr /*alpha*/,
                                 index_tensor_desc.get(),
                                 GetBasePtr(&index_tensor),
                                 trans_out_grad_desc.get(),
                                 GetBasePtr(&trans_out_grad),
                                 trans_in_x_desc.get(),
                                 GetBasePtr(&trans_in_x),
                                 nullptr /*beta*/,
                                 trans_in_x_grad_desc.get(),
                                 GetBasePtr(&trans_in_x_grad));
      }
    } else {
      if (adaptive) {
        MLUCnnl::AdaptivePoolingBackward(ctx,
                                         pool_mode,
                                         trans_out_grad_desc.get(),
                                         GetBasePtr(&trans_out_grad),
                                         nullptr /*index_tensor_desc.get()*/,
                                         nullptr /*GetBasePtr(&index_tensor)*/,
                                         trans_in_x_grad_desc.get(),
                                         GetBasePtr(&trans_in_x_grad));
      } else {
        MLUCnnl::PoolingBackward(ctx,
                                 pool_desc.get(),
                                 nullptr /*alpha*/,
                                 nullptr,
                                 nullptr,
                                 trans_out_grad_desc.get(),
                                 GetBasePtr(&trans_out_grad),
                                 nullptr,
                                 nullptr,
                                 nullptr /*beta*/,
                                 trans_in_x_grad_desc.get(),
                                 GetBasePtr(&trans_in_x_grad));
      }
    }
    if (!channel_last) {
      std::vector<int> perm{0, 3, 1, 2};
      TransposeFromMLUTensor<T>(ctx,
                                perm,
                                &trans_in_x_grad,
                                in_x_grad,
                                false /*need_reshape_or_alloc*/);
    }
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
namespace plat = paddle::platform;
REGISTER_OP_MLU_KERNEL(pool2d,
                       ops::MLUPoolOpKernel<float>,
                       ops::MLUPoolOpKernel<plat::float16>);
REGISTER_OP_MLU_KERNEL(pool2d_grad,
                       ops::MLUPoolGradOpKernel<float, int>,
                       ops::MLUPoolGradOpKernel<plat::float16, int16_t>);
<|endoftext|>