<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svl/IndexedStyleSheets.hxx>

#include <svl/style.hxx>

#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

using namespace svl;

class MockedStyleSheet : public SfxStyleSheetBase
{
    public:
    MockedStyleSheet(const rtl::OUString& name, SfxStyleFamily fam = SFX_STYLE_FAMILY_CHAR)
    : SfxStyleSheetBase(name, NULL, fam, 0)
    {;}

};

struct DummyPredicate : public StyleSheetPredicate {
    bool Check(const SfxStyleSheetBase& styleSheet) SAL_OVERRIDE {
        (void)styleSheet; // fix compiler warning
        return true;
    }
};

class IndexedStyleSheetsTest : public CppUnit::TestFixture
{
    void InstantiationWorks();
    void AddedStylesheetsCanBeFoundAndRetrievedByPosition();
    void AddingSameStylesheetTwiceHasNoEffect();
    void RemovedStyleSheetIsNotFound();
    void RemovingStyleSheetWhichIsNotAvailableHasNoEffect();
    void StyleSheetsCanBeRetrievedByTheirName();
    void KnowsThatItStoresAStyleSheet();
    void PositionCanBeQueriedByFamily();
    void OnlyOneStyleSheetIsReturnedWhenReturnFirstIsUsed();

    // Adds code needed to register the test suite
    CPPUNIT_TEST_SUITE(IndexedStyleSheetsTest);

    CPPUNIT_TEST(InstantiationWorks);
    CPPUNIT_TEST(AddedStylesheetsCanBeFoundAndRetrievedByPosition);
    CPPUNIT_TEST(AddingSameStylesheetTwiceHasNoEffect);
    CPPUNIT_TEST(RemovedStyleSheetIsNotFound);
    CPPUNIT_TEST(RemovingStyleSheetWhichIsNotAvailableHasNoEffect);
    CPPUNIT_TEST(StyleSheetsCanBeRetrievedByTheirName);
    CPPUNIT_TEST(KnowsThatItStoresAStyleSheet);
    CPPUNIT_TEST(PositionCanBeQueriedByFamily);
    CPPUNIT_TEST(OnlyOneStyleSheetIsReturnedWhenReturnFirstIsUsed);

    // End of test suite definition
    CPPUNIT_TEST_SUITE_END();

};

void IndexedStyleSheetsTest::InstantiationWorks()
{
    IndexedStyleSheets iss;
}

void IndexedStyleSheetsTest::AddedStylesheetsCanBeFoundAndRetrievedByPosition()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    unsigned pos = iss.FindStyleSheetPosition(*sheet2);
    rtl::Reference<SfxStyleSheetBase> retrieved = iss.GetStyleSheetByPosition(pos);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("retrieved sheet is that which has been inserted.", sheet2.get(), retrieved.get());
}

void IndexedStyleSheetsTest::AddingSameStylesheetTwiceHasNoEffect()
{
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(rtl::OUString("sheet1")));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
    iss.AddStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
}

void IndexedStyleSheetsTest::RemovedStyleSheetIsNotFound()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.RemoveStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Removed style sheet is not found.",
            false, iss.HasStyleSheet(sheet1));
}

void IndexedStyleSheetsTest::RemovingStyleSheetWhichIsNotAvailableHasNoEffect()
{
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(rtl::OUString("sheet1")));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(rtl::OUString("sheet2")));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
    iss.RemoveStyleSheet(sheet2);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
}

void IndexedStyleSheetsTest::StyleSheetsCanBeRetrievedByTheirName()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name1));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);

    std::vector<unsigned> r = iss.FindPositionsByName(name1);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Two style sheets are found by 'name1'",
            2u, static_cast<unsigned>(r.size()));
    CPPUNIT_ASSERT_EQUAL(0u, r.at(0));
    CPPUNIT_ASSERT_EQUAL(2u, r.at(1));

    r = iss.FindPositionsByName(name2);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("One style sheets is found by 'name2'",
            1u, static_cast<unsigned>(r.size()));
    CPPUNIT_ASSERT_EQUAL(1u, r.at(0));
}

void IndexedStyleSheetsTest::KnowsThatItStoresAStyleSheet()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name2));
    rtl::Reference<SfxStyleSheetBase> sheet4(new MockedStyleSheet(name1));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);
    // do not add sheet 4

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Finds first stored style sheet even though two style sheets have the same name.",
            true, iss.HasStyleSheet(sheet1));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Finds second stored style sheet even though two style sheets have the same name.",
            true, iss.HasStyleSheet(sheet2));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Does not find style sheet which is not stored and has the same name as a stored.",
            false, iss.HasStyleSheet(sheet4));
}

void IndexedStyleSheetsTest::PositionCanBeQueriedByFamily()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::OUString name3("name3");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1, SFX_STYLE_FAMILY_CHAR));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2, SFX_STYLE_FAMILY_PARA));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name3, SFX_STYLE_FAMILY_CHAR));

    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);

    const std::vector<unsigned>& v = iss.GetStyleSheetPositionsByFamily(SFX_STYLE_FAMILY_CHAR);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Separation by family works.", static_cast<size_t>(2), v.size());

    const std::vector<unsigned>& w = iss.GetStyleSheetPositionsByFamily(SFX_STYLE_FAMILY_ALL);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Wildcard works for family queries.", static_cast<size_t>(3), w.size());
}

void IndexedStyleSheetsTest::OnlyOneStyleSheetIsReturnedWhenReturnFirstIsUsed()
{
    rtl::OUString name("name1");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name, SFX_STYLE_FAMILY_CHAR));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name, SFX_STYLE_FAMILY_PARA));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name, SFX_STYLE_FAMILY_CHAR));

    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);

    DummyPredicate predicate; // returns always true, i.e., all style sheets match the predicate.

    std::vector<unsigned> v = iss.FindPositionsByNameAndPredicate(name, predicate,
            IndexedStyleSheets::RETURN_FIRST);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Only one style sheet is returned.", static_cast<size_t>(1), v.size());

    std::vector<unsigned> w = iss.FindPositionsByNameAndPredicate(name, predicate,
                IndexedStyleSheets::RETURN_ALL);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("All style sheets are returned.", static_cast<size_t>(1), v.size());
}

CPPUNIT_TEST_SUITE_REGISTRATION(IndexedStyleSheetsTest);

CPPUNIT_PLUGIN_IMPLEMENT();
<commit_msg>svl: fix comparison in new unit test<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svl/IndexedStyleSheets.hxx>

#include <svl/style.hxx>

#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

using namespace svl;

class MockedStyleSheet : public SfxStyleSheetBase
{
    public:
    MockedStyleSheet(const rtl::OUString& name, SfxStyleFamily fam = SFX_STYLE_FAMILY_CHAR)
    : SfxStyleSheetBase(name, NULL, fam, 0)
    {;}

};

struct DummyPredicate : public StyleSheetPredicate {
    bool Check(const SfxStyleSheetBase& styleSheet) SAL_OVERRIDE {
        (void)styleSheet; // fix compiler warning
        return true;
    }
};

class IndexedStyleSheetsTest : public CppUnit::TestFixture
{
    void InstantiationWorks();
    void AddedStylesheetsCanBeFoundAndRetrievedByPosition();
    void AddingSameStylesheetTwiceHasNoEffect();
    void RemovedStyleSheetIsNotFound();
    void RemovingStyleSheetWhichIsNotAvailableHasNoEffect();
    void StyleSheetsCanBeRetrievedByTheirName();
    void KnowsThatItStoresAStyleSheet();
    void PositionCanBeQueriedByFamily();
    void OnlyOneStyleSheetIsReturnedWhenReturnFirstIsUsed();

    // Adds code needed to register the test suite
    CPPUNIT_TEST_SUITE(IndexedStyleSheetsTest);

    CPPUNIT_TEST(InstantiationWorks);
    CPPUNIT_TEST(AddedStylesheetsCanBeFoundAndRetrievedByPosition);
    CPPUNIT_TEST(AddingSameStylesheetTwiceHasNoEffect);
    CPPUNIT_TEST(RemovedStyleSheetIsNotFound);
    CPPUNIT_TEST(RemovingStyleSheetWhichIsNotAvailableHasNoEffect);
    CPPUNIT_TEST(StyleSheetsCanBeRetrievedByTheirName);
    CPPUNIT_TEST(KnowsThatItStoresAStyleSheet);
    CPPUNIT_TEST(PositionCanBeQueriedByFamily);
    CPPUNIT_TEST(OnlyOneStyleSheetIsReturnedWhenReturnFirstIsUsed);

    // End of test suite definition
    CPPUNIT_TEST_SUITE_END();

};

void IndexedStyleSheetsTest::InstantiationWorks()
{
    IndexedStyleSheets iss;
}

void IndexedStyleSheetsTest::AddedStylesheetsCanBeFoundAndRetrievedByPosition()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    unsigned pos = iss.FindStyleSheetPosition(*sheet2);
    rtl::Reference<SfxStyleSheetBase> retrieved = iss.GetStyleSheetByPosition(pos);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("retrieved sheet is that which has been inserted.", sheet2.get(), retrieved.get());
}

void IndexedStyleSheetsTest::AddingSameStylesheetTwiceHasNoEffect()
{
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(rtl::OUString("sheet1")));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
    iss.AddStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
}

void IndexedStyleSheetsTest::RemovedStyleSheetIsNotFound()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.RemoveStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Removed style sheet is not found.",
            false, iss.HasStyleSheet(sheet1));
}

void IndexedStyleSheetsTest::RemovingStyleSheetWhichIsNotAvailableHasNoEffect()
{
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(rtl::OUString("sheet1")));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(rtl::OUString("sheet2")));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
    iss.RemoveStyleSheet(sheet2);
    CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
}

void IndexedStyleSheetsTest::StyleSheetsCanBeRetrievedByTheirName()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name1));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);

    std::vector<unsigned> r = iss.FindPositionsByName(name1);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Two style sheets are found by 'name1'",
            2u, static_cast<unsigned>(r.size()));
    CPPUNIT_ASSERT_EQUAL(0u, r.at(0));
    CPPUNIT_ASSERT_EQUAL(2u, r.at(1));

    r = iss.FindPositionsByName(name2);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("One style sheets is found by 'name2'",
            1u, static_cast<unsigned>(r.size()));
    CPPUNIT_ASSERT_EQUAL(1u, r.at(0));
}

void IndexedStyleSheetsTest::KnowsThatItStoresAStyleSheet()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name1));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name2));
    rtl::Reference<SfxStyleSheetBase> sheet4(new MockedStyleSheet(name1));
    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);
    // do not add sheet 4

    CPPUNIT_ASSERT_EQUAL_MESSAGE("Finds first stored style sheet even though two style sheets have the same name.",
            true, iss.HasStyleSheet(sheet1));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Finds second stored style sheet even though two style sheets have the same name.",
            true, iss.HasStyleSheet(sheet2));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Does not find style sheet which is not stored and has the same name as a stored.",
            false, iss.HasStyleSheet(sheet4));
}

void IndexedStyleSheetsTest::PositionCanBeQueriedByFamily()
{
    rtl::OUString name1("name1");
    rtl::OUString name2("name2");
    rtl::OUString name3("name3");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1, SFX_STYLE_FAMILY_CHAR));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2, SFX_STYLE_FAMILY_PARA));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name3, SFX_STYLE_FAMILY_CHAR));

    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);

    const std::vector<unsigned>& v = iss.GetStyleSheetPositionsByFamily(SFX_STYLE_FAMILY_CHAR);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Separation by family works.", static_cast<size_t>(2), v.size());

    const std::vector<unsigned>& w = iss.GetStyleSheetPositionsByFamily(SFX_STYLE_FAMILY_ALL);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Wildcard works for family queries.", static_cast<size_t>(3), w.size());
}

void IndexedStyleSheetsTest::OnlyOneStyleSheetIsReturnedWhenReturnFirstIsUsed()
{
    rtl::OUString name("name1");
    rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name, SFX_STYLE_FAMILY_CHAR));
    rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name, SFX_STYLE_FAMILY_PARA));
    rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name, SFX_STYLE_FAMILY_CHAR));

    IndexedStyleSheets iss;
    iss.AddStyleSheet(sheet1);
    iss.AddStyleSheet(sheet2);
    iss.AddStyleSheet(sheet3);

    DummyPredicate predicate; // returns always true, i.e., all style sheets match the predicate.

    std::vector<unsigned> v = iss.FindPositionsByNameAndPredicate(name, predicate,
            IndexedStyleSheets::RETURN_FIRST);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Only one style sheet is returned.", static_cast<size_t>(1), v.size());

    std::vector<unsigned> w = iss.FindPositionsByNameAndPredicate(name, predicate,
                IndexedStyleSheets::RETURN_ALL);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("All style sheets are returned.", static_cast<size_t>(3), w.size());
}

CPPUNIT_TEST_SUITE_REGISTRATION(IndexedStyleSheetsTest);

CPPUNIT_PLUGIN_IMPLEMENT();
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: emptyproperties.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 16:30:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SDR_PROPERTIES_EMPTYPROPERTIES_HXX
#include <svx/sdr/properties/emptyproperties.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif

#ifndef _SVDDEF_HXX
#include <svddef.hxx>
#endif

#ifndef _SVDOBJ_HXX
#include <svdobj.hxx>
#endif

#ifndef _SVDPOOL_HXX
#include <svdpool.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace properties
    {
        // create a new itemset
        SfxItemSet& EmptyProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
        {
            // Basic implementation; Basic object has NO attributes
            DBG_ASSERT(sal_False, "EmptyProperties::CreateObjectSpecificItemSet() should never be called");
            return *(new SfxItemSet(rPool));
        }

        EmptyProperties::EmptyProperties(SdrObject& rObj)
        :   BaseProperties(rObj),
            mpEmptyItemSet(0L)
        {
        }

        EmptyProperties::EmptyProperties(const EmptyProperties& rProps, SdrObject& rObj)
        :   BaseProperties(rProps, rObj),
            mpEmptyItemSet(0L)
        {
            // #115593#
            // do not gererate an assert, else derivations like PageProperties will generate an assert
            // using the Clone() operator path.
        }

        EmptyProperties::~EmptyProperties()
        {
            if(mpEmptyItemSet)
            {
                delete mpEmptyItemSet;
                mpEmptyItemSet = 0L;
            }
        }

        BaseProperties& EmptyProperties::Clone(SdrObject& rObj) const
        {
            return *(new EmptyProperties(*this, rObj));
        }

        const SfxItemSet& EmptyProperties::GetObjectItemSet() const
        {
            if(!mpEmptyItemSet)
            {
                ((EmptyProperties*)this)->mpEmptyItemSet = &(((EmptyProperties*)this)->CreateObjectSpecificItemSet(*GetSdrObject().GetObjectItemPool()));
            }

            DBG_ASSERT(mpEmptyItemSet, "Could not create an SfxItemSet(!)");
            DBG_ASSERT(sal_False, "EmptyProperties::GetObjectItemSet() should never be called (!)");

            return *mpEmptyItemSet;
        }

        void EmptyProperties::SetObjectItem(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItem() should never be called (!)");
        }

        void EmptyProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItemDirect() should never be called (!)");
        }

        void EmptyProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ClearObjectItem() should never be called (!)");
        }

        void EmptyProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ClearObjectItemDirect() should never be called (!)");
        }

        void EmptyProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItemSet() should never be called (!)");
        }

        void EmptyProperties::ItemSetChanged(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ItemSetChanged() should never be called (!)");
        }

        sal_Bool EmptyProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const
        {
            DBG_ASSERT(sal_False, "EmptyProperties::AllowItemChange() should never be called (!)");
            return sal_True;
        }

        void EmptyProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ItemChange() should never be called (!)");
        }

        void EmptyProperties::PostItemChange(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::PostItemChange() should never be called (!)");
        }

        void EmptyProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, sal_Bool /*bDontRemoveHardAttr*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetStyleSheet() should never be called (!)");
        }

        SfxStyleSheet* EmptyProperties::GetStyleSheet() const
        {
            DBG_ASSERT(sal_False, "EmptyProperties::GetStyleSheet() should never be called (!)");
            return 0L;
        }

//BFS01     void EmptyProperties::PreProcessSave()
//BFS01     {
//BFS01     }

//BFS01     void EmptyProperties::PostProcessSave()
//BFS01     {
//BFS01     }
    } // end of namespace properties
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>INTEGRATION: CWS pchfix02 (1.6.114); FILE MERGED 2006/09/01 17:47:16 kaib 1.6.114.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: emptyproperties.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 05:42:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifndef _SDR_PROPERTIES_EMPTYPROPERTIES_HXX
#include <svx/sdr/properties/emptyproperties.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif

#ifndef _SVDDEF_HXX
#include <svddef.hxx>
#endif

#ifndef _SVDOBJ_HXX
#include <svdobj.hxx>
#endif

#ifndef _SVDPOOL_HXX
#include <svdpool.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace properties
    {
        // create a new itemset
        SfxItemSet& EmptyProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
        {
            // Basic implementation; Basic object has NO attributes
            DBG_ASSERT(sal_False, "EmptyProperties::CreateObjectSpecificItemSet() should never be called");
            return *(new SfxItemSet(rPool));
        }

        EmptyProperties::EmptyProperties(SdrObject& rObj)
        :   BaseProperties(rObj),
            mpEmptyItemSet(0L)
        {
        }

        EmptyProperties::EmptyProperties(const EmptyProperties& rProps, SdrObject& rObj)
        :   BaseProperties(rProps, rObj),
            mpEmptyItemSet(0L)
        {
            // #115593#
            // do not gererate an assert, else derivations like PageProperties will generate an assert
            // using the Clone() operator path.
        }

        EmptyProperties::~EmptyProperties()
        {
            if(mpEmptyItemSet)
            {
                delete mpEmptyItemSet;
                mpEmptyItemSet = 0L;
            }
        }

        BaseProperties& EmptyProperties::Clone(SdrObject& rObj) const
        {
            return *(new EmptyProperties(*this, rObj));
        }

        const SfxItemSet& EmptyProperties::GetObjectItemSet() const
        {
            if(!mpEmptyItemSet)
            {
                ((EmptyProperties*)this)->mpEmptyItemSet = &(((EmptyProperties*)this)->CreateObjectSpecificItemSet(*GetSdrObject().GetObjectItemPool()));
            }

            DBG_ASSERT(mpEmptyItemSet, "Could not create an SfxItemSet(!)");
            DBG_ASSERT(sal_False, "EmptyProperties::GetObjectItemSet() should never be called (!)");

            return *mpEmptyItemSet;
        }

        void EmptyProperties::SetObjectItem(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItem() should never be called (!)");
        }

        void EmptyProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItemDirect() should never be called (!)");
        }

        void EmptyProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ClearObjectItem() should never be called (!)");
        }

        void EmptyProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ClearObjectItemDirect() should never be called (!)");
        }

        void EmptyProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItemSet() should never be called (!)");
        }

        void EmptyProperties::ItemSetChanged(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ItemSetChanged() should never be called (!)");
        }

        sal_Bool EmptyProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const
        {
            DBG_ASSERT(sal_False, "EmptyProperties::AllowItemChange() should never be called (!)");
            return sal_True;
        }

        void EmptyProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::ItemChange() should never be called (!)");
        }

        void EmptyProperties::PostItemChange(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::PostItemChange() should never be called (!)");
        }

        void EmptyProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, sal_Bool /*bDontRemoveHardAttr*/)
        {
            DBG_ASSERT(sal_False, "EmptyProperties::SetStyleSheet() should never be called (!)");
        }

        SfxStyleSheet* EmptyProperties::GetStyleSheet() const
        {
            DBG_ASSERT(sal_False, "EmptyProperties::GetStyleSheet() should never be called (!)");
            return 0L;
        }

//BFS01     void EmptyProperties::PreProcessSave()
//BFS01     {
//BFS01     }

//BFS01     void EmptyProperties::PostProcessSave()
//BFS01     {
//BFS01     }
    } // end of namespace properties
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* @file
 * System Console Definition
 */

#include <cstddef>
#include <cstdio>
#include <string>

#include "base/inifile.hh"
#include "base/str.hh"	// for to_number()
#include "base/trace.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "dev/alpha_console.hh"
#include "dev/console.hh"
#include "dev/simple_disk.hh"
#include "dev/tlaser_clock.hh"
#include "mem/bus/bus.hh"
#include "mem/bus/pio_interface.hh"
#include "mem/bus/pio_interface_impl.hh"
#include "mem/functional_mem/memory_control.hh"
#include "sim/builder.hh"
#include "sim/system.hh"

using namespace std;

AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
                           System *system, BaseCPU *cpu, TlaserClock *clock,
                           int num_cpus, MemoryController *mmu, Addr a,
                           HierParams *hier, Bus *bus)
    : PioDevice(name), disk(d), console(cons), addr(a)
{
    mmu->add_child(this, Range<Addr>(addr, addr + size));

    if (bus) {
        pioInterface = newPioInterface(name, hier, bus, this,
                                       &AlphaConsole::cacheAccess);
        pioInterface->setAddrRange(addr, addr + size);
    }

    consoleData = new uint8_t[size];
    memset(consoleData, 0, size);

    alphaAccess->last_offset = size - 1;
    alphaAccess->kernStart = system->getKernelStart();
    alphaAccess->kernEnd = system->getKernelEnd();
    alphaAccess->entryPoint = system->getKernelEntry();

    alphaAccess->version = ALPHA_ACCESS_VERSION;
    alphaAccess->numCPUs = num_cpus;
    alphaAccess->mem_size = system->physmem->size();
    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
    alphaAccess->intrClockFrequency = clock->frequency();

    alphaAccess->diskUnit = 1;
}

Fault
AlphaConsole::read(MemReqPtr &req, uint8_t *data)
{
    memset(data, 0, req->size);
    uint64_t val;

    Addr daddr = req->paddr - addr;

    switch (daddr) {
      case offsetof(AlphaAccess, inputChar):
        val = console->console_in();
        break;

      default:
        val = *(uint64_t *)(consoleData + daddr);
        break;
    }

    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);

    switch (req->size) {
      case sizeof(uint32_t):
        *(uint32_t *)data = (uint32_t)val;
        break;

      case sizeof(uint64_t):
        *(uint64_t *)data = val;
        break;

      default:
        return Machine_Check_Fault;
    }

    return No_Fault;
}

Fault
AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
{
    uint64_t val;

    switch (req->size) {
      case sizeof(uint32_t):
        val = *(uint32_t *)data;
        break;

      case sizeof(uint64_t):
        val = *(uint64_t *)data;
        break;
      default:
        return Machine_Check_Fault;
    }

    Addr daddr = req->paddr - addr;
    ExecContext *other_xc;

    switch (daddr) {
      case offsetof(AlphaAccess, diskUnit):
        alphaAccess->diskUnit = val;
        break;

      case offsetof(AlphaAccess, diskCount):
        alphaAccess->diskCount = val;
        break;

      case offsetof(AlphaAccess, diskPAddr):
        alphaAccess->diskPAddr = val;
        break;

      case offsetof(AlphaAccess, diskBlock):
        alphaAccess->diskBlock = val;
        break;

      case offsetof(AlphaAccess, diskOperation):
        if (val == 0x13)
            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
                       alphaAccess->diskCount);
        else
            panic("Invalid disk operation!");

        break;

      case offsetof(AlphaAccess, outputChar):
        console->out((char)(val & 0xff), false);
        break;

      case offsetof(AlphaAccess, bootStrapImpure):
        alphaAccess->bootStrapImpure = val;
        break;

      case offsetof(AlphaAccess, bootStrapCPU):
        warn("%d: Trying to launch another CPU!", curTick);
        assert(val > 0 && "Must not access primary cpu");

        other_xc = req->xc->system->execContexts[val];
        other_xc->regs.intRegFile[16] = val;
        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
        other_xc->regs.intRegFile[0] = val;
        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
        other_xc->activate(); //Start the cpu
        break;

      default:
        return Machine_Check_Fault;
    }

    return No_Fault;
}

Tick
AlphaConsole::cacheAccess(MemReqPtr &req)
{
    return curTick + 1000;
}

void
AlphaAccess::serialize(ostream &os)
{
    SERIALIZE_SCALAR(last_offset);
    SERIALIZE_SCALAR(version);
    SERIALIZE_SCALAR(numCPUs);
    SERIALIZE_SCALAR(mem_size);
    SERIALIZE_SCALAR(cpuClock);
    SERIALIZE_SCALAR(intrClockFrequency);
    SERIALIZE_SCALAR(kernStart);
    SERIALIZE_SCALAR(kernEnd);
    SERIALIZE_SCALAR(entryPoint);
    SERIALIZE_SCALAR(diskUnit);
    SERIALIZE_SCALAR(diskCount);
    SERIALIZE_SCALAR(diskPAddr);
    SERIALIZE_SCALAR(diskBlock);
    SERIALIZE_SCALAR(diskOperation);
    SERIALIZE_SCALAR(outputChar);
    SERIALIZE_SCALAR(inputChar);
    SERIALIZE_SCALAR(bootStrapImpure);
    SERIALIZE_SCALAR(bootStrapCPU);
}

void
AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_SCALAR(last_offset);
    UNSERIALIZE_SCALAR(version);
    UNSERIALIZE_SCALAR(numCPUs);
    UNSERIALIZE_SCALAR(mem_size);
    UNSERIALIZE_SCALAR(cpuClock);
    UNSERIALIZE_SCALAR(intrClockFrequency);
    UNSERIALIZE_SCALAR(kernStart);
    UNSERIALIZE_SCALAR(kernEnd);
    UNSERIALIZE_SCALAR(entryPoint);
    UNSERIALIZE_SCALAR(diskUnit);
    UNSERIALIZE_SCALAR(diskCount);
    UNSERIALIZE_SCALAR(diskPAddr);
    UNSERIALIZE_SCALAR(diskBlock);
    UNSERIALIZE_SCALAR(diskOperation);
    UNSERIALIZE_SCALAR(outputChar);
    UNSERIALIZE_SCALAR(inputChar);
    UNSERIALIZE_SCALAR(bootStrapImpure);
    UNSERIALIZE_SCALAR(bootStrapCPU);
}

void
AlphaConsole::serialize(ostream &os)
{
    alphaAccess->serialize(os);
}

void
AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
{
    alphaAccess->unserialize(cp, section);
}

BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)

    SimObjectParam<SimConsole *> sim_console;
    SimObjectParam<SimpleDisk *> disk;
    Param<int> num_cpus;
    SimObjectParam<MemoryController *> mmu;
    Param<Addr> addr;
    SimObjectParam<System *> system;
    SimObjectParam<BaseCPU *> cpu;
    SimObjectParam<TlaserClock *> clock;
    SimObjectParam<Bus*> io_bus;
    SimObjectParam<HierParams *> hier;

END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)

BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)

    INIT_PARAM(sim_console, "The Simulator Console"),
    INIT_PARAM(disk, "Simple Disk"),
    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
    INIT_PARAM(mmu, "Memory Controller"),
    INIT_PARAM(addr, "Device Address"),
    INIT_PARAM(system, "system object"),
    INIT_PARAM(cpu, "Processor"),
    INIT_PARAM(clock, "Turbolaser Clock"),
    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)

END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)

CREATE_SIM_OBJECT(AlphaConsole)
{
    return new AlphaConsole(getInstanceName(), sim_console, disk,
                            system, cpu, clock, num_cpus, mmu,
                            addr, hier, io_bus);
}

REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
<commit_msg>Add support for multiple address ranges in memory interfaces.<commit_after>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* @file
 * System Console Definition
 */

#include <cstddef>
#include <cstdio>
#include <string>

#include "base/inifile.hh"
#include "base/str.hh"	// for to_number()
#include "base/trace.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "dev/alpha_console.hh"
#include "dev/console.hh"
#include "dev/simple_disk.hh"
#include "dev/tlaser_clock.hh"
#include "mem/bus/bus.hh"
#include "mem/bus/pio_interface.hh"
#include "mem/bus/pio_interface_impl.hh"
#include "mem/functional_mem/memory_control.hh"
#include "sim/builder.hh"
#include "sim/system.hh"

using namespace std;

AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
                           System *system, BaseCPU *cpu, TlaserClock *clock,
                           int num_cpus, MemoryController *mmu, Addr a,
                           HierParams *hier, Bus *bus)
    : PioDevice(name), disk(d), console(cons), addr(a)
{
    mmu->add_child(this, Range<Addr>(addr, addr + size));

    if (bus) {
        pioInterface = newPioInterface(name, hier, bus, this,
                                       &AlphaConsole::cacheAccess);
        pioInterface->addAddrRange(addr, addr + size);
    }

    consoleData = new uint8_t[size];
    memset(consoleData, 0, size);

    alphaAccess->last_offset = size - 1;
    alphaAccess->kernStart = system->getKernelStart();
    alphaAccess->kernEnd = system->getKernelEnd();
    alphaAccess->entryPoint = system->getKernelEntry();

    alphaAccess->version = ALPHA_ACCESS_VERSION;
    alphaAccess->numCPUs = num_cpus;
    alphaAccess->mem_size = system->physmem->size();
    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
    alphaAccess->intrClockFrequency = clock->frequency();

    alphaAccess->diskUnit = 1;
}

Fault
AlphaConsole::read(MemReqPtr &req, uint8_t *data)
{
    memset(data, 0, req->size);
    uint64_t val;

    Addr daddr = req->paddr - addr;

    switch (daddr) {
      case offsetof(AlphaAccess, inputChar):
        val = console->console_in();
        break;

      default:
        val = *(uint64_t *)(consoleData + daddr);
        break;
    }

    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);

    switch (req->size) {
      case sizeof(uint32_t):
        *(uint32_t *)data = (uint32_t)val;
        break;

      case sizeof(uint64_t):
        *(uint64_t *)data = val;
        break;

      default:
        return Machine_Check_Fault;
    }

    return No_Fault;
}

Fault
AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
{
    uint64_t val;

    switch (req->size) {
      case sizeof(uint32_t):
        val = *(uint32_t *)data;
        break;

      case sizeof(uint64_t):
        val = *(uint64_t *)data;
        break;
      default:
        return Machine_Check_Fault;
    }

    Addr daddr = req->paddr - addr;
    ExecContext *other_xc;

    switch (daddr) {
      case offsetof(AlphaAccess, diskUnit):
        alphaAccess->diskUnit = val;
        break;

      case offsetof(AlphaAccess, diskCount):
        alphaAccess->diskCount = val;
        break;

      case offsetof(AlphaAccess, diskPAddr):
        alphaAccess->diskPAddr = val;
        break;

      case offsetof(AlphaAccess, diskBlock):
        alphaAccess->diskBlock = val;
        break;

      case offsetof(AlphaAccess, diskOperation):
        if (val == 0x13)
            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
                       alphaAccess->diskCount);
        else
            panic("Invalid disk operation!");

        break;

      case offsetof(AlphaAccess, outputChar):
        console->out((char)(val & 0xff), false);
        break;

      case offsetof(AlphaAccess, bootStrapImpure):
        alphaAccess->bootStrapImpure = val;
        break;

      case offsetof(AlphaAccess, bootStrapCPU):
        warn("%d: Trying to launch another CPU!", curTick);
        assert(val > 0 && "Must not access primary cpu");

        other_xc = req->xc->system->execContexts[val];
        other_xc->regs.intRegFile[16] = val;
        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
        other_xc->regs.intRegFile[0] = val;
        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
        other_xc->activate(); //Start the cpu
        break;

      default:
        return Machine_Check_Fault;
    }

    return No_Fault;
}

Tick
AlphaConsole::cacheAccess(MemReqPtr &req)
{
    return curTick + 1000;
}

void
AlphaAccess::serialize(ostream &os)
{
    SERIALIZE_SCALAR(last_offset);
    SERIALIZE_SCALAR(version);
    SERIALIZE_SCALAR(numCPUs);
    SERIALIZE_SCALAR(mem_size);
    SERIALIZE_SCALAR(cpuClock);
    SERIALIZE_SCALAR(intrClockFrequency);
    SERIALIZE_SCALAR(kernStart);
    SERIALIZE_SCALAR(kernEnd);
    SERIALIZE_SCALAR(entryPoint);
    SERIALIZE_SCALAR(diskUnit);
    SERIALIZE_SCALAR(diskCount);
    SERIALIZE_SCALAR(diskPAddr);
    SERIALIZE_SCALAR(diskBlock);
    SERIALIZE_SCALAR(diskOperation);
    SERIALIZE_SCALAR(outputChar);
    SERIALIZE_SCALAR(inputChar);
    SERIALIZE_SCALAR(bootStrapImpure);
    SERIALIZE_SCALAR(bootStrapCPU);
}

void
AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_SCALAR(last_offset);
    UNSERIALIZE_SCALAR(version);
    UNSERIALIZE_SCALAR(numCPUs);
    UNSERIALIZE_SCALAR(mem_size);
    UNSERIALIZE_SCALAR(cpuClock);
    UNSERIALIZE_SCALAR(intrClockFrequency);
    UNSERIALIZE_SCALAR(kernStart);
    UNSERIALIZE_SCALAR(kernEnd);
    UNSERIALIZE_SCALAR(entryPoint);
    UNSERIALIZE_SCALAR(diskUnit);
    UNSERIALIZE_SCALAR(diskCount);
    UNSERIALIZE_SCALAR(diskPAddr);
    UNSERIALIZE_SCALAR(diskBlock);
    UNSERIALIZE_SCALAR(diskOperation);
    UNSERIALIZE_SCALAR(outputChar);
    UNSERIALIZE_SCALAR(inputChar);
    UNSERIALIZE_SCALAR(bootStrapImpure);
    UNSERIALIZE_SCALAR(bootStrapCPU);
}

void
AlphaConsole::serialize(ostream &os)
{
    alphaAccess->serialize(os);
}

void
AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
{
    alphaAccess->unserialize(cp, section);
}

BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)

    SimObjectParam<SimConsole *> sim_console;
    SimObjectParam<SimpleDisk *> disk;
    Param<int> num_cpus;
    SimObjectParam<MemoryController *> mmu;
    Param<Addr> addr;
    SimObjectParam<System *> system;
    SimObjectParam<BaseCPU *> cpu;
    SimObjectParam<TlaserClock *> clock;
    SimObjectParam<Bus*> io_bus;
    SimObjectParam<HierParams *> hier;

END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)

BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)

    INIT_PARAM(sim_console, "The Simulator Console"),
    INIT_PARAM(disk, "Simple Disk"),
    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
    INIT_PARAM(mmu, "Memory Controller"),
    INIT_PARAM(addr, "Device Address"),
    INIT_PARAM(system, "system object"),
    INIT_PARAM(cpu, "Processor"),
    INIT_PARAM(clock, "Turbolaser Clock"),
    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)

END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)

CREATE_SIM_OBJECT(AlphaConsole)
{
    return new AlphaConsole(getInstanceName(), sim_console, disk,
                            system, cpu, clock, num_cpus, mmu,
                            addr, hier, io_bus);
}

REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
<|endoftext|>


<commit_before>/* Copyright 2021 The TensorFlow 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 "tensorflow/core/tpu/tpu_initializer_helper.h"

#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <fstream>
#include <string>
#include <utility>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/synchronization/mutex.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/tpu/libtftpu.h"
#include "tensorflow/core/tpu/tpu_api_dlsym_set_fn.h"
#include "tensorflow/core/tpu/tpu_ops_c_api.h"
#include "tensorflow/stream_executor/tpu/tpu_executor_c_api.h"

#if !defined(PLATFORM_GOOGLE)
#include "tensorflow/core/platform/cloud/gcs_file_system.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/tpu/tpu_api.h"
#include "tensorflow/stream_executor/tpu/tpu_platform.h"
#elif defined(LIBTPU_STATIC)
#include "tensorflow/core/tpu/tpu_api.h"
#include "tensorflow/stream_executor/tpu/tpu_platform.h"
#endif  // PLATFORM_GOOGLE

namespace tensorflow {
namespace tpu {
namespace {

static std::string GetEnvVar(const char* name) {
  // Constructing a std::string directly from nullptr is undefined behavior.
  return absl::StrCat(getenv(name));
}

bool GetEnvBool(const char* name, bool defval) {
  const char* env = getenv(name);
  if (env == nullptr) {
    return defval;
  }
  if (std::strcmp(env, "true") == 0) {
    return true;
  }
  if (std::strcmp(env, "false") == 0) {
    return false;
  }
  int int_env;
  bool has_int = absl::SimpleAtoi(env, &int_env);
  return has_int && int_env != 0;
}

}  // namespace

// This function gets pid of a process and checks if that process is using tpu.
// It is not able to check processes that are owned by another user.
bool IsTpuUsed(int64_t pid) {
  std::string path = absl::StrCat("/proc/", pid, "/fd");
  DIR* raw_fd_dir = opendir(path.c_str());
  if (!raw_fd_dir) {
    return false;
  }
  std::unique_ptr<DIR, int (*)(DIR*)> fd_dir(raw_fd_dir, closedir);
  struct dirent* ent;
  std::string line;
  std::string tpu_dev_path = "/dev/accel0";
  line.resize(tpu_dev_path.size());
  while ((ent = readdir(raw_fd_dir))) {
    if (!isdigit(*ent->d_name)) continue;
    int64_t fd = strtol(ent->d_name, nullptr, 10);
    path = absl::StrCat("/proc/", pid, "/fd/", fd);
    if (!readlink(path.c_str(), &line[0], line.size())) continue;
    if (line != tpu_dev_path) continue;
    return true;
  }
  return false;
}

// This function iterates through all the processes in /proc and finds out if
// any process it was able to check is using the TPU. It does not have
// permission to processes owned by another user.
// TODO (shahrokhi) use tensorflow/core/platform/filesystem (GetChildren) for
// this.
StatusOr<int64_t> FindLibtpuProcess() {
  DIR* proc = opendir("/proc");

  if (proc == nullptr) {
    return errors::Unavailable("was not able to open /proc");
  }
  std::unique_ptr<DIR, int (*)(DIR*)> proc_dir(proc, closedir);
  struct dirent* ent;
  int64_t pid;
  while ((ent = readdir(proc))) {
    if (!isdigit(*ent->d_name)) continue;

    pid = strtol(ent->d_name, nullptr, 10);
    if (IsTpuUsed(pid)) {
      return pid;
    }
  }
  return errors::NotFound("did not find which pid uses the libtpu.so");
}

Status TryAcquireTpuLock() {
  static absl::Mutex* mu = new absl::Mutex();
  absl::MutexLock l(mu);

  std::string load_library_override = absl::StrCat(getenv("TPU_LOAD_LIBRARY"));

  if (load_library_override == "1") {
    return Status::OK();
  } else if (load_library_override == "0") {
    return errors::FailedPrecondition("TPU_LOAD_LIBRARY=0, not loading libtpu");
  }

  // If TPU_CHIPS_PER_PROCESS_BOUNDS doesn't include all chips, we assume
  // we're using different chips in different processes and thus multiple
  // libtpu loads are ok.
  // TODO(skyewm): we could make per-chip lock files and look at
  // TPU_VISIBLE_DEVICES if we wanted to make this really precise.
  std::string chips_per_process_bounds =
      GetEnvVar("TPU_CHIPS_PER_PROCESS_BOUNDS");
  bool allow_multiple_libtpu_load =
      GetEnvBool("ALLOW_MULTIPLE_LIBTPU_LOAD", false);
  // TODO(skyewm): remove this when TPU_CHIPS_PER_HOST_BOUNDS is fully
  // deprecated
  if (chips_per_process_bounds.empty()) {
    chips_per_process_bounds = GetEnvVar("TPU_CHIPS_PER_HOST_BOUNDS");
  }
  if ((chips_per_process_bounds.empty() ||
       chips_per_process_bounds == "2,2,1") &&
      !allow_multiple_libtpu_load) {
    int fd = open("/tmp/libtpu_lockfile", O_CREAT | O_RDWR, 0644);

    // This lock is held until the process exits intentionally. The underlying
    // TPU device will be held on until it quits.
    if (lockf(fd, F_TLOCK, 0) != 0) {
      auto pid = FindLibtpuProcess();
      if (pid.ok()) {
        return errors::Aborted(absl::StrCat(
            "libtpu.so is already in use by process with pid ",
            pid.ValueOrDie(),
            ". Not attempting to load libtpu.so in this process."));
      } else {
        return errors::Aborted(
            "libtpu.so already in use by another process probably owned by "
            "another user. Run \"$ sudo lsof -w /dev/accel0\" to figure out "
            "which process is using the TPU. Not attempting to load "
            "libtpu.so in this process.");
      }
    } else {
      return Status::OK();
    }
  } else {
    VLOG(1) << "TPU_CHIPS_PER_PROCESS_BOUNDS is not empty or "
               "ALLOW_MULTIPLE_LIBTPU_LOAD is set to True, "
               "therefore allowing multiple libtpu.so loads.";
    return Status::OK();
  }
}
#if !defined(PLATFORM_GOOGLE)
#include "tensorflow/core/tpu/tpu_library_init_fns.inc"

Status InitializeTpuLibrary(void* library_handle) {
  Status s = InitializeTpuStructFns(library_handle);

  // Retrieve arguments from environment if applicable
  std::pair<std::vector<std::string>, std::vector<const char*>> args =
      GetLibTpuInitArguments();

  // TPU platform registration must only be performed after the library is
  // loaded. We do not want to register a TPU platform in XLA without the
  // supporting library providing the necessary APIs.
  if (s.ok()) {
    void (*initialize_fn)(bool init_library, int num_args, const char** args);
    initialize_fn = reinterpret_cast<decltype(initialize_fn)>(
        dlsym(library_handle, "TfTpu_Initialize"));
    (*initialize_fn)(/*init_library=*/true, args.second.size(),
                     args.second.data());

    RegisterTpuPlatform();
  }

  return s;
}

namespace {
void* CreateGcsFilesystemFn() {
  return new tensorflow::RetryingGcsFileSystem();
}

// This is a temporary fix for including GCS file system on TPU builds.
// Will be removed once b/176954917 is fully resolved with the build fix.
void InitializeCreateGcsFileSystemFnPtr() {
  int fd = shm_open(absl::StrCat("/tmp_tf_gcs_fs_pointer_", getpid()).data(),
                    O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
  if (fd == -1) {
    LOG(ERROR) << "Unable to open shared memory for GCS file system creator.";
    return;
  }

  if (ftruncate(fd, sizeof(tensorflow::FileSystem*)) == -1) {
    LOG(ERROR)
        << "Unable to allocate shared memory for GCS file system creator.";
    return;
  }

  void* (**fn)() = reinterpret_cast<void* (**)()>(mmap(
      NULL, sizeof(void* (*)()), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
  if (fn == MAP_FAILED) {
    LOG(ERROR) << "Cannot mmap shared memory for GCS file system creator.";
    return;
  }

  *fn = &CreateGcsFilesystemFn;

  munmap(fn, sizeof(void* (*)()));
  close(fd);

  // Clean up shared memory on a clean exit.
  atexit([]() {
    shm_unlink(absl::StrCat("/tmp_tf_gcs_fs_pointer_", getpid()).data());
  });
}
}  // namespace
Status FindAndLoadTpuLibrary() {
  const char* env_value = getenv("TPU_LIBRARY_PATH");
  const char* libtpu_path =
      env_value && strlen(env_value) > 0 ? env_value : "libtpu.so";
  LOG(INFO) << "Libtpu path is: " << libtpu_path;
  void* library = dlopen(libtpu_path, RTLD_NOW);
  if (library) {
    // We can open the shared library which means we are in a TPU environment.
    // Try to acquire exclusive access.
    TF_RETURN_IF_ERROR(TryAcquireTpuLock());
    TF_RETURN_IF_ERROR(InitializeTpuLibrary(library));
  }

  InitializeCreateGcsFileSystemFnPtr();
  return Status::OK();
}

#elif defined(LIBTPU_STATIC)

#include "tensorflow/core/tpu/tpu_library_init_fns.inc"

Status InitializeTpuLibrary() {
  // Retrieve arguments from environment if applicable
  std::pair<std::vector<std::string>, std::vector<const char*>> args =
      GetLibTpuInitArguments();

  TfTpu_Initialize(/*init_library*/ true, args.second.size(),
                   args.second.data());

  RegisterTpuPlatform();
  return Status::OK();
}

Status FindAndLoadTpuLibrary() {
  // We can open the shared library which means we are in a TPU environment.
  // Try to acquire exclusive access.
  TF_RETURN_IF_ERROR(TryAcquireTpuLock());
  TF_RETURN_IF_ERROR(InitializeTpuLibrary());
  return Status::OK();
}

#else   // PLATFORM_GOOGLE
Status InitializeTpuLibrary(void* library_handle) {
  return errors::Unimplemented("You must statically link in a TPU library.");
}
#endif  // PLATFORM_GOOGLE
std::pair<std::vector<std::string>, std::vector<const char*>>
GetLibTpuInitArguments() {
  // We make copies of the arguments returned by getenv because the memory
  // returned may be altered or invalidated by further calls to getenv.
  std::vector<std::string> args;
  std::vector<const char*> arg_ptrs;

  // Retrieve arguments from environment if applicable.
  char* env = getenv("LIBTPU_INIT_ARGS");
  if (env != nullptr) {
    // TODO(frankchn): Handles quotes properly if necessary.
    args = absl::StrSplit(env, ' ');
  }

  arg_ptrs.reserve(args.size());
  for (int i = 0; i < args.size(); ++i) {
    arg_ptrs.push_back(args[i].data());
  }

  return {std::move(args), std::move(arg_ptrs)};
}

}  // namespace tpu
}  // namespace tensorflow
<commit_msg>Fix JAX / TPU builds<commit_after>/* Copyright 2021 The TensorFlow 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 "tensorflow/core/tpu/tpu_initializer_helper.h"

#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <fstream>
#include <string>
#include <utility>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/synchronization/mutex.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/tpu/libtftpu.h"
#include "tensorflow/core/tpu/tpu_api_dlsym_set_fn.h"
#include "tensorflow/core/tpu/tpu_ops_c_api.h"
#include "tensorflow/stream_executor/tpu/tpu_executor_c_api.h"

#if !defined(PLATFORM_GOOGLE)
#include "tensorflow/core/platform/cloud/gcs_file_system.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/tpu/tpu_api.h"
#include "tensorflow/stream_executor/tpu/tpu_platform.h"
#elif defined(LIBTPU_STATIC)
#include "tensorflow/core/tpu/tpu_api.h"
#include "tensorflow/stream_executor/tpu/tpu_platform.h"
#endif  // PLATFORM_GOOGLE

namespace tensorflow {
namespace tpu {
namespace {

static std::string GetEnvVar(const char* name) {
  // Constructing a std::string directly from nullptr is undefined behavior.
  return absl::StrCat(getenv(name));
}

bool GetEnvBool(const char* name, bool defval) {
  const char* env = getenv(name);
  if (env == nullptr) {
    return defval;
  }
  if (std::strcmp(env, "true") == 0) {
    return true;
  }
  if (std::strcmp(env, "false") == 0) {
    return false;
  }
  int int_env;
  bool has_int = absl::SimpleAtoi(env, &int_env);
  return has_int && int_env != 0;
}

}  // namespace

// This function gets pid of a process and checks if that process is using tpu.
// It is not able to check processes that are owned by another user.
bool IsTpuUsed(int64_t pid) {
  std::string path = absl::StrCat("/proc/", pid, "/fd");
  DIR* raw_fd_dir = opendir(path.c_str());
  if (!raw_fd_dir) {
    return false;
  }
  std::unique_ptr<DIR, int (*)(DIR*)> fd_dir(raw_fd_dir, closedir);
  struct dirent* ent;
  std::string line;
  std::string tpu_dev_path = "/dev/accel0";
  line.resize(tpu_dev_path.size());
  while ((ent = readdir(raw_fd_dir))) {
    if (!isdigit(*ent->d_name)) continue;
    int64_t fd = strtol(ent->d_name, nullptr, 10);
    path = absl::StrCat("/proc/", pid, "/fd/", fd);
    if (!readlink(path.c_str(), &line[0], line.size())) continue;
    if (line != tpu_dev_path) continue;
    return true;
  }
  return false;
}

// This function iterates through all the processes in /proc and finds out if
// any process it was able to check is using the TPU. It does not have
// permission to processes owned by another user.
// TODO (shahrokhi) use tensorflow/core/platform/filesystem (GetChildren) for
// this.
StatusOr<int64_t> FindLibtpuProcess() {
  DIR* proc = opendir("/proc");

  if (proc == nullptr) {
    return errors::Unavailable("was not able to open /proc");
  }
  std::unique_ptr<DIR, int (*)(DIR*)> proc_dir(proc, closedir);
  struct dirent* ent;
  int64_t pid;
  while ((ent = readdir(proc))) {
    if (!isdigit(*ent->d_name)) continue;

    pid = strtol(ent->d_name, nullptr, 10);
    if (IsTpuUsed(pid)) {
      return pid;
    }
  }
  return errors::NotFound("did not find which pid uses the libtpu.so");
}

Status TryAcquireTpuLock() {
  static absl::Mutex* mu = new absl::Mutex();
  absl::MutexLock l(mu);

  const char* env_value = getenv("TPU_LOAD_LIBRARY");
  if (!env_value) {
    return errors::FailedPrecondition(
        "TPU_LOAD_LIBRARY environment variable not defined");
  }

  std::string load_library_override = absl::StrCat(env_value);

  if (load_library_override == "1") {
    return Status::OK();
  } else if (load_library_override == "0") {
    return errors::FailedPrecondition("TPU_LOAD_LIBRARY=0, not loading libtpu");
  }

  // If TPU_CHIPS_PER_PROCESS_BOUNDS doesn't include all chips, we assume
  // we're using different chips in different processes and thus multiple
  // libtpu loads are ok.
  // TODO(skyewm): we could make per-chip lock files and look at
  // TPU_VISIBLE_DEVICES if we wanted to make this really precise.
  std::string chips_per_process_bounds =
      GetEnvVar("TPU_CHIPS_PER_PROCESS_BOUNDS");
  bool allow_multiple_libtpu_load =
      GetEnvBool("ALLOW_MULTIPLE_LIBTPU_LOAD", false);
  // TODO(skyewm): remove this when TPU_CHIPS_PER_HOST_BOUNDS is fully
  // deprecated
  if (chips_per_process_bounds.empty()) {
    chips_per_process_bounds = GetEnvVar("TPU_CHIPS_PER_HOST_BOUNDS");
  }
  if ((chips_per_process_bounds.empty() ||
       chips_per_process_bounds == "2,2,1") &&
      !allow_multiple_libtpu_load) {
    int fd = open("/tmp/libtpu_lockfile", O_CREAT | O_RDWR, 0644);

    // This lock is held until the process exits intentionally. The underlying
    // TPU device will be held on until it quits.
    if (lockf(fd, F_TLOCK, 0) != 0) {
      auto pid = FindLibtpuProcess();
      if (pid.ok()) {
        return errors::Aborted(absl::StrCat(
            "libtpu.so is already in use by process with pid ",
            pid.ValueOrDie(),
            ". Not attempting to load libtpu.so in this process."));
      } else {
        return errors::Aborted(
            "libtpu.so already in use by another process probably owned by "
            "another user. Run \"$ sudo lsof -w /dev/accel0\" to figure out "
            "which process is using the TPU. Not attempting to load "
            "libtpu.so in this process.");
      }
    } else {
      return Status::OK();
    }
  } else {
    VLOG(1) << "TPU_CHIPS_PER_PROCESS_BOUNDS is not empty or "
               "ALLOW_MULTIPLE_LIBTPU_LOAD is set to True, "
               "therefore allowing multiple libtpu.so loads.";
    return Status::OK();
  }
}
#if !defined(PLATFORM_GOOGLE)
#include "tensorflow/core/tpu/tpu_library_init_fns.inc"

Status InitializeTpuLibrary(void* library_handle) {
  Status s = InitializeTpuStructFns(library_handle);

  // Retrieve arguments from environment if applicable
  std::pair<std::vector<std::string>, std::vector<const char*>> args =
      GetLibTpuInitArguments();

  // TPU platform registration must only be performed after the library is
  // loaded. We do not want to register a TPU platform in XLA without the
  // supporting library providing the necessary APIs.
  if (s.ok()) {
    void (*initialize_fn)(bool init_library, int num_args, const char** args);
    initialize_fn = reinterpret_cast<decltype(initialize_fn)>(
        dlsym(library_handle, "TfTpu_Initialize"));
    (*initialize_fn)(/*init_library=*/true, args.second.size(),
                     args.second.data());

    RegisterTpuPlatform();
  }

  return s;
}

namespace {
void* CreateGcsFilesystemFn() {
  return new tensorflow::RetryingGcsFileSystem();
}

// This is a temporary fix for including GCS file system on TPU builds.
// Will be removed once b/176954917 is fully resolved with the build fix.
void InitializeCreateGcsFileSystemFnPtr() {
  int fd = shm_open(absl::StrCat("/tmp_tf_gcs_fs_pointer_", getpid()).data(),
                    O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
  if (fd == -1) {
    LOG(ERROR) << "Unable to open shared memory for GCS file system creator.";
    return;
  }

  if (ftruncate(fd, sizeof(tensorflow::FileSystem*)) == -1) {
    LOG(ERROR)
        << "Unable to allocate shared memory for GCS file system creator.";
    return;
  }

  void* (**fn)() = reinterpret_cast<void* (**)()>(mmap(
      NULL, sizeof(void* (*)()), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
  if (fn == MAP_FAILED) {
    LOG(ERROR) << "Cannot mmap shared memory for GCS file system creator.";
    return;
  }

  *fn = &CreateGcsFilesystemFn;

  munmap(fn, sizeof(void* (*)()));
  close(fd);

  // Clean up shared memory on a clean exit.
  atexit([]() {
    shm_unlink(absl::StrCat("/tmp_tf_gcs_fs_pointer_", getpid()).data());
  });
}
}  // namespace
Status FindAndLoadTpuLibrary() {
  const char* env_value = getenv("TPU_LIBRARY_PATH");
  const char* libtpu_path =
      env_value && strlen(env_value) > 0 ? env_value : "libtpu.so";
  LOG(INFO) << "Libtpu path is: " << libtpu_path;
  void* library = dlopen(libtpu_path, RTLD_NOW);
  if (library) {
    // We can open the shared library which means we are in a TPU environment.
    // Try to acquire exclusive access.
    TF_RETURN_IF_ERROR(TryAcquireTpuLock());
    TF_RETURN_IF_ERROR(InitializeTpuLibrary(library));
  }

  InitializeCreateGcsFileSystemFnPtr();
  return Status::OK();
}

#elif defined(LIBTPU_STATIC)

#include "tensorflow/core/tpu/tpu_library_init_fns.inc"

Status InitializeTpuLibrary() {
  // Retrieve arguments from environment if applicable
  std::pair<std::vector<std::string>, std::vector<const char*>> args =
      GetLibTpuInitArguments();

  TfTpu_Initialize(/*init_library*/ true, args.second.size(),
                   args.second.data());

  RegisterTpuPlatform();
  return Status::OK();
}

Status FindAndLoadTpuLibrary() {
  // We can open the shared library which means we are in a TPU environment.
  // Try to acquire exclusive access.
  TF_RETURN_IF_ERROR(TryAcquireTpuLock());
  TF_RETURN_IF_ERROR(InitializeTpuLibrary());
  return Status::OK();
}

#else   // PLATFORM_GOOGLE
Status InitializeTpuLibrary(void* library_handle) {
  return errors::Unimplemented("You must statically link in a TPU library.");
}
#endif  // PLATFORM_GOOGLE
std::pair<std::vector<std::string>, std::vector<const char*>>
GetLibTpuInitArguments() {
  // We make copies of the arguments returned by getenv because the memory
  // returned may be altered or invalidated by further calls to getenv.
  std::vector<std::string> args;
  std::vector<const char*> arg_ptrs;

  // Retrieve arguments from environment if applicable.
  char* env = getenv("LIBTPU_INIT_ARGS");
  if (env != nullptr) {
    // TODO(frankchn): Handles quotes properly if necessary.
    args = absl::StrSplit(env, ' ');
  }

  arg_ptrs.reserve(args.size());
  for (int i = 0; i < args.size(); ++i) {
    arg_ptrs.push_back(args[i].data());
  }

  return {std::move(args), std::move(arg_ptrs)};
}

}  // namespace tpu
}  // namespace tensorflow
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkDCMTKTransformIO.h"
#include "itkDCMTKTransformIOFactory.h"
#include "itkTransformFileReader.h"
#include "itkImageSeriesReader.h"
#include "itkDCMTKImageIO.h"
#include "itkDCMTKSeriesFileNames.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkCompositeTransform.h"
#include "itkImageFileWriter.h"
#include "itkMetaDataObject.h"
#include "itkResampleImageFilter.h"

int ReadDicomTransformAndResampleExample( int argc, char* argv[] )
{
  // Parse command line arguments
  if( argc < 5 )
    {
    std::cerr << "Usage: " << argv[0]
              << " fixedSeriesDirectory movingSeriesDirectory transform fixedImageOutput resampledMovingOutput" << std::endl;
    return EXIT_FAILURE;
    }
  const char * fixedSeriesDirectory = argv[1];
  const char * movingSeriesDirectory = argv[2];
  const char * transformFileName = argv[3];
  const char * fixedImageOutputFileName = argv[4];
  const char * resampledMovingOutputFileName = argv[5];

  // Basic types
  const unsigned int Dimension = 3;
  typedef short                              PixelType;
  typedef itk::Image< PixelType, Dimension > ImageType;

  // Read the fixed and moving image
  typedef itk::ImageSeriesReader< ImageType > ReaderType;
  ReaderType::Pointer fixedReader = ReaderType::New();

  // DCMTKImageIO does not populate the MetaDataDictionary yet
  //typedef itk::DCMTKImageIO ImageIOType;
  typedef itk::GDCMImageIO ImageIOType;
  ImageIOType::Pointer fixedIO = ImageIOType::New();
  fixedReader->SetImageIO( fixedIO );

  //typedef itk::DCMTKSeriesFileNames SeriesFileNamesType;
  typedef itk::GDCMSeriesFileNames SeriesFileNamesType;
  SeriesFileNamesType::Pointer fixedSeriesFileNames = SeriesFileNamesType::New();
  fixedSeriesFileNames->SetInputDirectory( fixedSeriesDirectory );
  typedef SeriesFileNamesType::FileNamesContainerType FileNamesContainerType;
  const FileNamesContainerType & fixedFileNames = fixedSeriesFileNames->GetInputFileNames();
  std::cout << "There are " << fixedFileNames.size() << " fixed image slices." << std::endl;
  std::cout << "First fixed images series UID: " << fixedSeriesFileNames->GetSeriesUIDs()[0] << "\n" << std::endl;
  fixedReader->SetFileNames( fixedFileNames );

  ReaderType::Pointer movingReader = ReaderType::New();
  ImageIOType::Pointer movingIO = ImageIOType::New();
  movingReader->SetImageIO( movingIO );

  SeriesFileNamesType::Pointer movingSeriesFileNames = SeriesFileNamesType::New();
  movingSeriesFileNames->SetInputDirectory( movingSeriesDirectory );
  const FileNamesContainerType &  movingFileNames = movingSeriesFileNames->GetInputFileNames();
  std::cout << "There are " << movingFileNames.size() << " moving image slices." << std::endl;
  std::cout << "First moving images series UID: " << movingSeriesFileNames->GetSeriesUIDs()[0] << "\n" << std::endl;
  movingReader->SetFileNames( movingFileNames );

  try
    {
    fixedReader->Update();
    movingReader->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  // Create a DICOM transform reader
  typedef float ScalarType;

  itk::DCMTKTransformIOFactory::Pointer dcmtkTransformIOFactory = itk::DCMTKTransformIOFactory::New();
  itk::ObjectFactoryBase::RegisterFactory( dcmtkTransformIOFactory );

  typedef itk::TransformFileReaderTemplate< ScalarType > TransformReaderType;
  TransformReaderType::Pointer transformReader = TransformReaderType::New();
  transformReader->SetFileName( transformFileName );

  typedef itk::DCMTKTransformIO< ScalarType > TransformIOType;
  TransformIOType::Pointer transformIO = TransformIOType::New();
  transformReader->SetTransformIO( transformIO );

  // Read in the fixed image transform
  const ReaderType::DictionaryType & fixedMetaDataDict = fixedIO->GetMetaDataDictionary();
  std::string fixedFrameOfReferenceUID;
  if( ! itk::ExposeMetaData< std::string >( fixedMetaDataDict, "0020|0052", fixedFrameOfReferenceUID ) )
    {
    std::cerr << "Could not find the fixed image frame of reference UID." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Fixed image frame of reference UID: " << fixedFrameOfReferenceUID << std::endl;
  transformIO->SetFrameOfReferenceUID( fixedFrameOfReferenceUID );

  try
    {
    transformReader->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }
  typedef TransformReaderType::TransformListType TransformListType;
  TransformListType * transformList = transformReader->GetTransformList();

  typedef itk::CompositeTransform< ScalarType, Dimension > ReadTransformType;
  TransformListType::const_iterator transformIt = transformList->begin();
  ReadTransformType::Pointer fixedTransform = dynamic_cast< ReadTransformType * >( (*transformIt).GetPointer() );
  if( fixedTransform.IsNull() )
    {
    std::cerr << "Did not get the expected transform out." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Fixed transform: " << fixedTransform << std::endl;

  // Read in the moving image transform
  const ReaderType::DictionaryType & movingMetaDataDict = movingIO->GetMetaDataDictionary();
  std::string movingFrameOfReferenceUID;
  if( ! itk::ExposeMetaData< std::string >( movingMetaDataDict, "0020|0052", movingFrameOfReferenceUID ) )
    {
    std::cerr << "Could not find the moving image frame of reference UID." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Moving image frame of reference UID: " << movingFrameOfReferenceUID << std::endl;
  transformIO->SetFrameOfReferenceUID( movingFrameOfReferenceUID );

  try
    {
    transformReader->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  transformList = transformReader->GetTransformList();
  transformIt = transformList->begin();
  ReadTransformType::Pointer movingTransform = dynamic_cast< ReadTransformType * >( (*transformIt).GetPointer() );
  if( movingTransform.IsNull() )
    {
    std::cerr << "Did not get the expected transform out." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Moving transform: " << movingTransform << std::endl;

  // Compose the transform from the fixed to the moving image
  ReadTransformType::Pointer movingTransformInverse = ReadTransformType::New();
  movingTransform->GetInverse( movingTransformInverse );

  ReadTransformType::Pointer fixedToMovingTransform = ReadTransformType::New();
  fixedToMovingTransform->AddTransform( fixedTransform );
  fixedToMovingTransform->AddTransform( movingTransformInverse );
  // Flatten out the two component CompositeTransforms.
  fixedToMovingTransform->FlattenTransformQueue();

  typedef itk::ResampleImageFilter< ImageType, ImageType, ScalarType, ScalarType > ResamplerType;
  ResamplerType::Pointer resampler = ResamplerType::New();
  resampler->SetInput( movingReader->GetOutput() );
  resampler->SetUseReferenceImage( true );
  resampler->SetReferenceImage( fixedReader->GetOutput() );
  resampler->SetTransform( fixedToMovingTransform );
  resampler->SetDefaultPixelValue( -1000 );

  // Write the fixed image and resampled moving image (should look similar)
  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( fixedImageOutputFileName );
  writer->SetInput( fixedReader->GetOutput() );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  writer->SetInput( resampler->GetOutput() );
  writer->SetFileName( resampledMovingOutputFileName );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<commit_msg>STYLE: Line wrap example for inclusion in PDF doc.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkDCMTKTransformIO.h"
#include "itkDCMTKTransformIOFactory.h"
#include "itkTransformFileReader.h"
#include "itkImageSeriesReader.h"
#include "itkDCMTKImageIO.h"
#include "itkDCMTKSeriesFileNames.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkCompositeTransform.h"
#include "itkImageFileWriter.h"
#include "itkMetaDataObject.h"
#include "itkResampleImageFilter.h"

int ReadDicomTransformAndResampleExample( int argc, char* argv[] )
{
  // Parse command line arguments
  if( argc < 5 )
    {
    std::cerr << "Usage: " << argv[0]
              << " fixedSeriesDirectory movingSeriesDirectory"
              << " transform fixedImageOutput resampledMovingOutput"
              << std::endl;
    return EXIT_FAILURE;
    }
  const char * fixedSeriesDirectory = argv[1];
  const char * movingSeriesDirectory = argv[2];
  const char * transformFileName = argv[3];
  const char * fixedImageOutputFileName = argv[4];
  const char * resampledMovingOutputFileName = argv[5];

  // Basic types
  const unsigned int Dimension = 3;
  typedef short                              PixelType;
  typedef itk::Image< PixelType, Dimension > ImageType;

  // Read the fixed and moving image
  typedef itk::ImageSeriesReader< ImageType > ReaderType;
  ReaderType::Pointer fixedReader = ReaderType::New();

  // DCMTKImageIO does not populate the MetaDataDictionary yet
  //typedef itk::DCMTKImageIO ImageIOType;
  typedef itk::GDCMImageIO ImageIOType;
  ImageIOType::Pointer fixedIO = ImageIOType::New();
  fixedReader->SetImageIO( fixedIO );

  //typedef itk::DCMTKSeriesFileNames SeriesFileNamesType;
  typedef itk::GDCMSeriesFileNames SeriesFileNamesType;
  SeriesFileNamesType::Pointer fixedSeriesFileNames =
    SeriesFileNamesType::New();
  fixedSeriesFileNames->SetInputDirectory( fixedSeriesDirectory );
  typedef SeriesFileNamesType::FileNamesContainerType FileNamesContainerType;
  const FileNamesContainerType & fixedFileNames =
    fixedSeriesFileNames->GetInputFileNames();
  std::cout << "There are "
            << fixedFileNames.size()
            << " fixed image slices."
            << std::endl;
  std::cout << "First fixed images series UID: "
            << fixedSeriesFileNames->GetSeriesUIDs()[0]
            << "\n" << std::endl;
  fixedReader->SetFileNames( fixedFileNames );

  ReaderType::Pointer movingReader = ReaderType::New();
  ImageIOType::Pointer movingIO = ImageIOType::New();
  movingReader->SetImageIO( movingIO );

  SeriesFileNamesType::Pointer movingSeriesFileNames =
    SeriesFileNamesType::New();
  movingSeriesFileNames->SetInputDirectory( movingSeriesDirectory );
  const FileNamesContainerType & movingFileNames =
    movingSeriesFileNames->GetInputFileNames();
  std::cout << "There are "
            << movingFileNames.size()
            << " moving image slices."
            << std::endl;
  std::cout << "First moving images series UID: "
            << movingSeriesFileNames->GetSeriesUIDs()[0]
            << "\n" << std::endl;
  movingReader->SetFileNames( movingFileNames );

  try
    {
    fixedReader->Update();
    movingReader->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  // Create a DICOM transform reader
  typedef float ScalarType;

  itk::DCMTKTransformIOFactory::Pointer dcmtkTransformIOFactory =
    itk::DCMTKTransformIOFactory::New();
  itk::ObjectFactoryBase::RegisterFactory( dcmtkTransformIOFactory );

  typedef itk::TransformFileReaderTemplate< ScalarType > TransformReaderType;
  TransformReaderType::Pointer transformReader = TransformReaderType::New();
  transformReader->SetFileName( transformFileName );

  typedef itk::DCMTKTransformIO< ScalarType > TransformIOType;
  TransformIOType::Pointer transformIO = TransformIOType::New();
  transformReader->SetTransformIO( transformIO );

  // Read in the fixed image transform
  const ReaderType::DictionaryType & fixedMetaDataDict =
    fixedIO->GetMetaDataDictionary();
  std::string fixedFrameOfReferenceUID;
  if( ! itk::ExposeMetaData< std::string >( fixedMetaDataDict,
                                            "0020|0052",
                                            fixedFrameOfReferenceUID ) )
    {
    std::cerr << "Could not find the fixed image frame of reference UID." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Fixed image frame of reference UID: "
            << fixedFrameOfReferenceUID << std::endl;
  transformIO->SetFrameOfReferenceUID( fixedFrameOfReferenceUID );

  try
    {
    transformReader->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }
  typedef TransformReaderType::TransformListType TransformListType;
  TransformListType * transformList = transformReader->GetTransformList();

  typedef itk::CompositeTransform< ScalarType, Dimension > ReadTransformType;
  TransformListType::const_iterator transformIt = transformList->begin();
  ReadTransformType::Pointer fixedTransform =
    dynamic_cast< ReadTransformType * >( (*transformIt).GetPointer() );
  if( fixedTransform.IsNull() )
    {
    std::cerr << "Did not get the expected transform out." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Fixed transform: " << fixedTransform << std::endl;

  // Read in the moving image transform
  const ReaderType::DictionaryType & movingMetaDataDict =
    movingIO->GetMetaDataDictionary();
  std::string movingFrameOfReferenceUID;
  if( ! itk::ExposeMetaData< std::string >( movingMetaDataDict,
                                            "0020|0052",
                                            movingFrameOfReferenceUID ) )
    {
    std::cerr << "Could not find the moving image frame of reference UID." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Moving image frame of reference UID: "
            << movingFrameOfReferenceUID << std::endl;
  transformIO->SetFrameOfReferenceUID( movingFrameOfReferenceUID );

  try
    {
    transformReader->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  transformList = transformReader->GetTransformList();
  transformIt = transformList->begin();
  ReadTransformType::Pointer movingTransform =
    dynamic_cast< ReadTransformType * >( (*transformIt).GetPointer() );
  if( movingTransform.IsNull() )
    {
    std::cerr << "Did not get the expected transform out." << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Moving transform: " << movingTransform << std::endl;

  // Compose the transform from the fixed to the moving image
  ReadTransformType::Pointer movingTransformInverse = ReadTransformType::New();
  movingTransform->GetInverse( movingTransformInverse );

  ReadTransformType::Pointer fixedToMovingTransform = ReadTransformType::New();
  fixedToMovingTransform->AddTransform( fixedTransform );
  fixedToMovingTransform->AddTransform( movingTransformInverse );
  // Flatten out the two component CompositeTransforms.
  fixedToMovingTransform->FlattenTransformQueue();

  typedef itk::ResampleImageFilter< ImageType, ImageType, ScalarType, ScalarType >
    ResamplerType;
  ResamplerType::Pointer resampler = ResamplerType::New();
  resampler->SetInput( movingReader->GetOutput() );
  resampler->SetUseReferenceImage( true );
  resampler->SetReferenceImage( fixedReader->GetOutput() );
  resampler->SetTransform( fixedToMovingTransform );
  resampler->SetDefaultPixelValue( -1000 );

  // Write the fixed image and resampled moving image (should look similar)
  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( fixedImageOutputFileName );
  writer->SetInput( fixedReader->GetOutput() );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  writer->SetInput( resampler->GetOutput() );
  writer->SetFileName( resampledMovingOutputFileName );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#ifdef SYMGS_COLOR
#include "ColorSYMGS.hpp"

class colouredForwardSweep{
  public:
  local_int_t colors_row;
  local_int_1d_type colors_ind;

  local_matrix_type A;
  double_1d_type rv, xv;
  int_1d_type matrixDiagonal;

  colouredForwardSweep(const local_int_t colors_row_, const local_int_1d_type& colors_ind_,
    const local_matrix_type& A_, const double_1d_type& rv_, double_1d_type& xv_,
    const int_1d_type matrixDiagonal_):
    colors_row(colors_row_), colors_ind(colors_ind_), A(A_), rv(rv_), xv(xv_),
    matrixDiagonal(matrixDiagonal_) {}

  void operator()(const int & i)const{
    local_int_t currentRow = colors_ind(colors_row + i); // This should tell us what row we're doing SYMGS on.
    int start = A.graph.row_map(currentRow);
    int end = A.graph.row_map(currentRow+1);
    const double currentDiagonal = A.values(matrixDiagonal(currentRow));
    double sum = rv(currentRow);
    for(int j = start; j < end; j++)
      sum -= A.values(j) * xv(A.graph.entries(j));
    sum += xv(currentRow) * currentDiagonal;
    xv(currentRow) = sum/currentDiagonal;
  }
};

class colouredBackSweep{
  public:
  local_int_t colors_row;
  local_int_1d_type colors_ind;

  local_matrix_type A;
  double_1d_type rv, xv;
  int_1d_type matrixDiagonal;

  colouredBackSweep(const local_int_t colors_row_, const local_int_1d_type& colors_ind_,
      const local_matrix_type& A_, const double_1d_type& rv_, double_1d_type& xv_,
      const int_1d_type matrixDiagonal_):
      colors_row(colors_row_), colors_ind(colors_ind_), A(A_), rv(rv_), xv(xv_),
      matrixDiagonal(matrixDiagonal_) {}

  void operator()(const int & i)const{
    local_int_t currentRow = colors_ind(colors_row + i); // This should tell us what row we're doing SYMGS on.
    int start = A.graph.row_map(currentRow);
    int end = A.graph.row_map(currentRow+1);
    const double currentDiagonal = A.values(matrixDiagonal(currentRow));
    double sum = rv(currentRow);
    for(int j = start; j < end; j++)
      sum -= A.values(j) * xv(A.graph.entries(j));
    sum += xv(currentRow) * currentDiagonal;
    xv(currentRow) = sum/currentDiagonal;
  }
};

int ColorSYMGS( const SparseMatrix & A, const Vector & r, Vector & x){
assert(x.localLength == A.localNumberOfColumns); // Make sure x contains space for halo values

#ifndef HPCG_NOMPI
  ExchangeHalo(A,x);
#endif
	 // Forward Sweep!
  const int numColors = A.numColors;
  local_int_t dummy = 0;
  for(int i = 0; i < numColors; i++){
    int currentColor = A.f_colors_order(i);
    int start = A.colors_map(currentColor - 1); // Colors start at 1, i starts at 0
    int end = A.colors_map(currentColor);
    dummy += end - start;
    Kokkos::parallel_for(end - start, colouredForwardSweep(start, A.colors_ind, A.localMatrix, r.values, x.values, A.matrixDiagonal));
  }
  assert(dummy == A.localNumberOfRows);
 // Back Sweep!
  for(int i = numColors -1; i >= 0; --i){
    int currentColor = A.f_colors_order(i);
    int start = A.colors_map(currentColor - 1); // Colors start at 1, i starts at 0
    int end = A.colors_map(currentColor);
    Kokkos::parallel_for(end - start, colouredBackSweep(start, A.colors_ind, A.localMatrix, r.values, x.values, A.matrixDiagonal));
  }

return(0);
}
#endif
<commit_msg>Debugging<commit_after>#ifdef SYMGS_COLOR
#include "ColorSYMGS.hpp"

class colouredForwardSweep{
  public:
  local_int_t colors_row;
  local_int_1d_type colors_ind;

  local_matrix_type A;
  double_1d_type rv, xv;
  int_1d_type matrixDiagonal;

  colouredForwardSweep(const local_int_t colors_row_, const local_int_1d_type& colors_ind_,
    const local_matrix_type& A_, const double_1d_type& rv_, double_1d_type& xv_,
    const int_1d_type matrixDiagonal_):
    colors_row(colors_row_), colors_ind(colors_ind_), A(A_), rv(rv_), xv(xv_),
    matrixDiagonal(matrixDiagonal_) {}

KOKKOS_INLINE_FUNCTION
  void operator()(const int & i)const{
    local_int_t currentRow = colors_ind(colors_row + i); // This should tell us what row we're doing SYMGS on.
    int start = A.graph.row_map(currentRow);
    int end = A.graph.row_map(currentRow+1);
    const double currentDiagonal = A.values(matrixDiagonal(currentRow));
    double sum = rv(currentRow);
    for(int j = start; j < end; j++)
      sum -= A.values(j) * xv(A.graph.entries(j));
    sum += xv(currentRow) * currentDiagonal;
    xv(currentRow) = sum/currentDiagonal;
  }
};

class colouredBackSweep{
  public:
  local_int_t colors_row;
  local_int_1d_type colors_ind;

  local_matrix_type A;
  double_1d_type rv, xv;
  int_1d_type matrixDiagonal;

  colouredBackSweep(const local_int_t colors_row_, const local_int_1d_type& colors_ind_,
      const local_matrix_type& A_, const double_1d_type& rv_, double_1d_type& xv_,
      const int_1d_type matrixDiagonal_):
      colors_row(colors_row_), colors_ind(colors_ind_), A(A_), rv(rv_), xv(xv_),
      matrixDiagonal(matrixDiagonal_) {}
KOKKOS_INLINE_FUNCTION
  void operator()(const int & i)const{
    local_int_t currentRow = colors_ind(colors_row + i); // This should tell us what row we're doing SYMGS on.
    int start = A.graph.row_map(currentRow);
    int end = A.graph.row_map(currentRow+1);
    const double currentDiagonal = A.values(matrixDiagonal(currentRow));
    double sum = rv(currentRow);
    for(int j = start; j < end; j++)
      sum -= A.values(j) * xv(A.graph.entries(j));
    sum += xv(currentRow) * currentDiagonal;
    xv(currentRow) = sum/currentDiagonal;
  }
};

int ColorSYMGS( const SparseMatrix & A, const Vector & r, Vector & x){
assert(x.localLength == A.localNumberOfColumns); // Make sure x contains space for halo values

#ifndef HPCG_NOMPI
  ExchangeHalo(A,x);
#endif
	 // Forward Sweep!
  const int numColors = A.numColors;
  local_int_t dummy = 0;
  for(int i = 0; i < numColors; i++){
    int currentColor = A.f_colors_order(i);
    int start = A.colors_map(currentColor - 1); // Colors start at 1, i starts at 0
    int end = A.colors_map(currentColor);
    dummy += end - start;
    Kokkos::parallel_for(end - start, colouredForwardSweep(start, A.colors_ind, A.localMatrix, r.values, x.values, A.matrixDiagonal));
  }
  assert(dummy == A.localNumberOfRows);
 // Back Sweep!
  for(int i = numColors -1; i >= 0; --i){
    int currentColor = A.f_colors_order(i);
    int start = A.colors_map(currentColor - 1); // Colors start at 1, i starts at 0
    int end = A.colors_map(currentColor);
    Kokkos::parallel_for(end - start, colouredBackSweep(start, A.colors_ind, A.localMatrix, r.values, x.values, A.matrixDiagonal));
  }

return(0);
}
#endif
<|endoftext|>