<commit_before>/**
 * @file    TypeDescriptor.hpp
 * @author  niob
 * @date    Oct 21, 2016
 * @brief   Defines the {@link TypeDescriptor} class.
 */

#ifndef TYPEDESCRIPTOR_HPP_
#define TYPEDESCRIPTOR_HPP_
#pragma once

#include <cstddef>
#include <initializer_list>
#include <vector>

namespace ssw {

/**
 * Represents a type descriptor for a managed object.
 *
 * The type descriptor stores information about the size of objects, and locations of pointers to other
 * managed objects. It allows iteration through pointer offsets using standard {@link begin} and
 * {@link end} iterators.
 */
class TypeDescriptor
{
	const std::size_t mSize;
	const std::vector<std::ptrdiff_t> mOffsets;

public:

	/**
	 * Create a TypeDescriptor with the specified size and no pointers.
	 *
	 * @param size The size of objects of the described type.
	 */
	TypeDescriptor(std::size_t size)
			: mSize(size), mOffsets() {
	}

	/**
	 * Create a TypeDescriptor with the specified size and pointer offsets.
	 *
	 * @param size The size of objects of the described type.
	 * @param offsets The offsets within objects of the described type of pointers to other managed objects.
	 */
	TypeDescriptor(std::size_t size, std::initializer_list<std::ptrdiff_t> offsets)
			: mSize(size), mOffsets(offsets) {
	}

	/**
	 * Get the size of the objects described by this type descriptor.
	 */
	std::size_t size() const noexcept {
		return mSize;
	}

	/**
	 * Get a reference to the vector of pointer offsets.
	 */
	const std::vector<std::ptrdiff_t>& offsets() const noexcept {
		return mOffsets;
	}

	/**
	 * Determine whether the described object has any pointers to other managed objects.
	 */
	explicit operator bool() const noexcept {
		return !mOffsets.empty();
	}

	/**
	 * Get an iterator to the beginning of the pointer offset container.
	 *
	 * @return A `const` iterator to the first pointer offset.
	 */
	auto begin() const noexcept(noexcept(mOffsets.cbegin())) {
		return mOffsets.cbegin();
	}

	/**
	 * Get an iterator to the end of the pointer offset container.
	 *
	 * @return A `const` iterator past the last pointer offset.
	 */
	auto end() const noexcept(noexcept(mOffsets.cend())) {
		return mOffsets.cend();
	}
};

} // namespace ssw

#endif /* TYPEDESCRIPTOR_HPP_ */
<commit_msg>Add pointer to destructor to TypeDescriptor.<commit_after>/**
 * @file    TypeDescriptor.hpp
 * @author  niob
 * @date    Oct 21, 2016
 * @brief   Defines the {@link TypeDescriptor} class.
 */

#ifndef TYPEDESCRIPTOR_HPP_
#define TYPEDESCRIPTOR_HPP_
#pragma once

#include <cstddef>
#include <initializer_list>
#include <vector>

namespace ssw {

/**
 * Represents a type descriptor for a managed object.
 *
 * The type descriptor stores information about the size of objects, a pointer to the destructor, and
 * locations of pointers to other managed objects. It allows iteration through pointer offsets using
 * standard {@link begin} and {@link end} iterators.
 */
class TypeDescriptor
{
	using Destructor = void(*)(const void*);

	const std::size_t mSize;
	const Destructor mDestructor;
	const std::vector<std::ptrdiff_t> mOffsets;

	TypeDescriptor(std::size_t size, Destructor destructor, std::initializer_list<std::ptrdiff_t> offsets)
			: mSize(size), mDestructor(destructor), mOffsets(offsets) {
	}

public:

	/**
	 * Create a TypeDescriptor for the specified type with the specified pointer offsets.
	 *
	 * @param offsets (optional) The offsets, within `T` objects, of pointers to other managed objects.
	 * @return A TypeDescriptor.
	 *
	 * @tparam T The type to create the descriptor for.
	 */
	template <typename T>
	static TypeDescriptor make(std::initializer_list<std::ptrdiff_t> offsets = {}) {
		return TypeDescriptor(sizeof(T), [](const void* x) { static_cast<const T*>(x)->~T(); }, offsets);
	}

	/**
	 * Get the size of the objects described by this type descriptor.
	 */
	std::size_t size() const noexcept {
		return mSize;
	}

	/**
	 * Get a reference to the vector of pointer offsets.
	 */
	const std::vector<std::ptrdiff_t>& offsets() const noexcept {
		return mOffsets;
	}

	/**
	 * Determine whether the described object has any pointers to other managed objects.
	 */
	explicit operator bool() const noexcept {
		return !mOffsets.empty();
	}

	/**
	 * Get an iterator to the beginning of the pointer offset container.
	 *
	 * @return A `const` iterator to the first pointer offset.
	 */
	auto begin() const noexcept(noexcept(mOffsets.cbegin())) {
		return mOffsets.cbegin();
	}

	/**
	 * Get an iterator to the end of the pointer offset container.
	 *
	 * @return A `const` iterator past the last pointer offset.
	 */
	auto end() const noexcept(noexcept(mOffsets.cend())) {
		return mOffsets.cend();
	}
};

} // namespace ssw

#endif /* TYPEDESCRIPTOR_HPP_ */
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <app/qbs/parser/commandlineparser.h>
#include <app/shared/logging/consolelogger.h>
#include <tools/buildoptions.h>
#include <tools/error.h>
#include <tools/hostosinfo.h>

#include <QtCore/qdir.h>
#include <QtCore/qregexp.h>
#include <QtCore/qtemporaryfile.h>

#include <QtTest/qtest.h>

using namespace qbs;

class TestCmdLineParser : public QObject
{
    Q_OBJECT
public:
    TestCmdLineParser()
    {
        ConsoleLogger::instance().logSink()->setEnabled(false);
    }

private slots:
    void testValidCommandLine()
    {
        QTemporaryFile projectFile;
        QVERIFY(projectFile.open());
        const QStringList fileArgs = QStringList() << "-f" << projectFile.fileName();
        QStringList args;
        args.append("-vvk");
        args.append("-v");
        args << "--products" << "blubb";
        args << "--changed-files" << "foo,bar" << fileArgs;
        args << "--check-timestamps";
        args << "--check-outputs";
        CommandLineParser parser;

        QVERIFY(parser.parseCommandLine(args));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerTrace);
        QCOMPARE(parser.command(), BuildCommandType);
        QCOMPARE(parser.products(), QStringList() << "blubb");
        QCOMPARE(parser.buildOptions(QString()).changedFiles().count(), 2);
        QVERIFY(parser.buildOptions(QString()).keepGoing());
        QVERIFY(parser.forceTimestampCheck());
        QVERIFY(parser.forceOutputCheck());
        QVERIFY(!parser.logTime());
        QCOMPARE(parser.buildConfigurations().count(), 1);

        QVERIFY(parser.parseCommandLine(QStringList() << "-vvvqqq" << fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), defaultLogLevel());

        QVERIFY(parser.parseCommandLine(QStringList() << "-t" << fileArgs));
        QVERIFY(parser.logTime());

        if (!Internal::HostOsInfo::isWindowsHost()) { // Windows has no progress bar atm.
            // Note: We cannot just check for !parser.logTime() here, because if the test is not
            // run in a terminal, "--show-progress" is ignored, in which case "--log-time"
            // takes effect.
            QVERIFY(parser.parseCommandLine(QStringList() << "-t" << "--show-progress"
                                            << fileArgs));
            QVERIFY(parser.showProgress() != parser.logTime());
        }

        QVERIFY(parser.parseCommandLine(QStringList() << "-vvqqq" << fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerWarning);

        QVERIFY(parser.parseCommandLine(QStringList() << "-vvvqq" << fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerDebug);

        QVERIFY(parser.parseCommandLine(QStringList() << "--log-level" << "trace" << fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerTrace);

        // Second "global" profile overwrites first.
        QVERIFY(parser.parseCommandLine(QStringList() << "profile:a" << fileArgs << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 1);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("b"));

        // Second build configuration-specific profile overwrites first.
        QVERIFY(parser.parseCommandLine(QStringList(fileArgs) << "config:debug" << "profile:a"
                                        << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 1);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("b"));

        QVERIFY(parser.parseCommandLine(QStringList(fileArgs) << "config:a-debug" << "profile:a"
                                        << "config:b-debug" << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 2);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(), QLatin1String("a-debug"));
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("a"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.configurationName").toString(), QLatin1String("b-debug"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.profile").toString(), QLatin1String("b"));

        // Redundant build request
        QVERIFY(parser.parseCommandLine(QStringList(fileArgs) << "config:debug" << "profile:a"
                                        << "config:debug" << "profile:a"));
        QCOMPARE(parser.buildConfigurations().count(), 1);

        QVERIFY(parser.parseCommandLine(QStringList() << "config:debug" << "profile:a"
                                        << "config:release" << "profile:b" << fileArgs));
        QCOMPARE(parser.buildConfigurations().count(), 2);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(), QLatin1String("debug"));
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("a"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.configurationName").toString(), QLatin1String("release"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.profile").toString(), QLatin1String("b"));

        // Non-global property takes precedence.
        QVERIFY(parser.parseCommandLine(QStringList(fileArgs) << "profile:a" << "config:debug"
                                        << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 1);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(), QLatin1String("debug"));
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("b"));

        // Digits are always handled as option parameters.
        QVERIFY(parser.parseCommandLine(QStringList(fileArgs) << "-j" << "123"));
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);
        QVERIFY(parser.parseCommandLine(QStringList(fileArgs) << "-j123"));
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);

        // Argument list separation for the "run" command.
        QVERIFY(parser.parseCommandLine(QStringList("run") << fileArgs << "config:custom"
                                        << "-j123"));
        QCOMPARE(parser.command(), RunCommandType);
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(),
                 QLatin1String("custom"));
        QVERIFY(parser.runArgs().empty());
        QVERIFY(parser.parseCommandLine(QStringList("run") << fileArgs << "-j" << "123" << "--"
                << "config:custom"));
        QCOMPARE(parser.command(), RunCommandType);
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(),
                 QLatin1String("default"));
        QCOMPARE(parser.runArgs(), QStringList({"config:custom"}));

        // show-version
        QVERIFY(parser.parseCommandLine(QStringList("show-version")));
        QVERIFY(parser.showVersion());
        QVERIFY(parser.parseCommandLine(QStringList("--version")));
        QVERIFY(parser.showVersion());
        QVERIFY(parser.parseCommandLine(QStringList("-V")));
        QVERIFY(parser.showVersion());
    }

    void testInvalidCommandLine()
    {
        QTemporaryFile projectFile;
        QVERIFY(projectFile.open());
        const QStringList fileArgs = QStringList() << "-f" << projectFile.fileName();
        CommandLineParser parser;
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "-x")); // Unknown short option.
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "--xyz")); // Unknown long option.
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "-vjv")); // Invalid position.
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "-j"));  // Missing argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << "-j" << "0" << fileArgs)); // Wrong argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "--products"));  // Missing argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << "--changed-files" << "," << fileArgs)); // Wrong argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << "--log-level" << "blubb" << fileArgs)); // Wrong argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "-123")); // Unknown numeric argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << fileArgs << "debug")); // Unknown parameter.
        QVERIFY(!parser.parseCommandLine(QStringList("help") << "build" << "clean")); // Too many arguments.
        QVERIFY(!parser.parseCommandLine(QStringList("clean") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("dump-nodes-tree") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("status") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("update-timestamps") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("show-version") << "config:debug")); // This command takes no arguments.
    }

};

QTEST_MAIN(TestCmdLineParser)

#include "tst_cmdlineparser.moc"
<commit_msg>CLI autotest: Factor out common code<commit_after>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <app/qbs/parser/commandlineparser.h>
#include <app/shared/logging/consolelogger.h>
#include <tools/buildoptions.h>
#include <tools/error.h>
#include <tools/hostosinfo.h>

#include <QtCore/qdir.h>
#include <QtCore/qregexp.h>
#include <QtCore/qtemporaryfile.h>

#include <QtTest/qtest.h>

using namespace qbs;

class TestCmdLineParser : public QObject
{
    Q_OBJECT
public:
    TestCmdLineParser()
    {
        ConsoleLogger::instance().logSink()->setEnabled(false);
    }

private slots:
    void initTestCase()
    {
        QVERIFY(m_projectFile.open());
        m_fileArgs = QStringList() << "-f" << m_projectFile.fileName();
    }

    void testValidCommandLine()
    {
        QStringList args;
        args.append("-vvk");
        args.append("-v");
        args << "--products" << "blubb";
        args << "--changed-files" << "foo,bar" << m_fileArgs;
        args << "--check-timestamps";
        args << "--check-outputs";
        CommandLineParser parser;

        QVERIFY(parser.parseCommandLine(args));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerTrace);
        QCOMPARE(parser.command(), BuildCommandType);
        QCOMPARE(parser.products(), QStringList() << "blubb");
        QCOMPARE(parser.buildOptions(QString()).changedFiles().count(), 2);
        QVERIFY(parser.buildOptions(QString()).keepGoing());
        QVERIFY(parser.forceTimestampCheck());
        QVERIFY(parser.forceOutputCheck());
        QVERIFY(!parser.logTime());
        QCOMPARE(parser.buildConfigurations().count(), 1);

        QVERIFY(parser.parseCommandLine(QStringList() << "-vvvqqq" << m_fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), defaultLogLevel());

        QVERIFY(parser.parseCommandLine(QStringList() << "-t" << m_fileArgs));
        QVERIFY(parser.logTime());

        if (!Internal::HostOsInfo::isWindowsHost()) { // Windows has no progress bar atm.
            // Note: We cannot just check for !parser.logTime() here, because if the test is not
            // run in a terminal, "--show-progress" is ignored, in which case "--log-time"
            // takes effect.
            QVERIFY(parser.parseCommandLine(QStringList() << "-t" << "--show-progress"
                                            << m_fileArgs));
            QVERIFY(parser.showProgress() != parser.logTime());
        }

        QVERIFY(parser.parseCommandLine(QStringList() << "-vvqqq" << m_fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerWarning);

        QVERIFY(parser.parseCommandLine(QStringList() << "-vvvqq" << m_fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerDebug);

        QVERIFY(parser.parseCommandLine(QStringList() << "--log-level" << "trace" << m_fileArgs));
        QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerTrace);

        // Second "global" profile overwrites first.
        QVERIFY(parser.parseCommandLine(QStringList() << "profile:a" << m_fileArgs << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 1);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("b"));

        // Second build configuration-specific profile overwrites first.
        QVERIFY(parser.parseCommandLine(QStringList(m_fileArgs) << "config:debug" << "profile:a"
                                        << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 1);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("b"));

        QVERIFY(parser.parseCommandLine(QStringList(m_fileArgs) << "config:a-debug" << "profile:a"
                                        << "config:b-debug" << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 2);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(), QLatin1String("a-debug"));
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("a"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.configurationName").toString(), QLatin1String("b-debug"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.profile").toString(), QLatin1String("b"));

        // Redundant build request
        QVERIFY(parser.parseCommandLine(QStringList(m_fileArgs) << "config:debug" << "profile:a"
                                        << "config:debug" << "profile:a"));
        QCOMPARE(parser.buildConfigurations().count(), 1);

        QVERIFY(parser.parseCommandLine(QStringList() << "config:debug" << "profile:a"
                                        << "config:release" << "profile:b" << m_fileArgs));
        QCOMPARE(parser.buildConfigurations().count(), 2);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(), QLatin1String("debug"));
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("a"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.configurationName").toString(), QLatin1String("release"));
        QCOMPARE(parser.buildConfigurations().at(1).value("qbs.profile").toString(), QLatin1String("b"));

        // Non-global property takes precedence.
        QVERIFY(parser.parseCommandLine(QStringList(m_fileArgs) << "profile:a" << "config:debug"
                                        << "profile:b"));
        QCOMPARE(parser.buildConfigurations().count(), 1);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(), QLatin1String("debug"));
        QCOMPARE(parser.buildConfigurations().first().value("qbs.profile").toString(), QLatin1String("b"));

        // Digits are always handled as option parameters.
        QVERIFY(parser.parseCommandLine(QStringList(m_fileArgs) << "-j" << "123"));
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);
        QVERIFY(parser.parseCommandLine(QStringList(m_fileArgs) << "-j123"));
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);

        // Argument list separation for the "run" command.
        QVERIFY(parser.parseCommandLine(QStringList("run") << m_fileArgs << "config:custom"
                                        << "-j123"));
        QCOMPARE(parser.command(), RunCommandType);
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(),
                 QLatin1String("custom"));
        QVERIFY(parser.runArgs().empty());
        QVERIFY(parser.parseCommandLine(QStringList("run") << m_fileArgs << "-j" << "123" << "--"
                << "config:custom"));
        QCOMPARE(parser.command(), RunCommandType);
        QCOMPARE(parser.buildOptions(QString()).maxJobCount(), 123);
        QCOMPARE(parser.buildConfigurations().first().value("qbs.configurationName").toString(),
                 QLatin1String("default"));
        QCOMPARE(parser.runArgs(), QStringList({"config:custom"}));

        // show-version
        QVERIFY(parser.parseCommandLine(QStringList("show-version")));
        QVERIFY(parser.showVersion());
        QVERIFY(parser.parseCommandLine(QStringList("--version")));
        QVERIFY(parser.showVersion());
        QVERIFY(parser.parseCommandLine(QStringList("-V")));
        QVERIFY(parser.showVersion());
    }

    void testInvalidCommandLine()
    {
        CommandLineParser parser;
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "-x")); // Unknown short option.
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "--xyz")); // Unknown long option.
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "-vjv")); // Invalid position.
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "-j"));  // Missing argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << "-j" << "0" << m_fileArgs)); // Wrong argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "--products"));  // Missing argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << "--changed-files" << "," << m_fileArgs)); // Wrong argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << "--log-level" << "blubb" << m_fileArgs)); // Wrong argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "-123")); // Unknown numeric argument.
        QVERIFY(!parser.parseCommandLine(QStringList() << m_fileArgs << "debug")); // Unknown parameter.
        QVERIFY(!parser.parseCommandLine(QStringList("help") << "build" << "clean")); // Too many arguments.
        QVERIFY(!parser.parseCommandLine(QStringList("clean") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("dump-nodes-tree") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("status") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("update-timestamps") << "profile:x")); // This command cannot resolve.
        QVERIFY(!parser.parseCommandLine(QStringList("show-version") << "config:debug")); // This command takes no arguments.
    }

private:
    QTemporaryFile m_projectFile;
    QStringList m_fileArgs;
};

QTEST_MAIN(TestCmdLineParser)

#include "tst_cmdlineparser.moc"
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//TESTED_COMPONENT=src/multimedia

#include "tst_qradiotuner_s60.h"

void tst_QRadioTuner_s60::initTestCase()
{
    qRegisterMetaType<QRadioTuner::State>("QRadioTuner::State");
    qRegisterMetaType<QRadioTuner::Band>("QRadioTuner::Band");

    radio = new QRadioTuner(0);
    QVERIFY(radio->service() != 0);

    QSignalSpy stateSpy(radio, SIGNAL(stateChanged(QRadioTuner::State)));

    QCOMPARE(radio->state(), QRadioTuner::StoppedState);
    radio->start();
    QCOMPARE(radio->state(), QRadioTuner::ActiveState);

    QCOMPARE(stateSpy.count(), 1);
    QCOMPARE(stateSpy.first()[0].value<QRadioTuner::State>(), QRadioTuner::ActiveState);
}

void tst_QRadioTuner_s60::cleanupTestCase()
{
    QVERIFY(radio->error() == QRadioTuner::NoError);
    QVERIFY(radio->errorString().isEmpty());

    QSignalSpy stateSpy(radio, SIGNAL(stateChanged(QRadioTuner::State)));

    radio->stop();
    QCOMPARE(radio->state(), QRadioTuner::StoppedState);
    QCOMPARE(stateSpy.count(), 1);

    QCOMPARE(stateSpy.first()[0].value<QRadioTuner::State>(), QRadioTuner::StoppedState);

    delete radio;
}

void tst_QRadioTuner_s60::testBand()
{
    QVERIFY(radio->isBandSupported(QRadioTuner::FM));
    QVERIFY(!radio->isBandSupported(QRadioTuner::SW));

    if(radio->isBandSupported(QRadioTuner::AM)) {
        QSignalSpy readSignal(radio, SIGNAL(bandChanged(QRadioTuner::Band)));
        radio->setBand(QRadioTuner::AM);
        QTestEventLoop::instance().enterLoop(1);
        QVERIFY(radio->band() == QRadioTuner::AM);
        QVERIFY(readSignal.count() == 1);
    }
}

void tst_QRadioTuner_s60::testFrequency()
{
    QSignalSpy readSignal(radio, SIGNAL(frequencyChanged(int)));
    radio->setFrequency(104500000);
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(radio->frequency() == 104500000);
    QVERIFY(readSignal.count() == 1);

    // frequencyStep for FM radio is 100kHz (100000Hz)
    QVERIFY(radio->frequencyStep(QRadioTuner::FM) == 100000);
    QPair<int,int> test = radio->frequencyRange(QRadioTuner::FM);
    // frequency range for FM radio is 87,5MHz - 108MHz
    QVERIFY(test.first == 87500000);
    QVERIFY(test.second == 108000000);
}

void tst_QRadioTuner_s60::testMute()
{
    QSignalSpy readSignal(radio, SIGNAL(mutedChanged(bool)));
    radio->setMuted(true);
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(radio->isMuted());
    QVERIFY(readSignal.count() == 1);
}

void tst_QRadioTuner_s60::testSearch()
{
    QSignalSpy readSignal(radio, SIGNAL(searchingChanged(bool)));
    QVERIFY(!radio->isSearching());

    radio->searchForward();
    QVERIFY(radio->isSearching());
    QVERIFY(readSignal.count() == 1);

    radio->cancelSearch();
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(!radio->isSearching());
    QVERIFY(readSignal.count() == 2);

    radio->searchBackward();
    QVERIFY(radio->isSearching());
    QVERIFY(readSignal.count() == 3);

    radio->cancelSearch();
    QVERIFY(!radio->isSearching());
}

void tst_QRadioTuner_s60::testVolume()
{
    QVERIFY(radio->volume() == 100);
    QSignalSpy readSignal(radio, SIGNAL(volumeChanged(int)));
    radio->setVolume(50);
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(radio->volume() == 50);
    QVERIFY(readSignal.count() == 1);
}

void tst_QRadioTuner_s60::testSignal()
{
    int signalStrength = radio->signalStrength();
    QVERIFY(signalStrength == signalStrength);
    // There is no set of this only a get, do nothing else.
}

void tst_QRadioTuner_s60::testStereo()
{
    QVERIFY(radio->isStereo());
    radio->setStereoMode(QRadioTuner::ForceMono);
    QVERIFY(radio->stereoMode() == QRadioTuner::ForceMono);
}
<commit_msg>MOBILITY-2526<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//TESTED_COMPONENT=src/multimedia

#include "tst_qradiotuner_s60.h"

#define QTRY_COMPARE_S60(a,e)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if ((a) == (e)) break;                  \
        QTest::qWait(100);                      \
    }

void tst_QRadioTuner_s60::initTestCase()
{
    qRegisterMetaType<QRadioTuner::State>("QRadioTuner::State");
    qRegisterMetaType<QRadioTuner::Band>("QRadioTuner::Band");

    radio = new QRadioTuner(0);
    QVERIFY(radio->service() != 0);

    QSignalSpy stateSpy(radio, SIGNAL(stateChanged(QRadioTuner::State)));

    QCOMPARE(radio->state(), QRadioTuner::StoppedState);
    radio->start();
    //QCOMPARE(radio->state(), QRadioTuner::ActiveState);
    QTRY_COMPARE_S60(radio->state(), QRadioTuner::ActiveState);

    QCOMPARE(stateSpy.count(), 1);
    QCOMPARE(stateSpy.first()[0].value<QRadioTuner::State>(), QRadioTuner::ActiveState);
}

void tst_QRadioTuner_s60::cleanupTestCase()
{
    QVERIFY(radio->error() == QRadioTuner::NoError);
    QVERIFY(radio->errorString().isEmpty());

    QSignalSpy stateSpy(radio, SIGNAL(stateChanged(QRadioTuner::State)));

    radio->stop();
    QTRY_COMPARE_S60(radio->state(), QRadioTuner::StoppedState);
    QCOMPARE(stateSpy.count(), 1);

    QCOMPARE(stateSpy.first()[0].value<QRadioTuner::State>(), QRadioTuner::StoppedState);

    delete radio;
}

void tst_QRadioTuner_s60::testBand()
{
    QVERIFY(radio->isBandSupported(QRadioTuner::FM));
    QVERIFY(!radio->isBandSupported(QRadioTuner::SW));

    if(radio->isBandSupported(QRadioTuner::AM)) {
        QSignalSpy readSignal(radio, SIGNAL(bandChanged(QRadioTuner::Band)));
        radio->setBand(QRadioTuner::AM);
        QTestEventLoop::instance().enterLoop(1);
        QVERIFY(radio->band() == QRadioTuner::AM);
        QVERIFY(readSignal.count() == 1);
    }
}

void tst_QRadioTuner_s60::testFrequency()
{
    QSignalSpy readSignal(radio, SIGNAL(frequencyChanged(int)));
    radio->setFrequency(104500000);
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(radio->frequency() == 104500000);
    QVERIFY(readSignal.count() == 1);

    // frequencyStep for FM radio is 100kHz (100000Hz)
    QVERIFY(radio->frequencyStep(QRadioTuner::FM) == 100000);
    QPair<int,int> test = radio->frequencyRange(QRadioTuner::FM);
    // frequency range for FM radio is 87,5MHz - 108MHz
    QVERIFY(test.first == 87500000);
    QVERIFY(test.second == 108000000);
}

void tst_QRadioTuner_s60::testMute()
{
    QSignalSpy readSignal(radio, SIGNAL(mutedChanged(bool)));
    radio->setMuted(true);
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(radio->isMuted());
    QVERIFY(readSignal.count() == 1);
}

void tst_QRadioTuner_s60::testSearch()
{
    QSignalSpy readSignal(radio, SIGNAL(searchingChanged(bool)));
    QVERIFY(!radio->isSearching());

    radio->searchForward();
    QVERIFY(radio->isSearching());
    QVERIFY(readSignal.count() == 1);

    radio->cancelSearch();
    QTestEventLoop::instance().enterLoop(1);
    QVERIFY(!radio->isSearching());
    QVERIFY(readSignal.count() == 2);

    radio->searchBackward();
    QVERIFY(radio->isSearching());
    QVERIFY(readSignal.count() == 3);

    radio->cancelSearch();
    QVERIFY(!radio->isSearching());
}

void tst_QRadioTuner_s60::testVolume()
{
    QVERIFY(radio->volume() == 50);
    QSignalSpy readSignal(radio, SIGNAL(volumeChanged(int)));
    radio->setVolume(70);
    QTestEventLoop::instance().enterLoop(1);
    QTRY_COMPARE_S60(radio->volume() , 70);
    QTRY_COMPARE_S60(readSignal.count() ,1);
}

void tst_QRadioTuner_s60::testSignal()
{
    int signalStrength = radio->signalStrength();
    QVERIFY(signalStrength == signalStrength);
    // There is no set of this only a get, do nothing else.
}

void tst_QRadioTuner_s60::testStereo()
{
    QVERIFY(radio->isStereo());
    radio->setStereoMode(QRadioTuner::ForceMono);
    QVERIFY(radio->stereoMode() == QRadioTuner::ForceMono);
}
<|endoftext|>


<commit_before>#include <string>
#include <stdint.h>

#include "buffer_t.h"
#include "JITCompiledModule.h"
#include "CodeGen.h"
#include "LLVM_Headers.h"
#include "Debug.h"

namespace Halide {
namespace Internal {

using std::string;

using namespace llvm;

// Wraps an execution engine. Takes ownership of the given module and
// the memory for jit compiled code.
class JITModuleHolder {
public:
    mutable RefCount ref_count;

    JITModuleHolder(llvm::ExecutionEngine *ee, llvm::Module *m, void (*stop_threads)()) :
        execution_engine(ee),
        module(m),
        context(&m->getContext()),
        shutdown_thread_pool(stop_threads) {
    }

    ~JITModuleHolder() {
        for (size_t i = 0; i < cleanup_routines.size(); i++) {
            void *ptr = reinterpret_bits<void *>(cleanup_routines[i]);
            debug(1) << "Calling target specific cleanup routine at " << ptr << "\n";
            (*cleanup_routines[i])();
        }

        shutdown_thread_pool();
        delete execution_engine;
        delete context;
        // No need to delete the module - deleting the execution engine should take care of that.
    }

    ExecutionEngine *execution_engine;
    Module *module;
    LLVMContext *context;
    void (*shutdown_thread_pool)();

    /** Do any target-specific module cleanup. */
    std::vector<void (*)()> cleanup_routines;
};

template<>
EXPORT RefCount &ref_count<JITModuleHolder>(const JITModuleHolder *f) {return f->ref_count;}

template<>
EXPORT void destroy<JITModuleHolder>(const JITModuleHolder *f) {delete f;}

namespace {

#ifdef __arm__
// On ARM we need to track the addresses of all the functions we
// retrieve so that we can flush the icache.
char *start, *end;
#endif

// Retrieve a function pointer from an llvm module, possibly by
// compiling it. Returns it by assigning to the last argument.
template<typename FP>
void hook_up_function_pointer(ExecutionEngine *ee, Module *mod, const string &name, bool must_succeed, FP *result) {

    assert(mod && ee);

    debug(2) << "Retrieving " << name << " from module\n";
    llvm::Function *fn = mod->getFunction(name);
    if (!fn) {
        if (must_succeed) {
            std::cerr << "Could not find function " << name << " in module\n";
            assert(false);
        } else {
            *result = NULL;
            return;
        }
    }

    debug(2) << "JIT Compiling " << name << "\n";
    void *f = ee->getPointerToFunction(fn);
    if (!f && must_succeed) {
        std::cerr << "Compiling " << name << " returned NULL\n";
        assert(false);
    }

    debug(2) << "Function " << name << " is at " << f << "\n";

    *result = reinterpret_bits<FP>(f);

    #ifdef __arm__
    if (start == NULL) {
        start = (char *)f;
        end = (char *)f;
    } else {
        start = std::min(start, (char *)f);
        end = std::max(end, (char *)f+32);
    }
    #endif
}

}

void JITCompiledModule::compile_module(CodeGen *cg, llvm::Module *m, const string &function_name) {

    // Make the execution engine
    debug(2) << "Creating new execution engine\n";
    string error_string;

    TargetOptions options;
    options.LessPreciseFPMADOption = true;
    options.NoFramePointerElim = false;
    options.AllowFPOpFusion = FPOpFusion::Fast;
    options.UnsafeFPMath = true;
    options.NoInfsFPMath = true;
    options.NoNaNsFPMath = true;
    options.HonorSignDependentRoundingFPMathOption = false;
    options.UseSoftFloat = false;
    options.FloatABIType =
        cg->use_soft_float_abi() ? FloatABI::Soft : FloatABI::Hard;
    options.NoZerosInBSS = false;
    options.GuaranteedTailCallOpt = false;
    options.DisableTailCalls = false;
    options.StackAlignmentOverride = 0;
    options.TrapFuncName = "";
    options.PositionIndependentExecutable = true;
    options.EnableSegmentedStacks = false;
    options.UseInitArray = false;

    EngineBuilder engine_builder(m);
    engine_builder.setTargetOptions(options);
    engine_builder.setErrorStr(&error_string);
    engine_builder.setEngineKind(EngineKind::JIT);
    #ifdef USE_MCJIT
    engine_builder.setUseMCJIT(true);
    JITMemoryManager *memory_manager = JITMemoryManager::CreateDefaultMemManager();
    engine_builder.setJITMemoryManager(memory_manager);
    #else
    engine_builder.setUseMCJIT(false);
    #endif
    engine_builder.setOptLevel(CodeGenOpt::Aggressive);
    engine_builder.setMCPU(cg->mcpu());
    engine_builder.setMAttrs(vec<string>(cg->mattrs()));
    ExecutionEngine *ee = engine_builder.create();
    if (!ee) std::cerr << error_string << "\n";
    assert(ee && "Couldn't create execution engine");

    #ifdef __arm__
    start = end = NULL;
    #endif

    // Do any target-specific initialization
    cg->jit_init(ee, m);

    // Retrieve function pointers from the compiled module (which also
    // triggers compilation)
    debug(1) << "JIT compiling...\n";

    hook_up_function_pointer(ee, m, function_name, true, &function);

    void *function_address = reinterpret_bits<void *>(function);
    debug(1) << "JIT compiled function pointer " << function_address << "\n";

    hook_up_function_pointer(ee, m, function_name + "_jit_wrapper", true, &wrapped_function);
    hook_up_function_pointer(ee, m, "halide_copy_to_host", false, &copy_to_host);
    hook_up_function_pointer(ee, m, "halide_copy_to_dev", false, &copy_to_dev);
    hook_up_function_pointer(ee, m, "halide_dev_free", false, &free_dev_buffer);
    hook_up_function_pointer(ee, m, "halide_set_error_handler", true, &set_error_handler);
    hook_up_function_pointer(ee, m, "halide_set_custom_allocator", true, &set_custom_allocator);
    hook_up_function_pointer(ee, m, "halide_set_custom_do_par_for", true, &set_custom_do_par_for);
    hook_up_function_pointer(ee, m, "halide_set_custom_do_task", true, &set_custom_do_task);
    hook_up_function_pointer(ee, m, "halide_set_custom_trace", true, &set_custom_trace);
    hook_up_function_pointer(ee, m, "halide_set_random_seed", true, &set_random_seed);
    hook_up_function_pointer(ee, m, "halide_shutdown_thread_pool", true, &shutdown_thread_pool);

    debug(2) << "Finalizing object\n";
    ee->finalizeObject();

    // Stash the various objects that need to stay alive behind a reference-counted pointer.
    module = new JITModuleHolder(ee, m, shutdown_thread_pool);

    // Do any target-specific post-compilation module meddling
    cg->jit_finalize(ee, m, &module.ptr->cleanup_routines);

    #ifdef __arm__
    // Flush each function from the dcache so that it gets pulled into
    // the icache correctly.

    // finalizeMemory should have done the trick, but as of Aug 28
    // 2013, it doesn't work unless we also manually flush the
    // cache. Otherwise the icache's view of the code is missing the
    // relocations, which gets really confusing to debug, because
    // gdb's view of the code uses the dcache, so the disassembly
    // isn't right.
    debug(2) << "Flushing cache from " << (void *)start
             << " to " << (void *)end << "\n";
    __clear_cache(start, end);
    #endif

    // TODO: I don't think this is necessary, we shouldn't have any static constructors
    // ee->runStaticConstructorsDestructors(false);

}

}
}
<commit_msg>Changed clear_cache to the builtin version<commit_after>#include <string>
#include <stdint.h>

#include "buffer_t.h"
#include "JITCompiledModule.h"
#include "CodeGen.h"
#include "LLVM_Headers.h"
#include "Debug.h"

namespace Halide {
namespace Internal {

using std::string;

using namespace llvm;

// Wraps an execution engine. Takes ownership of the given module and
// the memory for jit compiled code.
class JITModuleHolder {
public:
    mutable RefCount ref_count;

    JITModuleHolder(llvm::ExecutionEngine *ee, llvm::Module *m, void (*stop_threads)()) :
        execution_engine(ee),
        module(m),
        context(&m->getContext()),
        shutdown_thread_pool(stop_threads) {
    }

    ~JITModuleHolder() {
        for (size_t i = 0; i < cleanup_routines.size(); i++) {
            void *ptr = reinterpret_bits<void *>(cleanup_routines[i]);
            debug(1) << "Calling target specific cleanup routine at " << ptr << "\n";
            (*cleanup_routines[i])();
        }

        shutdown_thread_pool();
        delete execution_engine;
        delete context;
        // No need to delete the module - deleting the execution engine should take care of that.
    }

    ExecutionEngine *execution_engine;
    Module *module;
    LLVMContext *context;
    void (*shutdown_thread_pool)();

    /** Do any target-specific module cleanup. */
    std::vector<void (*)()> cleanup_routines;
};

template<>
EXPORT RefCount &ref_count<JITModuleHolder>(const JITModuleHolder *f) {return f->ref_count;}

template<>
EXPORT void destroy<JITModuleHolder>(const JITModuleHolder *f) {delete f;}

namespace {

#ifdef __arm__
// On ARM we need to track the addresses of all the functions we
// retrieve so that we can flush the icache.
char *start, *end;
#endif

// Retrieve a function pointer from an llvm module, possibly by
// compiling it. Returns it by assigning to the last argument.
template<typename FP>
void hook_up_function_pointer(ExecutionEngine *ee, Module *mod, const string &name, bool must_succeed, FP *result) {

    assert(mod && ee);

    debug(2) << "Retrieving " << name << " from module\n";
    llvm::Function *fn = mod->getFunction(name);
    if (!fn) {
        if (must_succeed) {
            std::cerr << "Could not find function " << name << " in module\n";
            assert(false);
        } else {
            *result = NULL;
            return;
        }
    }

    debug(2) << "JIT Compiling " << name << "\n";
    void *f = ee->getPointerToFunction(fn);
    if (!f && must_succeed) {
        std::cerr << "Compiling " << name << " returned NULL\n";
        assert(false);
    }

    debug(2) << "Function " << name << " is at " << f << "\n";

    *result = reinterpret_bits<FP>(f);

    #ifdef __arm__
    if (start == NULL) {
        start = (char *)f;
        end = (char *)f;
    } else {
        start = std::min(start, (char *)f);
        end = std::max(end, (char *)f+32);
    }
    #endif
}

}

void JITCompiledModule::compile_module(CodeGen *cg, llvm::Module *m, const string &function_name) {

    // Make the execution engine
    debug(2) << "Creating new execution engine\n";
    string error_string;

    TargetOptions options;
    options.LessPreciseFPMADOption = true;
    options.NoFramePointerElim = false;
    options.AllowFPOpFusion = FPOpFusion::Fast;
    options.UnsafeFPMath = true;
    options.NoInfsFPMath = true;
    options.NoNaNsFPMath = true;
    options.HonorSignDependentRoundingFPMathOption = false;
    options.UseSoftFloat = false;
    options.FloatABIType =
        cg->use_soft_float_abi() ? FloatABI::Soft : FloatABI::Hard;
    options.NoZerosInBSS = false;
    options.GuaranteedTailCallOpt = false;
    options.DisableTailCalls = false;
    options.StackAlignmentOverride = 0;
    options.TrapFuncName = "";
    options.PositionIndependentExecutable = true;
    options.EnableSegmentedStacks = false;
    options.UseInitArray = false;

    EngineBuilder engine_builder(m);
    engine_builder.setTargetOptions(options);
    engine_builder.setErrorStr(&error_string);
    engine_builder.setEngineKind(EngineKind::JIT);
    #ifdef USE_MCJIT
    engine_builder.setUseMCJIT(true);
    JITMemoryManager *memory_manager = JITMemoryManager::CreateDefaultMemManager();
    engine_builder.setJITMemoryManager(memory_manager);
    #else
    engine_builder.setUseMCJIT(false);
    #endif
    engine_builder.setOptLevel(CodeGenOpt::Aggressive);
    engine_builder.setMCPU(cg->mcpu());
    engine_builder.setMAttrs(vec<string>(cg->mattrs()));
    ExecutionEngine *ee = engine_builder.create();
    if (!ee) std::cerr << error_string << "\n";
    assert(ee && "Couldn't create execution engine");

    #ifdef __arm__
    start = end = NULL;
    #endif

    // Do any target-specific initialization
    cg->jit_init(ee, m);

    // Retrieve function pointers from the compiled module (which also
    // triggers compilation)
    debug(1) << "JIT compiling...\n";

    hook_up_function_pointer(ee, m, function_name, true, &function);

    void *function_address = reinterpret_bits<void *>(function);
    debug(1) << "JIT compiled function pointer " << function_address << "\n";

    hook_up_function_pointer(ee, m, function_name + "_jit_wrapper", true, &wrapped_function);
    hook_up_function_pointer(ee, m, "halide_copy_to_host", false, &copy_to_host);
    hook_up_function_pointer(ee, m, "halide_copy_to_dev", false, &copy_to_dev);
    hook_up_function_pointer(ee, m, "halide_dev_free", false, &free_dev_buffer);
    hook_up_function_pointer(ee, m, "halide_set_error_handler", true, &set_error_handler);
    hook_up_function_pointer(ee, m, "halide_set_custom_allocator", true, &set_custom_allocator);
    hook_up_function_pointer(ee, m, "halide_set_custom_do_par_for", true, &set_custom_do_par_for);
    hook_up_function_pointer(ee, m, "halide_set_custom_do_task", true, &set_custom_do_task);
    hook_up_function_pointer(ee, m, "halide_set_custom_trace", true, &set_custom_trace);
    hook_up_function_pointer(ee, m, "halide_set_random_seed", true, &set_random_seed);
    hook_up_function_pointer(ee, m, "halide_shutdown_thread_pool", true, &shutdown_thread_pool);

    debug(2) << "Finalizing object\n";
    ee->finalizeObject();

    // Stash the various objects that need to stay alive behind a reference-counted pointer.
    module = new JITModuleHolder(ee, m, shutdown_thread_pool);

    // Do any target-specific post-compilation module meddling
    cg->jit_finalize(ee, m, &module.ptr->cleanup_routines);

    #ifdef __arm__
    // Flush each function from the dcache so that it gets pulled into
    // the icache correctly.

    // finalizeMemory should have done the trick, but as of Aug 28
    // 2013, it doesn't work unless we also manually flush the
    // cache. Otherwise the icache's view of the code is missing the
    // relocations, which gets really confusing to debug, because
    // gdb's view of the code uses the dcache, so the disassembly
    // isn't right.
    debug(2) << "Flushing cache from " << (void *)start
             << " to " << (void *)end << "\n";
    __builtin___clear_cache(start, end);
    #endif

    // TODO: I don't think this is necessary, we shouldn't have any static constructors
    // ee->runStaticConstructorsDestructors(false);

}

}
}
<|endoftext|>


<commit_before>/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

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

 QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

/// @file
///     @author Don Gagne <don@thegagnes.com>

#include "AutoPilotPlugin.h"

AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
    QObject(parent),
    _uas(uas),
    _pluginReady(false)
{
    Q_ASSERT(_uas);
}

bool AutoPilotPlugin::factExists(FactSystem::Provider_t provider, int componentId, const QString& name)
{
    switch (provider) {
        case FactSystem::ParameterProvider:
            return getParameterLoader()->factExists(componentId, name);

        // Other providers will go here once they come online
    }
}

Fact* AutoPilotPlugin::getFact(FactSystem::Provider_t provider, int componentId, const QString& name)
{
    switch (provider) {
        case FactSystem::ParameterProvider:
            return getParameterLoader()->getFact(componentId, name);

        // Other providers will go here once they come online
    }
}
<commit_msg>Fix compiler warnings<commit_after>/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

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

 QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

/// @file
///     @author Don Gagne <don@thegagnes.com>

#include "AutoPilotPlugin.h"

AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
    QObject(parent),
    _uas(uas),
    _pluginReady(false)
{
    Q_ASSERT(_uas);
}

bool AutoPilotPlugin::factExists(FactSystem::Provider_t provider, int componentId, const QString& name)
{
    switch (provider) {
        case FactSystem::ParameterProvider:
            return getParameterLoader()->factExists(componentId, name);

        // Other providers will go here once they come online
    }

    Q_ASSERT(false);
    return false;
}

Fact* AutoPilotPlugin::getFact(FactSystem::Provider_t provider, int componentId, const QString& name)
{
    switch (provider) {
        case FactSystem::ParameterProvider:
            return getParameterLoader()->getFact(componentId, name);

        // Other providers will go here once they come online
    }

    Q_ASSERT(false);
    return false;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <babylon/asio/asio.h>
#include <babylon/core/string.h>
#include <babylon/core/filesystem.h>
#include <babylon/babylon_common.h>

#include <thread>
#include <iostream>

std::string assets_folder = std::string(BABYLON_REPO_DIR) + std::string("/assets/");

std::string textUrl = std::string("file:/") + assets_folder + "/samples_info.json";
std::string binaryUrl = std::string("file:/") + assets_folder
  + "/glTF-Sample-Models/2.0/AntiqueCamera/glTF/camera_camera_Normal.png";
std::string nonExistingFileUrl = "file:/non_existing_file";

std::vector<std::string> textFilesUrls = {
  textUrl, nonExistingFileUrl, textUrl, textUrl, nonExistingFileUrl, textUrl, nonExistingFileUrl
};

std::vector<std::string> binaryFilesUrls  = {
  binaryUrl, nonExistingFileUrl, binaryUrl, binaryUrl, nonExistingFileUrl, binaryUrl, nonExistingFileUrl
};

void SampleApplicationLoop()
{
  auto mainThreadId = std::this_thread::get_id();

  int nb_success_text = 0;
  int nb_success_binary = 0;
  int nb_error = 0;
  int nb_calls_to_progress = 0;

  // Sample callbacks that will be called *synchronously*
  auto onSuccessText = [&nb_success_text, mainThreadId](const std::string& /*textContent*/) {
    auto thisThreadId = std::this_thread::get_id();
    assert(thisThreadId == mainThreadId);
    ++nb_success_text;
  };
  auto onSuccessBinary = [&nb_success_binary, mainThreadId](const BABYLON::ArrayBuffer& /*data*/) {
    auto thisThreadId = std::this_thread::get_id();
    assert(thisThreadId == mainThreadId);
    ++nb_success_binary;
  };
  auto onError = [&nb_error, mainThreadId](const std::string& /*message*/) {
    auto thisThreadId = std::this_thread::get_id();
    assert(thisThreadId == mainThreadId);
    ++nb_error;
  };
  auto onProgress = [&nb_calls_to_progress, mainThreadId](bool /*lengthComputable*/, size_t /*loaded*/, size_t /*total*/) {
    auto thisThreadId = std::this_thread::get_id();
    assert(thisThreadId == mainThreadId);
    ++nb_calls_to_progress;
  };

  // Sample application main loop
  bool applicationShallExit = false;
  while(!applicationShallExit)
  {
    if (!textFilesUrls.empty())
    {
      std::string url = textFilesUrls.back();
      textFilesUrls.pop_back();
      BABYLON::asio::LoadUrlAsync_Text(url, onSuccessText, onError, onProgress);
    }
    if (!binaryFilesUrls.empty())
    {
      std::string url = binaryFilesUrls.back();
      binaryFilesUrls.pop_back();
      BABYLON::asio::LoadUrlAsync_Binary(url, onSuccessBinary, onError, onProgress);
    }

    applicationShallExit =
      textFilesUrls.empty() && binaryFilesUrls.empty() && ! BABYLON::asio::HasRemainingTasks();

    // Remember to call asio::HeartBeat_Sync() in your application main loop:
    // if there are pending callbacks, this will call the first one *synchronously*
    BABYLON::asio::HeartBeat_Sync();
  };

  EXPECT_EQ(nb_success_text, 4);
  EXPECT_EQ(nb_success_binary, 4);
  EXPECT_EQ(nb_error, 6);
  EXPECT_GT(nb_calls_to_progress, 10);
//  printf("nb_success_text=%i, nb_success_binary=%i, nb_error=%i nb_calls_to_progress=%i\n",
//    nb_success_text, nb_success_binary, nb_error, nb_calls_to_progress);
}

TEST(async_requests, SampleApplicationLoop)
{
  SampleApplicationLoop();
}

TEST(async_requests, LoadText)
{
#if 0 // This code works, but features no real google test call
  std::cout << "\n";
  auto onSuccessText = [](const std::string& textContent) {
    std::cout << "\n==>\n" << textContent << "\n<==\n";
  };
  auto onError = [](const std::string& message) {
    std::cout << "Error:" << message << "!!!\n";
  };
  auto onProgress = [](bool lengthComputable, size_t loaded, size_t total) {
    std::cout << "onProgress " << loaded << " / " << total << " lengthComputable: " << lengthComputable << "\n";
  };

  BABYLON::asio::LoadUrlAsync_Text(textUrl, onSuccessText, onError, onProgress);
  BABYLON::asio::Service_WaitAll_Sync();
#endif
}
<commit_msg>improve asio_test (EXPECT_EQ thread_ids)<commit_after>#include <gtest/gtest.h>
#include <babylon/asio/asio.h>
#include <babylon/core/string.h>
#include <babylon/core/filesystem.h>
#include <babylon/babylon_common.h>

#include <thread>
#include <iostream>

std::string assets_folder = std::string(BABYLON_REPO_DIR) + std::string("/assets/");

std::string textUrl = std::string("file:/") + assets_folder + "/samples_info.json";
std::string binaryUrl = std::string("file:/") + assets_folder
  + "/glTF-Sample-Models/2.0/AntiqueCamera/glTF/camera_camera_Normal.png";
std::string nonExistingFileUrl = "file:/non_existing_file";

std::vector<std::string> textFilesUrls = {
  textUrl, nonExistingFileUrl, textUrl, textUrl, nonExistingFileUrl, textUrl, nonExistingFileUrl
};

std::vector<std::string> binaryFilesUrls  = {
  binaryUrl, nonExistingFileUrl, binaryUrl, binaryUrl, nonExistingFileUrl, binaryUrl, nonExistingFileUrl
};

void SampleApplicationLoop()
{
  auto mainThreadId = std::this_thread::get_id();

  int nb_success_text = 0;
  int nb_success_binary = 0;
  int nb_error = 0;
  int nb_calls_to_progress = 0;

  // Sample callbacks that will be called *synchronously*
  auto onSuccessText = [&nb_success_text, mainThreadId](const std::string& /*textContent*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_success_text;
  };
  auto onSuccessBinary = [&nb_success_binary, mainThreadId](const BABYLON::ArrayBuffer& /*data*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_success_binary;
  };
  auto onError = [&nb_error, mainThreadId](const std::string& /*message*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_error;
  };
  auto onProgress = [&nb_calls_to_progress, mainThreadId](bool /*lengthComputable*/, size_t /*loaded*/, size_t /*total*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_calls_to_progress;
  };

  // Sample application main loop
  bool applicationShallExit = false;
  while(!applicationShallExit)
  {
    if (!textFilesUrls.empty())
    {
      std::string url = textFilesUrls.back();
      textFilesUrls.pop_back();
      BABYLON::asio::LoadUrlAsync_Text(url, onSuccessText, onError, onProgress);
    }
    if (!binaryFilesUrls.empty())
    {
      std::string url = binaryFilesUrls.back();
      binaryFilesUrls.pop_back();
      BABYLON::asio::LoadUrlAsync_Binary(url, onSuccessBinary, onError, onProgress);
    }

    applicationShallExit =
      textFilesUrls.empty() && binaryFilesUrls.empty() && ! BABYLON::asio::HasRemainingTasks();

    // Remember to call asio::HeartBeat_Sync() in your application main loop:
    // if there are pending callbacks, this will call the first one *synchronously*
    BABYLON::asio::HeartBeat_Sync();
  };

  EXPECT_EQ(nb_success_text, 4);
  EXPECT_EQ(nb_success_binary, 4);
  EXPECT_EQ(nb_error, 6);
  EXPECT_GT(nb_calls_to_progress, 10);
//  printf("nb_success_text=%i, nb_success_binary=%i, nb_error=%i nb_calls_to_progress=%i\n",
//    nb_success_text, nb_success_binary, nb_error, nb_calls_to_progress);
}

TEST(async_requests, SampleApplicationLoop)
{
  SampleApplicationLoop();
}

TEST(async_requests, LoadText)
{
#if 0 // This code works, but features no real google test call
  std::cout << "\n";
  auto onSuccessText = [](const std::string& textContent) {
    std::cout << "\n==>\n" << textContent << "\n<==\n";
  };
  auto onError = [](const std::string& message) {
    std::cout << "Error:" << message << "!!!\n";
  };
  auto onProgress = [](bool lengthComputable, size_t loaded, size_t total) {
    std::cout << "onProgress " << loaded << " / " << total << " lengthComputable: " << lengthComputable << "\n";
  };

  BABYLON::asio::LoadUrlAsync_Text(textUrl, onSuccessText, onError, onProgress);
  BABYLON::asio::Service_WaitAll_Sync();
#endif
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
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.
*/

// Test under-development.  Calls async mem-copy API, experiment with functionality.

#include "hip_runtime.h"
#include "test_common.h"
unsigned p_streams = 2;

void simpleNegTest()
{
    printf ("testing: %s\n",__func__);
    hipError_t e;
    float *A_malloc, *A_pinned, *A_d;

    size_t Nbytes = N*sizeof(float);
    A_malloc = (float*)malloc(Nbytes);
    HIPCHECK(hipHostMalloc((void**)&A_pinned, Nbytes, hipHostMallocDefault));
    A_d = NULL;
    HIPCHECK(hipMalloc(&A_d, Nbytes));
    HIPASSERT(A_d != NULL);
    // Can't use default with async copy
    e = hipMemcpyAsync(A_pinned, A_d, Nbytes, hipMemcpyDefault, NULL);
//    HIPASSERT (e == hipSuccess);

    // Not sure what happens here, the memory must be pinned.
    e = hipMemcpyAsync(A_malloc, A_d, Nbytes, hipMemcpyHostToDevice, NULL);

    printf ("  async memcpy of A_malloc to A_d. Result=%d\n", e);
    //HIPASSERT (e==hipErrorInvalidValue);
}

class Pinned;
class Unpinned;

template <typename T> struct HostTraits;

template<>
struct HostTraits<Pinned>
{
    static const char *Name() { return "Pinned"; } ;

    static void *Alloc(size_t sizeBytes) {
        void *p;
        HIPCHECK(hipHostMalloc((void**)&p, sizeBytes, hipHostMallocDefault));
        return p;
    };
};

template<typename T>
__global__ void
addK (hipLaunchParm lp, T *A, T K, size_t numElements)
{
    size_t offset = (hipBlockIdx_x * hipBlockDim_x + hipThreadIdx_x);
    size_t stride = hipBlockDim_x * hipGridDim_x ;

    for (size_t i=offset; i<numElements; i+=stride) {
        A[i] = A[i] + K;
	}
}

//---
//Tests propert dependency resolution between H2D and D2H commands in same stream:
//IN: numInflight : number of copies inflight at any time:
//IN: numPongs = number of iterations to run (iteration)
template<typename T, class AllocType>
void test_pingpong(hipStream_t stream, size_t numElements, int numInflight, int numPongs, bool doHostSide)
{
    HIPASSERT(numElements % numInflight == 0); // Must be evenly divisible.
    size_t Nbytes = numElements*sizeof(T);
    size_t eachCopyElements = numElements / numInflight;
    size_t eachCopyBytes = eachCopyElements * sizeof(T);

    unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, numElements);

    printf ("-----------------------------------------------------------------------------------------------\n");
    printf ("testing: %s<%s>  Nbytes=%zu (%6.1f MB) numPongs=%d numInflight=%d eachCopyElements=%zu eachCopyBytes=%zu\n",
            __func__, HostTraits<AllocType>::Name(), Nbytes, (double)(Nbytes)/1024.0/1024.0, numPongs, numInflight, eachCopyElements, eachCopyBytes);

    T *A_h = NULL;
    T *A_d = NULL;

    A_h = (T*)(HostTraits<AllocType>::Alloc(Nbytes));
    HIPCHECK(hipMalloc(&A_d, Nbytes));

    // Initialize the host array:
    const T initValue = 13;
    const T deviceConst = 2;
    const T hostConst = 10000;
    for (size_t i=0; i<numElements; i++) {
        A_h[i] = initValue + i;
    }

    for (int k=0; k<numPongs; k++ ) {
        for (int i=0; i<numInflight; i++) {
            HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
            HIPCHECK(hipMemcpyAsync(&A_d[i*eachCopyElements], &A_h[i*eachCopyElements], eachCopyBytes, hipMemcpyHostToDevice, stream));
        }

        hipLaunchKernel(addK<T>, dim3(blocks), dim3(threadsPerBlock), 0, stream,   A_d, 2, numElements);

        for (int i=0; i<numInflight; i++ ) {
            HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
            HIPCHECK(hipMemcpyAsync(&A_h[i*eachCopyElements], &A_d[i*eachCopyElements], eachCopyBytes, hipMemcpyDeviceToHost, stream));
        }

        if (doHostSide) {
            assert(0);
#if 0
            hipEvent_t e;
            HIPCHECK(hipEventCreate(&e));
#endif
            HIPCHECK(hipDeviceSynchronize());
            for (size_t i=0; i<numElements; i++) {
                A_h[i] += hostConst;
            }
        }
    };

    HIPCHECK(hipDeviceSynchronize());

    // Verify we copied back all the data correctly:
    for (size_t i=0; i<numElements; i++) {
        T gold = initValue + i;
        // Perform calcs in same order as test above to replicate FP order-of-operations:
        for (int k=0; k<numPongs; k++) {
            gold += deviceConst;
            if (doHostSide) {
                gold += hostConst;
            }
        }

        if (gold != A_h[i]) {
            std::cout << i << ": gold=" << gold << " out=" << A_h[i] << std::endl;
            HIPASSERT(gold == A_h[i]);
        }
    }

    HIPCHECK(hipHostFree(A_h));
    HIPCHECK(hipFree(A_d));
}

//---
//Send many async copies to the same stream.
//This requires runtime to keep track of many outstanding commands, and in the case of HCC requires growing/tracking the signal pool:
template<typename T>
void test_manyInflightCopies(hipStream_t stream, int numElements, int numCopies, bool syncBetweenCopies)
{
    size_t Nbytes = numElements*sizeof(T);
    size_t eachCopyElements = numElements / numCopies;
    size_t eachCopyBytes = eachCopyElements * sizeof(T);

    printf ("-----------------------------------------------------------------------------------------------\n");
    printf ("testing: %s  Nbytes=%zu (%6.1f MB) numCopies=%d eachCopyElements=%zu eachCopyBytes=%zu\n",
            __func__, Nbytes, (double)(Nbytes)/1024.0/1024.0, numCopies, eachCopyElements, eachCopyBytes);

    T *A_d;
    T *A_h1, *A_h2;

    HIPCHECK(hipHostMalloc((void**)&A_h1, Nbytes, hipHostMallocDefault));
    HIPCHECK(hipHostMalloc((void**)&A_h2, Nbytes, hipHostMallocDefault));
    HIPCHECK(hipMalloc(&A_d, Nbytes));

    for (int i=0; i<numElements; i++) {
        A_h1[i] = 3.14f + static_cast<T> (i);
    }

    //stream=0; // fixme TODO

    for (int i=0; i<numCopies; i++)
    {
        HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
        HIPCHECK(hipMemcpyAsync(&A_d[i*eachCopyElements], &A_h1[i*eachCopyElements], eachCopyBytes, hipMemcpyHostToDevice, stream));
    }

    if (syncBetweenCopies) {
        HIPCHECK(hipDeviceSynchronize());
    }

    for (int i=0; i<numCopies; i++)
    {
        HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
        HIPCHECK(hipMemcpyAsync(&A_h2[i*eachCopyElements], &A_d[i*eachCopyElements], eachCopyBytes, hipMemcpyDeviceToHost, stream));
    }

    HIPCHECK(hipDeviceSynchronize());

    // Verify we copied back all the data correctly:
    for (int i=0; i<numElements; i++) {
        HIPASSERT(A_h1[i] == A_h2[i]);
    }

    HIPCHECK(hipHostFree(A_h1));
    HIPCHECK(hipHostFree(A_h2));
    HIPCHECK(hipFree(A_d));
}

//---
//Classic example showing how to overlap data transfer with compute.
//We divide the work into "chunks" and create a stream for each chunk.
//Each chunk then runs a H2D copy, followed by kernel execution, followed by D2H copyback.
//Work in separate streams is independent which enables concurrency.

// IN: nStreams : number of streams to use for the test
// IN :useNullStream - use NULL stream.  Synchronizes everything.
// IN: useSyncMemcpyH2D - use sync memcpy (no overlap) for H2D
// IN: useSyncMemcpyD2H - use sync memcpy (no overlap) for D2H
void test_chunkedAsyncExample(int nStreams, bool useNullStream, bool useSyncMemcpyH2D, bool useSyncMemcpyD2H)
{

    size_t Nbytes = N*sizeof(int);
    printf ("testing: %s(useNullStream=%d, useSyncMemcpyH2D=%d, useSyncMemcpyD2H=%d)  ",__func__, useNullStream, useSyncMemcpyH2D, useSyncMemcpyD2H);
    printf ("Nbytes=%zu (%6.1f MB)\n", Nbytes, (double)(Nbytes)/1024.0/1024.0);

    int *A_d, *B_d, *C_d;
    int *A_h, *B_h, *C_h;

    HipTest::initArrays (&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, true);

    unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);

    hipStream_t *stream = (hipStream_t*)malloc(sizeof(hipStream_t) * nStreams);
    if (useNullStream) {
        nStreams = 1;
        stream[0] = NULL;
    } else  {
        for (int i = 0; i < nStreams; ++i) {
            HIPCHECK (hipStreamCreate(&stream[i]));
        }
    }

    size_t workLeft = N;
    size_t workPerStream = N / nStreams;
    for (int i = 0; i < nStreams; ++i) {
        size_t work = (workLeft < workPerStream) ? workLeft : workPerStream;
        size_t workBytes = work * sizeof(int);

        size_t offset = i*workPerStream;
        HIPASSERT(A_d + offset < A_d + Nbytes);
        HIPASSERT(B_d + offset < B_d + Nbytes);
        HIPASSERT(C_d + offset < C_d + Nbytes);
        if (useSyncMemcpyH2D) {
            HIPCHECK ( hipMemcpy(&A_d[offset], &A_h[offset], workBytes, hipMemcpyHostToDevice));
            HIPCHECK ( hipMemcpy(&B_d[offset], &B_h[offset], workBytes, hipMemcpyHostToDevice));
        } else {
            HIPCHECK ( hipMemcpyAsync(&A_d[offset], &A_h[offset], workBytes, hipMemcpyHostToDevice, stream[i]));
            HIPCHECK ( hipMemcpyAsync(&B_d[offset], &B_h[offset], workBytes, hipMemcpyHostToDevice, stream[i]));
        };

        hipLaunchKernel(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), 0, stream[i], &A_d[offset], &B_d[offset], &C_d[offset], work);

        if (useSyncMemcpyD2H) {
            HIPCHECK ( hipMemcpy(&C_h[offset], &C_d[offset], workBytes, hipMemcpyDeviceToHost));
        } else {
            HIPCHECK ( hipMemcpyAsync(&C_h[offset], &C_d[offset], workBytes, hipMemcpyDeviceToHost, stream[i]));
        }
    }

    HIPCHECK (hipDeviceSynchronize());

    HipTest::checkVectorADD(A_h, B_h, C_h, N);

    HipTest::freeArrays (A_d, B_d, C_d, A_h, B_h, C_h, true);

    free(stream);
};

//---
//Parse arguments specific to this test.
void parseMyArguments(int argc, char *argv[])
{
    int more_argc = HipTest::parseStandardArguments(argc, argv, false);

    // parse args for this test:
    for (int i = 1; i < more_argc; i++) {
        const char *arg = argv[i];

        if (!strcmp(arg, "--streams")) {
            if (++i >= argc || !HipTest::parseUInt(argv[i], &p_streams)) {
               failed("Bad streams argument");
            }
        } else {
            failed("Bad argument '%s'", arg);
        }
    };
};

int main(int argc, char *argv[])
{
    HipTest::parseStandardArguments(argc, argv, true);
    parseMyArguments(argc, argv);

    printf ("info: set device to %d  tests=%x\n", p_gpuDevice, p_tests);
    HIPCHECK(hipSetDevice(p_gpuDevice));

    if (p_tests & 0x01) {
        simpleNegTest();
    }

    if (p_tests & 0x02) {
        hipStream_t stream;
        HIPCHECK (hipStreamCreate(&stream));

        test_manyInflightCopies<float>(stream, 1024,   16,  true);
        test_manyInflightCopies<float>(stream, 1024,    4,  true); // verify we re-use the same entries instead of growing pool.
        test_manyInflightCopies<float>(stream, 1024*8, 64, false);

        HIPCHECK(hipStreamDestroy(stream));
    }

    if (p_tests & 0x04) {
        test_chunkedAsyncExample(p_streams, true, true, true); // Easy sync version
        test_chunkedAsyncExample(p_streams, false, true, true); // Easy sync version
        test_chunkedAsyncExample(p_streams, false, false, true); // Some async
        test_chunkedAsyncExample(p_streams, false, false, false); // All async
    }

    if (p_tests & 0x08) {
        hipStream_t stream;
        HIPCHECK (hipStreamCreate(&stream));

//        test_pingpong<int, Pinned>(stream, 1024*1024*32, 1, 1, false);
//        test_pingpong<int, Pinned>(stream, 1024*1024*32, 1, 10, false);

        HIPCHECK(hipStreamDestroy(stream));
    }

    passed();

}
<commit_msg>fix test args<commit_after>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
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.
*/

// Test under-development.  Calls async mem-copy API, experiment with functionality.

#include "hip_runtime.h"
#include "test_common.h"
unsigned p_streams = 2;

void simpleNegTest()
{
    printf ("testing: %s\n",__func__);
    hipError_t e;
    float *A_malloc, *A_pinned, *A_d;

    size_t Nbytes = N*sizeof(float);
    A_malloc = (float*)malloc(Nbytes);
    HIPCHECK(hipHostMalloc((void**)&A_pinned, Nbytes, hipHostMallocDefault));
    A_d = NULL;
    HIPCHECK(hipMalloc(&A_d, Nbytes));
    HIPASSERT(A_d != NULL);
    // Can't use default with async copy
    e = hipMemcpyAsync(A_pinned, A_d, Nbytes, hipMemcpyDefault, NULL);
//    HIPASSERT (e == hipSuccess);

    // Not sure what happens here, the memory must be pinned.
    e = hipMemcpyAsync(A_malloc, A_d, Nbytes, hipMemcpyHostToDevice, NULL);

    printf ("  async memcpy of A_malloc to A_d. Result=%d\n", e);
    //HIPASSERT (e==hipErrorInvalidValue);
}

class Pinned;
class Unpinned;

template <typename T> struct HostTraits;

template<>
struct HostTraits<Pinned>
{
    static const char *Name() { return "Pinned"; } ;

    static void *Alloc(size_t sizeBytes) {
        void *p;
        HIPCHECK(hipHostMalloc((void**)&p, sizeBytes, hipHostMallocDefault));
        return p;
    };
};

template<typename T>
__global__ void
addK (hipLaunchParm lp, T *A, T K, size_t numElements)
{
    size_t offset = (hipBlockIdx_x * hipBlockDim_x + hipThreadIdx_x);
    size_t stride = hipBlockDim_x * hipGridDim_x ;

    for (size_t i=offset; i<numElements; i+=stride) {
        A[i] = A[i] + K;
	}
}

//---
//Tests propert dependency resolution between H2D and D2H commands in same stream:
//IN: numInflight : number of copies inflight at any time:
//IN: numPongs = number of iterations to run (iteration)
template<typename T, class AllocType>
void test_pingpong(hipStream_t stream, size_t numElements, int numInflight, int numPongs, bool doHostSide)
{
    HIPASSERT(numElements % numInflight == 0); // Must be evenly divisible.
    size_t Nbytes = numElements*sizeof(T);
    size_t eachCopyElements = numElements / numInflight;
    size_t eachCopyBytes = eachCopyElements * sizeof(T);

    unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, numElements);

    printf ("-----------------------------------------------------------------------------------------------\n");
    printf ("testing: %s<%s>  Nbytes=%zu (%6.1f MB) numPongs=%d numInflight=%d eachCopyElements=%zu eachCopyBytes=%zu\n",
            __func__, HostTraits<AllocType>::Name(), Nbytes, (double)(Nbytes)/1024.0/1024.0, numPongs, numInflight, eachCopyElements, eachCopyBytes);

    T *A_h = NULL;
    T *A_d = NULL;

    A_h = (T*)(HostTraits<AllocType>::Alloc(Nbytes));
    HIPCHECK(hipMalloc(&A_d, Nbytes));

    // Initialize the host array:
    const T initValue = 13;
    const T deviceConst = 2;
    const T hostConst = 10000;
    for (size_t i=0; i<numElements; i++) {
        A_h[i] = initValue + i;
    }

    for (int k=0; k<numPongs; k++ ) {
        for (int i=0; i<numInflight; i++) {
            HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
            HIPCHECK(hipMemcpyAsync(&A_d[i*eachCopyElements], &A_h[i*eachCopyElements], eachCopyBytes, hipMemcpyHostToDevice, stream));
        }

        hipLaunchKernel(addK<T>, dim3(blocks), dim3(threadsPerBlock), 0, stream,   A_d, 2, numElements);

        for (int i=0; i<numInflight; i++ ) {
            HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
            HIPCHECK(hipMemcpyAsync(&A_h[i*eachCopyElements], &A_d[i*eachCopyElements], eachCopyBytes, hipMemcpyDeviceToHost, stream));
        }

        if (doHostSide) {
            assert(0);
#if 0
            hipEvent_t e;
            HIPCHECK(hipEventCreate(&e));
#endif
            HIPCHECK(hipDeviceSynchronize());
            for (size_t i=0; i<numElements; i++) {
                A_h[i] += hostConst;
            }
        }
    };

    HIPCHECK(hipDeviceSynchronize());

    // Verify we copied back all the data correctly:
    for (size_t i=0; i<numElements; i++) {
        T gold = initValue + i;
        // Perform calcs in same order as test above to replicate FP order-of-operations:
        for (int k=0; k<numPongs; k++) {
            gold += deviceConst;
            if (doHostSide) {
                gold += hostConst;
            }
        }

        if (gold != A_h[i]) {
            std::cout << i << ": gold=" << gold << " out=" << A_h[i] << std::endl;
            HIPASSERT(gold == A_h[i]);
        }
    }

    HIPCHECK(hipHostFree(A_h));
    HIPCHECK(hipFree(A_d));
}

//---
//Send many async copies to the same stream.
//This requires runtime to keep track of many outstanding commands, and in the case of HCC requires growing/tracking the signal pool:
template<typename T>
void test_manyInflightCopies(hipStream_t stream, int numElements, int numCopies, bool syncBetweenCopies)
{
    size_t Nbytes = numElements*sizeof(T);
    size_t eachCopyElements = numElements / numCopies;
    size_t eachCopyBytes = eachCopyElements * sizeof(T);

    printf ("-----------------------------------------------------------------------------------------------\n");
    printf ("testing: %s  Nbytes=%zu (%6.1f MB) numCopies=%d eachCopyElements=%zu eachCopyBytes=%zu\n",
            __func__, Nbytes, (double)(Nbytes)/1024.0/1024.0, numCopies, eachCopyElements, eachCopyBytes);

    T *A_d;
    T *A_h1, *A_h2;

    HIPCHECK(hipHostMalloc((void**)&A_h1, Nbytes, hipHostMallocDefault));
    HIPCHECK(hipHostMalloc((void**)&A_h2, Nbytes, hipHostMallocDefault));
    HIPCHECK(hipMalloc(&A_d, Nbytes));

    for (int i=0; i<numElements; i++) {
        A_h1[i] = 3.14f + static_cast<T> (i);
    }

    //stream=0; // fixme TODO

    for (int i=0; i<numCopies; i++)
    {
        HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
        HIPCHECK(hipMemcpyAsync(&A_d[i*eachCopyElements], &A_h1[i*eachCopyElements], eachCopyBytes, hipMemcpyHostToDevice, stream));
    }

    if (syncBetweenCopies) {
        HIPCHECK(hipDeviceSynchronize());
    }

    for (int i=0; i<numCopies; i++)
    {
        HIPASSERT(A_d + i*eachCopyElements < A_d + Nbytes);
        HIPCHECK(hipMemcpyAsync(&A_h2[i*eachCopyElements], &A_d[i*eachCopyElements], eachCopyBytes, hipMemcpyDeviceToHost, stream));
    }

    HIPCHECK(hipDeviceSynchronize());

    // Verify we copied back all the data correctly:
    for (int i=0; i<numElements; i++) {
        HIPASSERT(A_h1[i] == A_h2[i]);
    }

    HIPCHECK(hipHostFree(A_h1));
    HIPCHECK(hipHostFree(A_h2));
    HIPCHECK(hipFree(A_d));
}

//---
//Classic example showing how to overlap data transfer with compute.
//We divide the work into "chunks" and create a stream for each chunk.
//Each chunk then runs a H2D copy, followed by kernel execution, followed by D2H copyback.
//Work in separate streams is independent which enables concurrency.

// IN: nStreams : number of streams to use for the test
// IN :useNullStream - use NULL stream.  Synchronizes everything.
// IN: useSyncMemcpyH2D - use sync memcpy (no overlap) for H2D
// IN: useSyncMemcpyD2H - use sync memcpy (no overlap) for D2H
void test_chunkedAsyncExample(int nStreams, bool useNullStream, bool useSyncMemcpyH2D, bool useSyncMemcpyD2H)
{

    size_t Nbytes = N*sizeof(int);
    printf ("testing: %s(useNullStream=%d, useSyncMemcpyH2D=%d, useSyncMemcpyD2H=%d)  ",__func__, useNullStream, useSyncMemcpyH2D, useSyncMemcpyD2H);
    printf ("Nbytes=%zu (%6.1f MB)\n", Nbytes, (double)(Nbytes)/1024.0/1024.0);

    int *A_d, *B_d, *C_d;
    int *A_h, *B_h, *C_h;

    HipTest::initArrays (&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, true);

    unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);

    hipStream_t *stream = (hipStream_t*)malloc(sizeof(hipStream_t) * nStreams);
    if (useNullStream) {
        nStreams = 1;
        stream[0] = NULL;
    } else  {
        for (int i = 0; i < nStreams; ++i) {
            HIPCHECK (hipStreamCreate(&stream[i]));
        }
    }

    size_t workLeft = N;
    size_t workPerStream = N / nStreams;
    for (int i = 0; i < nStreams; ++i) {
        size_t work = (workLeft < workPerStream) ? workLeft : workPerStream;
        size_t workBytes = work * sizeof(int);

        size_t offset = i*workPerStream;
        HIPASSERT(A_d + offset < A_d + Nbytes);
        HIPASSERT(B_d + offset < B_d + Nbytes);
        HIPASSERT(C_d + offset < C_d + Nbytes);
        if (useSyncMemcpyH2D) {
            HIPCHECK ( hipMemcpy(&A_d[offset], &A_h[offset], workBytes, hipMemcpyHostToDevice));
            HIPCHECK ( hipMemcpy(&B_d[offset], &B_h[offset], workBytes, hipMemcpyHostToDevice));
        } else {
            HIPCHECK ( hipMemcpyAsync(&A_d[offset], &A_h[offset], workBytes, hipMemcpyHostToDevice, stream[i]));
            HIPCHECK ( hipMemcpyAsync(&B_d[offset], &B_h[offset], workBytes, hipMemcpyHostToDevice, stream[i]));
        };

        hipLaunchKernel(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), 0, stream[i], &A_d[offset], &B_d[offset], &C_d[offset], work);

        if (useSyncMemcpyD2H) {
            HIPCHECK ( hipMemcpy(&C_h[offset], &C_d[offset], workBytes, hipMemcpyDeviceToHost));
        } else {
            HIPCHECK ( hipMemcpyAsync(&C_h[offset], &C_d[offset], workBytes, hipMemcpyDeviceToHost, stream[i]));
        }
    }

    HIPCHECK (hipDeviceSynchronize());

    HipTest::checkVectorADD(A_h, B_h, C_h, N);

    HipTest::freeArrays (A_d, B_d, C_d, A_h, B_h, C_h, true);

    free(stream);
};

//---
//Parse arguments specific to this test.
void parseMyArguments(int argc, char *argv[])
{
    int more_argc = HipTest::parseStandardArguments(argc, argv, false);

    // parse args for this test:
    for (int i = 1; i < more_argc; i++) {
        const char *arg = argv[i];

        if (!strcmp(arg, "--streams")) {
            if (++i >= argc || !HipTest::parseUInt(argv[i], &p_streams)) {
               failed("Bad streams argument");
            }
        } else {
            failed("Bad argument '%s'", arg);
        }
    };
};

int main(int argc, char *argv[])
{
    HipTest::parseStandardArguments(argc, argv, false);
    parseMyArguments(argc, argv);

    printf ("info: set device to %d  tests=%x\n", p_gpuDevice, p_tests);
    HIPCHECK(hipSetDevice(p_gpuDevice));

    if (p_tests & 0x01) {
        simpleNegTest();
    }

    if (p_tests & 0x02) {
        hipStream_t stream;
        HIPCHECK (hipStreamCreate(&stream));

        test_manyInflightCopies<float>(stream, 1024,   16,  true);
        test_manyInflightCopies<float>(stream, 1024,    4,  true); // verify we re-use the same entries instead of growing pool.
        test_manyInflightCopies<float>(stream, 1024*8, 64, false);

        HIPCHECK(hipStreamDestroy(stream));
    }

    if (p_tests & 0x04) {
        test_chunkedAsyncExample(p_streams, true, true, true); // Easy sync version
        test_chunkedAsyncExample(p_streams, false, true, true); // Easy sync version
        test_chunkedAsyncExample(p_streams, false, false, true); // Some async
        test_chunkedAsyncExample(p_streams, false, false, false); // All async
    }

    if (p_tests & 0x08) {
        hipStream_t stream;
        HIPCHECK (hipStreamCreate(&stream));

//        test_pingpong<int, Pinned>(stream, 1024*1024*32, 1, 1, false);
//        test_pingpong<int, Pinned>(stream, 1024*1024*32, 1, 10, false);

        HIPCHECK(hipStreamDestroy(stream));
    }

    passed();

}
<|endoftext|>


<commit_before>#include "pdb/PDBChain.hpp"
#include "pdb/CGChain.hpp"

using namespace coffeemill;

int main(int argc, char* argv[])
{
    if(argc != 2 && argc != 3)
    {
        std::cout << "Usage  : ./seqextr [OPTION] [filename].pdb" << std::endl;
        std::cout << "Option : -cg : read cg style" << std::endl;
        return -1;
    }

    std::string argv1(argv[1]);
    if(argv1 == "-cg")
    {//read CG style
        std::ifstream pdbfile(argv[2]);

        while(!pdbfile.eof())
        {
            CGChain chain;
            chain.read_block(pdbfile);

            if(chain.chain_exist())
            {
                std::cout << "Chain " << chain.get_chainID() << ": ";
                std::cout << chain.get_sequence() << std::endl;
            }
        }
    }
    else
    {//read plane PDB
        std::ifstream pdbfile(argv[1]);

        while(!pdbfile.eof())
        {
            PDBChain chain;
            chain.read_block(pdbfile);

            if(chain.chain_exist())
            {
                std::cout << "Chain " << chain.get_chainID() << ": ";
                std::cout << chain.get_sequence() << std::endl;
            }
        }
    }
    return 0;
}

<commit_msg>add: catch stod exception > SequenceExtractor<commit_after>#include "pdb/PDBChain.hpp"
#include "pdb/CGChain.hpp"
using namespace coffeemill;

int main(int argc, char* argv[])
{
    if(argc != 2 && argc != 3)
    {
        std::cout << "Usage  : ./seqextr [OPTION] [filename].pdb" << std::endl;
        std::cout << "Option : -cg : read cg style" << std::endl;
        return -1;
    }

    std::string argv1(argv[1]);
    if(argv1 == "-cg")
    {//read CG style
        std::ifstream pdbfile(argv[2]);

        while(!pdbfile.eof())
        {
            CGChain chain;
            chain.read_block(pdbfile);

            if(chain.chain_exist())
            {
                std::cout << "Chain " << chain.get_chainID() << ": ";
                std::cout << chain.get_sequence() << std::endl;
            }
        }
    }
    else
    {//read plane PDB
        try{
            std::ifstream pdbfile(argv[1]);

            while(!pdbfile.eof())
            {
                PDBChain chain;
                chain.read_block(pdbfile);

                if(chain.chain_exist())
                {
                    std::cout << "Chain " << chain.get_chainID() << ": ";
                    std::cout << chain.get_sequence() << std::endl;
                }
            }
        }
        catch(std::exception& exp)
        {
            std::cerr << "while reading file, exception " << exp.what() << "was caught." << std::endl;
            std::cerr << "please use -cg option to read CG PDB" << std::endl;
            return EXIT_FAILURE;
        }
    }
    return 0;
}

<|endoftext|>