<commit_before>/** @file gsBoundaryConditions_test.cpp

    @brief test gsPde/gsBoundaryConditions

    This file is part of the G+Smo library.

    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/.

    Author(s): A. Mantzaflaris,  H. Weiner

**/

#include "gismo_unittest.h"
#include <typeinfo>
#include <memory>

std::string getBoxSideExpectedString(std::string string, int index)
{
    std::ostringstream stream;
    std::string result;
    stream << string << " (" << index << ")";
    result = stream.str();
    return result;
}

std::string getBoxSideActualString(gismo::boxSide boxSide)
{
    std::ostringstream stream;
    std::string result;
    stream << boxSide;
    result = stream.str();
    return result;
}

std::string getFunctionExprExpectedString(std::string string)
{
    std::ostringstream stream;
    std::string result;
    stream << "[ " << string << " ]";
    result = stream.str();
    return result;
}

std::string getFunctionExprActualString(gsFunctionExpr<real_t> func)
{
    std::ostringstream stream;
    std::string result;
    func.print(stream);
    result = stream.str();
    return result;
}

gsBoundaryConditions<real_t> gsBoundaryConditions_loadFromFile(std::string path)
{
    gsBoundaryConditions<real_t> result;
    gsReadFile<>(path, result);
    return result;
}

void gsBoundaryConditions_saveToFile(std::string path,
        gsBoundaryConditions<real_t> &sut)
{
    // clean-up before using file
    remove(path.c_str());
    // now save...
    gsFileData<> write;
    write << sut;
    write.dump(path);
}

// create the same gsBoundary condition as in test-data file "bc.xml"
gsBoundaryConditions<real_t> createBcGsBoundaryConditiions()
{
    // set-up
    gsBoundaryConditions<real_t> result;
    return result;
}

gsBoundaryConditions<real_t> createSimpleGsBoundaryConditiions()
{
    gsBoundaryConditions<real_t> result;
    return result;
}

gsFunctionExpr<real_t> getFunctionExpr(boundary_condition<real_t> bc)
{
    CHECK( 0 != dynamic_cast<gsFunctionExpr<real_t>*>(bc.m_function.get()) );
    gsFunction<real_t>::Ptr ptr = bc.m_function;
    gsFunctionExpr<real_t> * ptr2 =
        dynamic_cast<gsFunctionExpr<real_t> *>(ptr.get());
    gsFunctionExpr<real_t> result = *ptr2;
    return result;
}

void checkBoundaryCondition(boundary_condition<real_t> bc, bool parametric,
        std::string label, gismo::condition_type::type conditionType, index_t patch,
        index_t index, int unknown, int unkcomp, short_t domainDim,
        std::string funcName)
{
    // check boundary condition itself
    CHECK_EQUAL(parametric, bc.m_parametric);
    CHECK_EQUAL(label, bc.m_label);
    CHECK_EQUAL(conditionType, bc.m_type);
    CHECK_EQUAL(patch, bc.ps.patch);
    CHECK_EQUAL(index, bc.ps.m_index);
    CHECK_EQUAL(unknown, bc.m_unknown);
    CHECK_EQUAL(unkcomp, bc.m_unkcomp);
    // check functionExpr
    gismo::gsFunctionExpr<real_t> func = getFunctionExpr(bc);
    CHECK_EQUAL(domainDim, func.domainDim());
    std::string expectedName = getFunctionExprExpectedString(funcName);
    std::string actualName = getFunctionExprActualString(func);
    CHECK_EQUAL(expectedName, actualName);
}

void checkGsBoundaryCondition(const gsBoundaryConditions<real_t> & sut)
{
    // check corner value(s)
    gismo::gsBoundaryConditions<real_t>::cornerContainer c1 =
            sut.cornerValues();
    unsigned elems1 = 1;
    CHECK_EQUAL(elems1, c1.size());
    gismo::corner_value<real_t> cv1 = c1[0];
    CHECK_EQUAL(0, cv1.corner);
    CHECK_EQUAL(0, cv1.corner.m_index);
    CHECK_EQUAL(0, cv1.patch);
    CHECK_EQUAL(0.0, cv1.value);
    CHECK_EQUAL(0, cv1.unknown);

    // check dirichlet conditions
    std::string label1 = "Dirichlet";
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc0 = sut.container(
            label1);
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc1 =
            sut.dirichletSides();
    unsigned elems2 = 6;
    CHECK_EQUAL(elems2, bcc0.size());
    CHECK_EQUAL(elems2, bcc1.size());
    // check boundary conditions themselves
    std::string funcName0 = "0";
    int patches[4] =
    { 0, 0, 1, 1 };
    int indizes[4] =
    { 1, 3, 1, 2 };
    int unknown = 0;
    int unkcomp = 0;
    short_t domainDim = 2;
    for (int i = 0; i < 4; i++)
    {
        checkBoundaryCondition(bcc0[i], false, label1,
                gismo::condition_type::dirichlet, patches[i], indizes[i],
                unknown, unkcomp, domainDim, funcName0);
    }

    std::string funcName1 = "sin(pi*x)*sin(pi*y)";
    int patch4 = 0;
    int index4 = 2;
    int patch5 = 0;
    int index5 = 4;
    checkBoundaryCondition(bcc0[4], false, label1,
            gismo::condition_type::dirichlet, patch4, index4, unknown, unkcomp,
            domainDim, funcName1);
    checkBoundaryCondition(bcc0[5], false, label1,
            gismo::condition_type::dirichlet, patch5, index5, unknown, unkcomp,
            domainDim, funcName1);

    // check neumann conditions
    std::string label2 = "Neumann";
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc2 = sut.container(
            label2);
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc3 = sut.neumannSides();
    unsigned elems3 = 2;
    CHECK_EQUAL(elems3, bcc2.size());
    CHECK_EQUAL(elems3, bcc3.size());
    int patch6 = 1;
    int index6 = 3;
    int patch7 = 1;
    int index7 = 4;
    checkBoundaryCondition(bcc2[0], false, label2,
            gismo::condition_type::neumann, patch6, index6, unknown, unkcomp,
            domainDim, funcName0);
    checkBoundaryCondition(bcc3[0], false, label2,
            gismo::condition_type::neumann, patch6, index6, unknown, unkcomp,
            domainDim, funcName0);
    checkBoundaryCondition(bcc2[1], false, label2,
            gismo::condition_type::neumann, patch7, index7, unknown, unkcomp,
            domainDim, funcName0);
    checkBoundaryCondition(bcc3[1], false, label2,
            gismo::condition_type::neumann, patch7, index7, unknown, unkcomp,
            domainDim, funcName0);

    // check robin conditions
    std::string label3 = "Robin";
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc4 = sut.container(
            label3);
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc5 = sut.robinSides();
    unsigned elems4 = 0;
    CHECK_EQUAL(elems4, bcc4.size());
    CHECK_EQUAL(elems4, bcc5.size());
    // check bctype_iterator
    typedef gismo::gsBoundaryConditions<real_t>::const_bciterator bctype_it;
    int c = 0;
    for (bctype_it it = sut.beginAll(); it != sut.endAll(); ++it)
    {
        c++;
    }
    CHECK_EQUAL(3, c);
}

SUITE(gsBoundaryConditions_test)
{
    TEST(test_condition_type)
    {
        gismo::condition_type::type myType = gismo::condition_type::neumann;
        CHECK_EQUAL(gismo::condition_type::neumann, myType);
        CHECK_EQUAL(1, myType);
    }

    TEST(test_function_expr)
    {
        int dim1 = 1;
        std::string funcName1 = "tan(x)";
        gsFunctionExpr<real_t> func1 = gsFunctionExpr<real_t>(funcName1, dim1);
        short_t domainDim1 = func1.domainDim();
        CHECK_EQUAL(dim1, domainDim1);
        std::string expectedName1 = getFunctionExprExpectedString(funcName1);
        std::string actualName1 = getFunctionExprActualString(func1);
        CHECK_EQUAL(expectedName1, actualName1);
        int dim2 = 2;
        std::string funcName2 = "sin(x)*sin(y)";
        gsFunctionExpr<real_t> func2 = gsFunctionExpr<real_t>(funcName2, dim2);
        short_t domainDim2 = func2.domainDim();
        CHECK_EQUAL(dim2, domainDim2);
        std::string expectedName2 = getFunctionExprExpectedString(funcName2);
        std::string actualName2 = getFunctionExprActualString(func2);
        CHECK_EQUAL(expectedName2, actualName2);
    }

    TEST(test_box_side)
    {
        int index1 = 1;
        gismo::boxSide boxSide1 = gismo::boxSide(index1);
        CHECK_EQUAL(index1, boxSide1.m_index);
        std::string expect1 = getBoxSideExpectedString("west", index1);
        std::string actual1 = getBoxSideActualString(boxSide1);
        CHECK_EQUAL(expect1, actual1);
        int index2 = 7;
        gismo::boxSide boxSide2 = gismo::boxSide(index2);
        CHECK_EQUAL(index2, boxSide2.m_index);
        std::string expect2 = getBoxSideExpectedString("side", index2);
        std::string actual2 = getBoxSideActualString(boxSide2);
        CHECK_EQUAL(expect2, actual2);
    }

    TEST(test_boundary_condition)
    {
        int dim1 = 1;
        std::string funcName1 = "tan(x)";
        index_t index1 = 1; // Eigen Index
        index_t index2 = 2; // index_t
        gismo::boxSide boxSide1 = gismo::boxSide(index1);
        gismo::boundary_condition<real_t>::function_ptr funcPtr1 =
                gismo::memory::make_shared(
                        new gsFunctionExpr<real_t>(funcName1, dim1));
        std::string label1 = "Dirichlet";
        bool parametric1 = true;
        int unknown1 = 1;
        int unkcomp1 = 2;
        gismo::boundary_condition<real_t> bound = gismo::boundary_condition<real_t>(
                index2, boxSide1, funcPtr1, label1, unknown1, unkcomp1,
                parametric1);
        CHECK_EQUAL(parametric1, bound.m_parametric);
        CHECK_EQUAL(label1, bound.m_label);
        CHECK_EQUAL(gismo::condition_type::dirichlet, bound.m_type);
        CHECK_EQUAL(index2, bound.ps.patch);
        CHECK_EQUAL(index2, bound.patch());
        CHECK_EQUAL(index1, bound.ps.m_index);
        CHECK_EQUAL(funcPtr1, bound.m_function);
        CHECK_EQUAL(unknown1, bound.m_unknown);
        CHECK_EQUAL(unkcomp1, bound.m_unkcomp);
    }

    TEST(test_box_corner)
    {
        int index1 = 3;
        gismo::boxCorner c1 = gismo::boxCorner(index1);
        CHECK_EQUAL(index1, c1.m_index);
    }

    TEST(test_corner_value)
    {
        int index1 = 3;
        gismo::boxCorner c1 = gismo::boxCorner(index1);
        index_t p1 = 2;
        real_t v1 = 3.0;
        int u1 = 4;
        gismo::corner_value<real_t> cornerVal1 = gismo::corner_value<real_t>(p1, c1,
                v1, u1);
        CHECK_EQUAL(c1, cornerVal1.corner);
        CHECK_EQUAL(index1, cornerVal1.corner.m_index);
        CHECK_EQUAL(p1, cornerVal1.patch);
        CHECK_EQUAL(v1, cornerVal1.value);
        CHECK_EQUAL(u1, cornerVal1.unknown);
    }

    /***
     * test loading from bc.xml
     */
    TEST(load_from_bc_xml)
    {
        std::string path = gsFileManager::findInDataDir( "gsBoundaryConditions/bc.xml" );
        gsBoundaryConditions<real_t> sut = gsBoundaryConditions_loadFromFile(path);
        checkGsBoundaryCondition(sut);
    }

    /***
     * test loading from bc.xml and
     * saving to bc2.xml
     * and ensure that bc.xml and bc2.xml have
     * the same content
     */
    TEST(save_load_bc_xml)
    {
        std::string path1 = gsFileManager::findInDataDir( "gsBoundaryConditions/bc.xml" );
        std::string path2 = gsFileManager::getTempPath() + "/bc2.xml";

        gsBoundaryConditions<real_t> sut = gsBoundaryConditions_loadFromFile(path1);
        gsBoundaryConditions_saveToFile(path2, sut);
        gsBoundaryConditions<real_t> sut2 = gsBoundaryConditions_loadFromFile(path2);
        checkGsBoundaryCondition(sut2);
    }

}
<commit_msg>unittest repair<commit_after>/** @file gsBoundaryConditions_test.cpp

    @brief test gsPde/gsBoundaryConditions

    This file is part of the G+Smo library.

    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/.

    Author(s): A. Mantzaflaris,  H. Weiner

**/

#include "gismo_unittest.h"
#include <typeinfo>
#include <memory>

std::string getBoxSideExpectedString(std::string string, int index)
{
    std::ostringstream stream;
    std::string result;
    stream << string << " (" << index << ")";
    result = stream.str();
    return result;
}

std::string getBoxSideActualString(gismo::boxSide boxSide)
{
    std::ostringstream stream;
    std::string result;
    stream << boxSide;
    result = stream.str();
    return result;
}

std::string getFunctionExprExpectedString(std::string string)
{
    std::ostringstream stream;
    std::string result;
    stream << "[ " << string << " ]";
    result = stream.str();
    return result;
}

std::string getFunctionExprActualString(gsFunctionExpr<real_t> func)
{
    std::ostringstream stream;
    std::string result;
    func.print(stream);
    result = stream.str();
    return result;
}

gsBoundaryConditions<real_t> gsBoundaryConditions_loadFromFile(std::string path)
{
    gsBoundaryConditions<real_t> result;
    gsReadFile<>(path, result);
    return result;
}

void gsBoundaryConditions_saveToFile(std::string path,
        gsBoundaryConditions<real_t> &sut)
{
    // clean-up before using file
    remove(path.c_str());
    // now save...
    gsFileData<> write;
    write << sut;
    write.dump(path);
}

// create the same gsBoundary condition as in test-data file "bc.xml"
gsBoundaryConditions<real_t> createBcGsBoundaryConditiions()
{
    // set-up
    gsBoundaryConditions<real_t> result;
    return result;
}

gsBoundaryConditions<real_t> createSimpleGsBoundaryConditiions()
{
    gsBoundaryConditions<real_t> result;
    return result;
}

gsFunctionExpr<real_t> getFunctionExpr(boundary_condition<real_t> bc)
{
    CHECK( 0 != dynamic_cast<gsFunctionExpr<real_t>*>(bc.m_function.get()) );
    gsFunction<real_t>::Ptr ptr = bc.m_function;
    gsFunctionExpr<real_t> * ptr2 =
        dynamic_cast<gsFunctionExpr<real_t> *>(ptr.get());
    gsFunctionExpr<real_t> result = *ptr2;
    return result;
}

void checkBoundaryCondition(boundary_condition<real_t> bc, bool parametric,
        std::string label, gismo::condition_type::type conditionType, index_t patch,
        index_t index, int unknown, int unkcomp, short_t domainDim,
        std::string funcName)
{
    // check boundary condition itself
    CHECK_EQUAL(parametric, bc.m_parametric);
    CHECK_EQUAL(label, bc.m_label);
    CHECK_EQUAL(conditionType, bc.m_type);
    CHECK_EQUAL(patch, bc.ps.patch);
    CHECK_EQUAL(index, bc.ps.m_index);
    CHECK_EQUAL(unknown, bc.m_unknown);
    CHECK_EQUAL(unkcomp, bc.m_unkcomp);
    // check functionExpr
    gismo::gsFunctionExpr<real_t> func = getFunctionExpr(bc);
    CHECK_EQUAL(domainDim, func.domainDim());
    std::string expectedName = getFunctionExprExpectedString(funcName);
    std::string actualName = getFunctionExprActualString(func);
    CHECK_EQUAL(expectedName, actualName);
}

void checkGsBoundaryCondition(const gsBoundaryConditions<real_t> & sut)
{
    // check corner value(s)
    gismo::gsBoundaryConditions<real_t>::cornerContainer c1 =
            sut.cornerValues();
    unsigned elems1 = 1;
    CHECK_EQUAL(elems1, c1.size());
    gismo::corner_value<real_t> cv1 = c1[0];
    CHECK_EQUAL(0, cv1.corner);
    CHECK_EQUAL(0, cv1.corner.m_index);
    CHECK_EQUAL(0, cv1.patch);
    CHECK_EQUAL(0.0, cv1.value);
    CHECK_EQUAL(0, cv1.unknown);

    // check dirichlet conditions
    std::string label1 = "Dirichlet";
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc0 = sut.container(
            label1);
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc1 =
            sut.dirichletSides();
    unsigned elems2 = 6;
    CHECK_EQUAL(elems2, bcc0.size());
    CHECK_EQUAL(elems2, bcc1.size());
    // check boundary conditions themselves
    std::string funcName0 = "0";
    int patches[4] =
    { 0, 0, 1, 1 };
    int indizes[4] =
    { 1, 3, 1, 2 };
    int unknown = 0;
    int unkcomp = -1; //option not present in the XML yields default value -1
    short_t domainDim = 2;
    for (int i = 0; i < 4; i++)
    {
        checkBoundaryCondition(bcc0[i], false, label1,
                gismo::condition_type::dirichlet, patches[i], indizes[i],
                unknown, unkcomp, domainDim, funcName0);
    }

    std::string funcName1 = "sin(pi*x)*sin(pi*y)";
    int patch4 = 0;
    int index4 = 2;
    int patch5 = 0;
    int index5 = 4;
    checkBoundaryCondition(bcc0[4], false, label1,
            gismo::condition_type::dirichlet, patch4, index4, unknown, unkcomp,
            domainDim, funcName1);
    checkBoundaryCondition(bcc0[5], false, label1,
            gismo::condition_type::dirichlet, patch5, index5, unknown, unkcomp,
            domainDim, funcName1);

    // check neumann conditions
    std::string label2 = "Neumann";
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc2 = sut.container(
            label2);
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc3 = sut.neumannSides();
    unsigned elems3 = 2;
    CHECK_EQUAL(elems3, bcc2.size());
    CHECK_EQUAL(elems3, bcc3.size());
    int patch6 = 1;
    int index6 = 3;
    int patch7 = 1;
    int index7 = 4;
    checkBoundaryCondition(bcc2[0], false, label2,
            gismo::condition_type::neumann, patch6, index6, unknown, unkcomp,
            domainDim, funcName0);
    checkBoundaryCondition(bcc3[0], false, label2,
            gismo::condition_type::neumann, patch6, index6, unknown, unkcomp,
            domainDim, funcName0);
    checkBoundaryCondition(bcc2[1], false, label2,
            gismo::condition_type::neumann, patch7, index7, unknown, unkcomp,
            domainDim, funcName0);
    checkBoundaryCondition(bcc3[1], false, label2,
            gismo::condition_type::neumann, patch7, index7, unknown, unkcomp,
            domainDim, funcName0);

    // check robin conditions
    std::string label3 = "Robin";
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc4 = sut.container(
            label3);
    gismo::gsBoundaryConditions<real_t>::bcContainer bcc5 = sut.robinSides();
    unsigned elems4 = 0;
    CHECK_EQUAL(elems4, bcc4.size());
    CHECK_EQUAL(elems4, bcc5.size());
    // check bctype_iterator
    typedef gismo::gsBoundaryConditions<real_t>::const_bciterator bctype_it;
    int c = 0;
    for (bctype_it it = sut.beginAll(); it != sut.endAll(); ++it)
    {
        c++;
    }
    CHECK_EQUAL(3, c);
}

SUITE(gsBoundaryConditions_test)
{
    TEST(test_condition_type)
    {
        gismo::condition_type::type myType = gismo::condition_type::neumann;
        CHECK_EQUAL(gismo::condition_type::neumann, myType);
        CHECK_EQUAL(1, myType);
    }

    TEST(test_function_expr)
    {
        int dim1 = 1;
        std::string funcName1 = "tan(x)";
        gsFunctionExpr<real_t> func1 = gsFunctionExpr<real_t>(funcName1, dim1);
        short_t domainDim1 = func1.domainDim();
        CHECK_EQUAL(dim1, domainDim1);
        std::string expectedName1 = getFunctionExprExpectedString(funcName1);
        std::string actualName1 = getFunctionExprActualString(func1);
        CHECK_EQUAL(expectedName1, actualName1);
        int dim2 = 2;
        std::string funcName2 = "sin(x)*sin(y)";
        gsFunctionExpr<real_t> func2 = gsFunctionExpr<real_t>(funcName2, dim2);
        short_t domainDim2 = func2.domainDim();
        CHECK_EQUAL(dim2, domainDim2);
        std::string expectedName2 = getFunctionExprExpectedString(funcName2);
        std::string actualName2 = getFunctionExprActualString(func2);
        CHECK_EQUAL(expectedName2, actualName2);
    }

    TEST(test_box_side)
    {
        int index1 = 1;
        gismo::boxSide boxSide1 = gismo::boxSide(index1);
        CHECK_EQUAL(index1, boxSide1.m_index);
        std::string expect1 = getBoxSideExpectedString("west", index1);
        std::string actual1 = getBoxSideActualString(boxSide1);
        CHECK_EQUAL(expect1, actual1);
        int index2 = 7;
        gismo::boxSide boxSide2 = gismo::boxSide(index2);
        CHECK_EQUAL(index2, boxSide2.m_index);
        std::string expect2 = getBoxSideExpectedString("side", index2);
        std::string actual2 = getBoxSideActualString(boxSide2);
        CHECK_EQUAL(expect2, actual2);
    }

    TEST(test_boundary_condition)
    {
        int dim1 = 1;
        std::string funcName1 = "tan(x)";
        index_t index1 = 1; // Eigen Index
        index_t index2 = 2; // index_t
        gismo::boxSide boxSide1 = gismo::boxSide(index1);
        gismo::boundary_condition<real_t>::function_ptr funcPtr1 =
                gismo::memory::make_shared(
                        new gsFunctionExpr<real_t>(funcName1, dim1));
        std::string label1 = "Dirichlet";
        bool parametric1 = true;
        int unknown1 = 1;
        int unkcomp1 = 2;
        gismo::boundary_condition<real_t> bound = gismo::boundary_condition<real_t>(
                index2, boxSide1, funcPtr1, label1, unknown1, unkcomp1,
                parametric1);
        CHECK_EQUAL(parametric1, bound.m_parametric);
        CHECK_EQUAL(label1, bound.m_label);
        CHECK_EQUAL(gismo::condition_type::dirichlet, bound.m_type);
        CHECK_EQUAL(index2, bound.ps.patch);
        CHECK_EQUAL(index2, bound.patch());
        CHECK_EQUAL(index1, bound.ps.m_index);
        CHECK_EQUAL(funcPtr1, bound.m_function);
        CHECK_EQUAL(unknown1, bound.m_unknown);
        CHECK_EQUAL(unkcomp1, bound.m_unkcomp);
    }

    TEST(test_box_corner)
    {
        int index1 = 3;
        gismo::boxCorner c1 = gismo::boxCorner(index1);
        CHECK_EQUAL(index1, c1.m_index);
    }

    TEST(test_corner_value)
    {
        int index1 = 3;
        gismo::boxCorner c1 = gismo::boxCorner(index1);
        index_t p1 = 2;
        real_t v1 = 3.0;
        int u1 = 4;
        gismo::corner_value<real_t> cornerVal1 = gismo::corner_value<real_t>(p1, c1,
                v1, u1);
        CHECK_EQUAL(c1, cornerVal1.corner);
        CHECK_EQUAL(index1, cornerVal1.corner.m_index);
        CHECK_EQUAL(p1, cornerVal1.patch);
        CHECK_EQUAL(v1, cornerVal1.value);
        CHECK_EQUAL(u1, cornerVal1.unknown);
    }

    /***
     * test loading from bc.xml
     */
    TEST(load_from_bc_xml)
    {
        std::string path = gsFileManager::findInDataDir( "gsBoundaryConditions/bc.xml" );
        gsBoundaryConditions<real_t> sut = gsBoundaryConditions_loadFromFile(path);
        checkGsBoundaryCondition(sut);
    }

    /***
     * test loading from bc.xml and
     * saving to bc2.xml
     * and ensure that bc.xml and bc2.xml have
     * the same content
     */
    TEST(save_load_bc_xml)
    {
        std::string path1 = gsFileManager::findInDataDir( "gsBoundaryConditions/bc.xml" );
        std::string path2 = gsFileManager::getTempPath() + "/bc2.xml";

        gsBoundaryConditions<real_t> sut = gsBoundaryConditions_loadFromFile(path1);
        gsBoundaryConditions_saveToFile(path2, sut);
        gsBoundaryConditions<real_t> sut2 = gsBoundaryConditions_loadFromFile(path2);
        checkGsBoundaryCondition(sut2);
    }

}
<|endoftext|>


<commit_before>/* Copyright 2020 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 <stdlib.h>
#include <string.h>
#include <algorithm>
#include <list>
#include <map>
#include <tuple>
#include <vector>

#include "tensorflow/core/common_runtime/device/device_id.h"
#include "tensorflow/core/common_runtime/device/device_id_manager.h"
#include "tensorflow/core/common_runtime/device/device_id_utils.h"
#include "tensorflow/core/common_runtime/device_factory.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_init.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_process_state.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_util.h"
#include "tensorflow/core/framework/allocator.h"

namespace tensorflow {
namespace {

int64 MinSystemMemory(int64 available_memory) {
  // We use the following heuristic for now:
  //
  // If the available_memory is < 2GiB, we allocate 225MiB to system memory,
  // Otherwise, allocate max(300MiB, kMinSystemMemoryFraction *
  // available_memory) to system memory.
  //
  // In the future we could be more sophisticated by using a table of devices.
  int64 min_system_memory;
  constexpr float kMinSystemMemoryFraction = 0.06;
  if (available_memory < (1LL << 31)) {
    // 225MiB
    min_system_memory = 255 * 1024 * 1024;
  } else {
    // max(300 MiB, kMinSystemMemoryFraction * available_memory)
    min_system_memory = std::max(
        int64{314572800},
        static_cast<int64>(available_memory * kMinSystemMemoryFraction));
  }
#if defined(__GNUC__) && defined(__OPTIMIZE__)
// Do nothing
#elif !defined(__GNUC__) && defined(NDEBUG)
// Do nothing
#else
  // Double the amount of available PluggableDevice memory in non-opt builds
  // (debug builds in windows); because in non-opt builds more system memory is
  // necessary.
  min_system_memory *= 2;
#endif
  VLOG(5) << "available_memory = " << available_memory;
  VLOG(5) << "min_system_memory = " << min_system_memory;
  return min_system_memory;
}

// Get the memory limit for the virtual device being created on PluggableDevice
// with 'platform_device_id', when that virtual device is the only
// virtual device being created on that Plugged Device.
Status SingleVirtualDeviceMemoryLimit(const string& platform_name,
                                      const GPUOptions& gpu_options,
                                      PlatformDeviceId platform_device_id,
                                      int64* memory_limit) {
  int64 total_memory = 0;
  int64 available_memory = 0;
  se::Platform* platform = PluggableDeviceMachineManager(platform_name);
  se::StreamExecutor* se =
      DeviceIdUtil::ExecutorForPlatformDeviceId(platform, platform_device_id)
          .ValueOrDie();
  if (!se->DeviceMemoryUsage(&available_memory, &total_memory)) {
    return errors::Unknown(
        "Failed to query available memory for PluggableDevice ",
        platform_device_id.value());
  }

  int64 allocated_memory = 0;
  const double per_process_gpu_memory_fraction =
      gpu_options.per_process_gpu_memory_fraction();
  if (per_process_gpu_memory_fraction > 1.0 ||
      gpu_options.experimental().use_unified_memory()) {
    return errors::Internal("not support unified memory yet.");
  }

  if (per_process_gpu_memory_fraction == 0) {
    allocated_memory = available_memory;
    const int64 min_system_memory = MinSystemMemory(available_memory);
    if (min_system_memory < allocated_memory) {
      allocated_memory -= min_system_memory;
    }
  } else {
    allocated_memory = total_memory * per_process_gpu_memory_fraction;
  }
  *memory_limit = allocated_memory;
  return Status::OK();
}
}  // namespace

PluggableDeviceFactory::PluggableDeviceFactory(const string& device_type,
                                               const string& platform_name)
    : device_type_(device_type), platform_name_(platform_name) {}

Status PluggableDeviceFactory::ListPhysicalDevices(
    std::vector<string>* devices) {
  TF_RETURN_IF_ERROR(ValidatePluggableDeviceMachineManager(platform_name_));
  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);

  int device_count = platform->VisibleDeviceCount();
  for (int i = 0; i < device_count; ++i) {
    const string device_name =
        strings::StrCat("/physical_device:", device_type_, ":", i);
    devices->push_back(device_name);
  }

  return Status::OK();
}

Status PluggableDeviceFactory::GetDeviceDetails(
    int device_index, std::unordered_map<string, string>* details) {
  TF_RETURN_IF_ERROR(ValidatePluggableDeviceMachineManager(platform_name_));
  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
  if (platform == nullptr) {
    return Status::OK();
  }

  int device_count = platform->VisibleDeviceCount();
  if (device_index < 0 || device_index >= device_count) {
    return errors::Internal("Invalid device index: ", device_index);
  }

  auto desc_status = platform->DescriptionForDevice(device_index);
  if (!desc_status.ok()) {
    return desc_status.status();
  }

  auto desc = desc_status.ConsumeValueOrDie();
  (*details)["device_name"] = desc->name();
  return Status::OK();
}

Status PluggableDeviceFactory::CreateDevices(
    const SessionOptions& options, const string& name_prefix,
    std::vector<std::unique_ptr<Device>>* devices) {
  TF_RETURN_IF_ERROR(ValidatePluggableDeviceMachineManager(platform_name_));
  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
  if (platform == nullptr) {
    return Status::OK();
  }

  if (platform->VisibleDeviceCount() <= 0) {
    return Status::OK();
  }

  size_t num_devices_to_use = INT_MAX;
  auto iter = options.config.device_count().find(device_type_);
  if (iter != options.config.device_count().end()) {
    num_devices_to_use = iter->second;
  }
  const auto& gpu_options = options.config.gpu_options();
  std::vector<PlatformDeviceId> visible_device_order;

  if (num_devices_to_use > 0) {
    TF_RETURN_IF_ERROR(DeviceIdUtil::ParseVisibleDeviceList(
        gpu_options.visible_device_list(), platform->VisibleDeviceCount(),
        &visible_device_order));
  }
  if (num_devices_to_use > visible_device_order.size()) {
    num_devices_to_use = visible_device_order.size();
  }

  const auto& virtual_devices = gpu_options.experimental().virtual_devices();
  if (!virtual_devices.empty())
    VLOG(2) << "Pluggable device does not support virtual device setting yet";
  int next_tf_device_id = 0;
  std::vector<int64> memory_limit_bytes;
  for (int i = 0; i < num_devices_to_use; ++i) {
    const PlatformDeviceId platform_device_id = visible_device_order[i];
    int64 single_virtual_device_memory_limit = 0;
    TF_RETURN_IF_ERROR(SingleVirtualDeviceMemoryLimit(
        platform_name_, gpu_options, platform_device_id,
        &single_virtual_device_memory_limit));
    memory_limit_bytes.push_back(single_virtual_device_memory_limit);
    while (next_tf_device_id < memory_limit_bytes.size()) {
      TfDeviceId tf_device_id(next_tf_device_id);
      ++next_tf_device_id;
      TF_RETURN_IF_ERROR(DeviceIdManager::InsertTfPlatformDeviceIdPair(
          DeviceType(device_type_), tf_device_id, platform_device_id));
    }
  }
  const int num_tf_devices = next_tf_device_id;

  std::vector<DeviceLocality> device_localities;
  TF_RETURN_IF_ERROR(GetDeviceLocalities(num_tf_devices, &device_localities));

  // Build the PluggableDevices.
  CHECK_EQ(next_tf_device_id, memory_limit_bytes.size());
  for (int di = 0; di < num_tf_devices; ++di) {
    TfDeviceId tf_device_id(di);
    int64 bytes = memory_limit_bytes[di];
    TF_RETURN_IF_ERROR(CreatePluggableDevice(options, name_prefix, tf_device_id,
                                             bytes, device_localities[di],
                                             devices));
  }
}

static string GetShortDeviceDescription(PlatformDeviceId platform_device_id,
                                        const se::DeviceDescription& desc) {
  return strings::StrCat("device: ", platform_device_id.value(),
                         ", name: ", desc.name(),
                         ", pci bus id: ", desc.pci_bus_id());
}

Status PluggableDeviceFactory::CreatePluggableDevice(
    const SessionOptions& options, const string& name_prefix,
    TfDeviceId tf_device_id, int64 memory_limit,
    const DeviceLocality& dev_locality,
    std::vector<std::unique_ptr<Device>>* devices) {
  CHECK_GE(tf_device_id.value(), 0);
  const string device_name = strings::StrCat(
      name_prefix, "/device:", device_type_, ":", tf_device_id.value());

  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
  DeviceIdUtil::CheckValidTfDeviceId(DeviceType(device_type_), platform,
                                     tf_device_id);
  PlatformDeviceId platform_device_id;
  TF_RETURN_IF_ERROR(DeviceIdManager::TfToPlatformDeviceId(
      DeviceType(device_type_), tf_device_id, &platform_device_id));
  int numa_node = dev_locality.numa_node();

  auto desc_status = platform->DescriptionForDevice(platform_device_id.value());
  if (!desc_status.ok()) {
    return desc_status.status();
  }
  auto desc = desc_status.ConsumeValueOrDie();
  PluggableDeviceProcessState* process_state =
      PluggableDeviceProcessState::singleton(device_type_, platform_name_);
  Allocator* device_allocator = process_state->GetPluggableDeviceAllocator(
      options.config.gpu_options(), tf_device_id, memory_limit);
  if (device_allocator == nullptr) {
    return errors::Internal(
        "Failed to get memory allocator for TF PluggableDevice ",
        tf_device_id.value(), " with", memory_limit, " bytes of memory. ");
  }
  absl::optional<AllocatorStats> stats = device_allocator->GetStats();
  if (!stats) {
    return errors::Internal("No allocator statistics");
  }
  // 'memory_limit' is the required memory size, but if the allocator with
  // given tf_device_id was created before, we'll use it instead of creating
  // a new one (as Tf Device is a shared resource), in which case the actual
  // memory limit represented by 'stats.bytes_limit' used by that allocator
  // may be different(which should be an error);
  int64 bytes_limit = stats->bytes_limit ? *stats->bytes_limit : 0;
  std::unique_ptr<PluggableDevice> pluggable_device =
      absl::make_unique<PluggableDevice>(
          options, device_name, device_type_, platform_name_,
          static_cast<Bytes>(bytes_limit), dev_locality, tf_device_id,
          GetShortDeviceDescription(platform_device_id, *desc),
          device_allocator,
          ProcessState::singleton()->GetCPUAllocator(numa_node),
          false /*sync every op*/);
  LOG(INFO) << "Created TensorFlow device (" << device_name << "  with "
            << (bytes_limit >> 20)
            << " MB memory) -> physical PluggableDevice ("
            << GetShortDeviceDescription(platform_device_id, *desc) << ")";
  TF_RETURN_IF_ERROR(pluggable_device->Init(options));
  devices->push_back(std::move(pluggable_device));
  return Status::OK();
}

Status PluggableDeviceFactory::GetDeviceLocalities(
    int num_tf_devices, std::vector<DeviceLocality>* device_localities) {
  std::vector<TfDeviceId> all_tf_device_ids;
  all_tf_device_ids.reserve(num_tf_devices);
  for (int i = 0; i < num_tf_devices; ++i) {
    all_tf_device_ids.push_back(TfDeviceId(i));
  }
  for (TfDeviceId tf_device_id : all_tf_device_ids) {
    PlatformDeviceId platform_device_id;
    TF_RETURN_IF_ERROR(DeviceIdManager::TfToPlatformDeviceId(
        DeviceType(device_type_), tf_device_id, &platform_device_id));
    // Get Plugged device bus_id from its reported NUMA affinity. Because
    // devices are virtualized in some environment, we can't just use the device
    // id. NUMA locales are indexed from 0, buses are indexed from 1.
    se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
    auto desc_status =
        platform->DescriptionForDevice(platform_device_id.value());
    if (!desc_status.ok()) {
      return desc_status.status();
    }
    auto desc = desc_status.ConsumeValueOrDie();
    int numa_node = desc->numa_node();
    if (numa_node < 0) {
      // For some reason the StreamExecutor couldn't get the NUMA
      // affinity of the device. If this is not a multi-socket mobo with
      // devices local to different buses, it doesn't matter. If it is,
      // we may run into trouble later with data transfer operations.
      // The trouble may manifest as slower than expected performance,
      // or outright features.
      LOG(INFO) << "Could not identify NUMA node of platform " << device_type_
                << "Id" << platform_device_id
                << ", defaulting to 0. Your kernel may not have been built "
                << "with NUMA support. ";
      numa_node = 0;
    }
    DeviceLocality dev_locality;
    dev_locality.set_numa_node(numa_node);
    dev_locality.set_bus_id(numa_node + 1);
    device_localities->push_back(dev_locality);
    VLOG(1) << "PluggableDevice PlatformId" << platform_device_id
            << "TfDeviceId " << tf_device_id << "on bus "
            << dev_locality.bus_id() << " numa: " << numa_node;
  }
  return Status::OK();
}

}  // namespace tensorflow
<commit_msg>fix no return value error<commit_after>/* Copyright 2020 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 <stdlib.h>
#include <string.h>
#include <algorithm>
#include <list>
#include <map>
#include <tuple>
#include <vector>

#include "tensorflow/core/common_runtime/device/device_id.h"
#include "tensorflow/core/common_runtime/device/device_id_manager.h"
#include "tensorflow/core/common_runtime/device/device_id_utils.h"
#include "tensorflow/core/common_runtime/device_factory.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_init.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_process_state.h"
#include "tensorflow/core/common_runtime/pluggable_device/pluggable_device_util.h"
#include "tensorflow/core/framework/allocator.h"

namespace tensorflow {
namespace {

int64 MinSystemMemory(int64 available_memory) {
  // We use the following heuristic for now:
  //
  // If the available_memory is < 2GiB, we allocate 225MiB to system memory,
  // Otherwise, allocate max(300MiB, kMinSystemMemoryFraction *
  // available_memory) to system memory.
  //
  // In the future we could be more sophisticated by using a table of devices.
  int64 min_system_memory;
  constexpr float kMinSystemMemoryFraction = 0.06;
  if (available_memory < (1LL << 31)) {
    // 225MiB
    min_system_memory = 255 * 1024 * 1024;
  } else {
    // max(300 MiB, kMinSystemMemoryFraction * available_memory)
    min_system_memory = std::max(
        int64{314572800},
        static_cast<int64>(available_memory * kMinSystemMemoryFraction));
  }
#if defined(__GNUC__) && defined(__OPTIMIZE__)
// Do nothing
#elif !defined(__GNUC__) && defined(NDEBUG)
// Do nothing
#else
  // Double the amount of available PluggableDevice memory in non-opt builds
  // (debug builds in windows); because in non-opt builds more system memory is
  // necessary.
  min_system_memory *= 2;
#endif
  VLOG(5) << "available_memory = " << available_memory;
  VLOG(5) << "min_system_memory = " << min_system_memory;
  return min_system_memory;
}

// Get the memory limit for the virtual device being created on PluggableDevice
// with 'platform_device_id', when that virtual device is the only
// virtual device being created on that Plugged Device.
Status SingleVirtualDeviceMemoryLimit(const string& platform_name,
                                      const GPUOptions& gpu_options,
                                      PlatformDeviceId platform_device_id,
                                      int64* memory_limit) {
  int64 total_memory = 0;
  int64 available_memory = 0;
  se::Platform* platform = PluggableDeviceMachineManager(platform_name);
  se::StreamExecutor* se =
      DeviceIdUtil::ExecutorForPlatformDeviceId(platform, platform_device_id)
          .ValueOrDie();
  if (!se->DeviceMemoryUsage(&available_memory, &total_memory)) {
    return errors::Unknown(
        "Failed to query available memory for PluggableDevice ",
        platform_device_id.value());
  }

  int64 allocated_memory = 0;
  const double per_process_gpu_memory_fraction =
      gpu_options.per_process_gpu_memory_fraction();
  if (per_process_gpu_memory_fraction > 1.0 ||
      gpu_options.experimental().use_unified_memory()) {
    return errors::Internal("not support unified memory yet.");
  }

  if (per_process_gpu_memory_fraction == 0) {
    allocated_memory = available_memory;
    const int64 min_system_memory = MinSystemMemory(available_memory);
    if (min_system_memory < allocated_memory) {
      allocated_memory -= min_system_memory;
    }
  } else {
    allocated_memory = total_memory * per_process_gpu_memory_fraction;
  }
  *memory_limit = allocated_memory;
  return Status::OK();
}
}  // namespace

PluggableDeviceFactory::PluggableDeviceFactory(const string& device_type,
                                               const string& platform_name)
    : device_type_(device_type), platform_name_(platform_name) {}

Status PluggableDeviceFactory::ListPhysicalDevices(
    std::vector<string>* devices) {
  TF_RETURN_IF_ERROR(ValidatePluggableDeviceMachineManager(platform_name_));
  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);

  int device_count = platform->VisibleDeviceCount();
  for (int i = 0; i < device_count; ++i) {
    const string device_name =
        strings::StrCat("/physical_device:", device_type_, ":", i);
    devices->push_back(device_name);
  }

  return Status::OK();
}

Status PluggableDeviceFactory::GetDeviceDetails(
    int device_index, std::unordered_map<string, string>* details) {
  TF_RETURN_IF_ERROR(ValidatePluggableDeviceMachineManager(platform_name_));
  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
  if (platform == nullptr) {
    return Status::OK();
  }

  int device_count = platform->VisibleDeviceCount();
  if (device_index < 0 || device_index >= device_count) {
    return errors::Internal("Invalid device index: ", device_index);
  }

  auto desc_status = platform->DescriptionForDevice(device_index);
  if (!desc_status.ok()) {
    return desc_status.status();
  }

  auto desc = desc_status.ConsumeValueOrDie();
  (*details)["device_name"] = desc->name();
  return Status::OK();
}

Status PluggableDeviceFactory::CreateDevices(
    const SessionOptions& options, const string& name_prefix,
    std::vector<std::unique_ptr<Device>>* devices) {
  TF_RETURN_IF_ERROR(ValidatePluggableDeviceMachineManager(platform_name_));
  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
  if (platform == nullptr) {
    return Status::OK();
  }

  if (platform->VisibleDeviceCount() <= 0) {
    return Status::OK();
  }

  size_t num_devices_to_use = INT_MAX;
  auto iter = options.config.device_count().find(device_type_);
  if (iter != options.config.device_count().end()) {
    num_devices_to_use = iter->second;
  }
  const auto& gpu_options = options.config.gpu_options();
  std::vector<PlatformDeviceId> visible_device_order;

  if (num_devices_to_use > 0) {
    TF_RETURN_IF_ERROR(DeviceIdUtil::ParseVisibleDeviceList(
        gpu_options.visible_device_list(), platform->VisibleDeviceCount(),
        &visible_device_order));
  }
  if (num_devices_to_use > visible_device_order.size()) {
    num_devices_to_use = visible_device_order.size();
  }

  const auto& virtual_devices = gpu_options.experimental().virtual_devices();
  if (!virtual_devices.empty())
    VLOG(2) << "Pluggable device does not support virtual device setting yet";
  int next_tf_device_id = 0;
  std::vector<int64> memory_limit_bytes;
  for (int i = 0; i < num_devices_to_use; ++i) {
    const PlatformDeviceId platform_device_id = visible_device_order[i];
    int64 single_virtual_device_memory_limit = 0;
    TF_RETURN_IF_ERROR(SingleVirtualDeviceMemoryLimit(
        platform_name_, gpu_options, platform_device_id,
        &single_virtual_device_memory_limit));
    memory_limit_bytes.push_back(single_virtual_device_memory_limit);
    while (next_tf_device_id < memory_limit_bytes.size()) {
      TfDeviceId tf_device_id(next_tf_device_id);
      ++next_tf_device_id;
      TF_RETURN_IF_ERROR(DeviceIdManager::InsertTfPlatformDeviceIdPair(
          DeviceType(device_type_), tf_device_id, platform_device_id));
    }
  }
  const int num_tf_devices = next_tf_device_id;

  std::vector<DeviceLocality> device_localities;
  TF_RETURN_IF_ERROR(GetDeviceLocalities(num_tf_devices, &device_localities));

  // Build the PluggableDevices.
  CHECK_EQ(next_tf_device_id, memory_limit_bytes.size());
  for (int di = 0; di < num_tf_devices; ++di) {
    TfDeviceId tf_device_id(di);
    int64 bytes = memory_limit_bytes[di];
    TF_RETURN_IF_ERROR(CreatePluggableDevice(options, name_prefix, tf_device_id,
                                             bytes, device_localities[di],
                                             devices));
  }
  return Status::OK();
}

static string GetShortDeviceDescription(PlatformDeviceId platform_device_id,
                                        const se::DeviceDescription& desc) {
  return strings::StrCat("device: ", platform_device_id.value(),
                         ", name: ", desc.name(),
                         ", pci bus id: ", desc.pci_bus_id());
}

Status PluggableDeviceFactory::CreatePluggableDevice(
    const SessionOptions& options, const string& name_prefix,
    TfDeviceId tf_device_id, int64 memory_limit,
    const DeviceLocality& dev_locality,
    std::vector<std::unique_ptr<Device>>* devices) {
  CHECK_GE(tf_device_id.value(), 0);
  const string device_name = strings::StrCat(
      name_prefix, "/device:", device_type_, ":", tf_device_id.value());

  se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
  DeviceIdUtil::CheckValidTfDeviceId(DeviceType(device_type_), platform,
                                     tf_device_id);
  PlatformDeviceId platform_device_id;
  TF_RETURN_IF_ERROR(DeviceIdManager::TfToPlatformDeviceId(
      DeviceType(device_type_), tf_device_id, &platform_device_id));
  int numa_node = dev_locality.numa_node();

  auto desc_status = platform->DescriptionForDevice(platform_device_id.value());
  if (!desc_status.ok()) {
    return desc_status.status();
  }
  auto desc = desc_status.ConsumeValueOrDie();
  PluggableDeviceProcessState* process_state =
      PluggableDeviceProcessState::singleton(device_type_, platform_name_);
  Allocator* device_allocator = process_state->GetPluggableDeviceAllocator(
      options.config.gpu_options(), tf_device_id, memory_limit);
  if (device_allocator == nullptr) {
    return errors::Internal(
        "Failed to get memory allocator for TF PluggableDevice ",
        tf_device_id.value(), " with", memory_limit, " bytes of memory. ");
  }
  absl::optional<AllocatorStats> stats = device_allocator->GetStats();
  if (!stats) {
    return errors::Internal("No allocator statistics");
  }
  // 'memory_limit' is the required memory size, but if the allocator with
  // given tf_device_id was created before, we'll use it instead of creating
  // a new one (as Tf Device is a shared resource), in which case the actual
  // memory limit represented by 'stats.bytes_limit' used by that allocator
  // may be different(which should be an error);
  int64 bytes_limit = stats->bytes_limit ? *stats->bytes_limit : 0;
  std::unique_ptr<PluggableDevice> pluggable_device =
      absl::make_unique<PluggableDevice>(
          options, device_name, device_type_, platform_name_,
          static_cast<Bytes>(bytes_limit), dev_locality, tf_device_id,
          GetShortDeviceDescription(platform_device_id, *desc),
          device_allocator,
          ProcessState::singleton()->GetCPUAllocator(numa_node),
          false /*sync every op*/);
  LOG(INFO) << "Created TensorFlow device (" << device_name << "  with "
            << (bytes_limit >> 20)
            << " MB memory) -> physical PluggableDevice ("
            << GetShortDeviceDescription(platform_device_id, *desc) << ")";
  TF_RETURN_IF_ERROR(pluggable_device->Init(options));
  devices->push_back(std::move(pluggable_device));
  return Status::OK();
}

Status PluggableDeviceFactory::GetDeviceLocalities(
    int num_tf_devices, std::vector<DeviceLocality>* device_localities) {
  std::vector<TfDeviceId> all_tf_device_ids;
  all_tf_device_ids.reserve(num_tf_devices);
  for (int i = 0; i < num_tf_devices; ++i) {
    all_tf_device_ids.push_back(TfDeviceId(i));
  }
  for (TfDeviceId tf_device_id : all_tf_device_ids) {
    PlatformDeviceId platform_device_id;
    TF_RETURN_IF_ERROR(DeviceIdManager::TfToPlatformDeviceId(
        DeviceType(device_type_), tf_device_id, &platform_device_id));
    // Get Plugged device bus_id from its reported NUMA affinity. Because
    // devices are virtualized in some environment, we can't just use the device
    // id. NUMA locales are indexed from 0, buses are indexed from 1.
    se::Platform* platform = PluggableDeviceMachineManager(platform_name_);
    auto desc_status =
        platform->DescriptionForDevice(platform_device_id.value());
    if (!desc_status.ok()) {
      return desc_status.status();
    }
    auto desc = desc_status.ConsumeValueOrDie();
    int numa_node = desc->numa_node();
    if (numa_node < 0) {
      // For some reason the StreamExecutor couldn't get the NUMA
      // affinity of the device. If this is not a multi-socket mobo with
      // devices local to different buses, it doesn't matter. If it is,
      // we may run into trouble later with data transfer operations.
      // The trouble may manifest as slower than expected performance,
      // or outright features.
      LOG(INFO) << "Could not identify NUMA node of platform " << device_type_
                << "Id" << platform_device_id
                << ", defaulting to 0. Your kernel may not have been built "
                << "with NUMA support. ";
      numa_node = 0;
    }
    DeviceLocality dev_locality;
    dev_locality.set_numa_node(numa_node);
    dev_locality.set_bus_id(numa_node + 1);
    device_localities->push_back(dev_locality);
    VLOG(1) << "PluggableDevice PlatformId" << platform_device_id
            << "TfDeviceId " << tf_device_id << "on bus "
            << dev_locality.bus_id() << " numa: " << numa_node;
  }
  return Status::OK();
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>#include "response.hh"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using testing::Field;
using testing::UnorderedElementsAre;

TEST(ResponseTest, ParsesSuccessResponse) {
  using namespace std::chrono_literals;

  const aur::RpcResponse response(R"({
    "version": 5,
    "type": "multiinfo",
    "resultcount": 1,
    "results": [
      {
        "ID": 534056,
        "Name": "auracle-git",
        "PackageBaseID": 123768,
        "PackageBase": "auracle-git",
        "Version": "r36.752e4ba-1",
        "Description": "A flexible client for the AUR",
        "URL": "https://github.com/falconindy/auracle.git",
        "NumVotes": 15,
        "Popularity": 0.095498,
        "OutOfDate": null,
        "Maintainer": "falconindy",
        "FirstSubmitted": 1499013608,
        "LastModified": 1534000474,
        "URLPath": "/cgit/aur.git/snapshot/auracle-git.tar.gz",
        "Depends": [
          "pacman",
          "libarchive.so",
          "libcurl.so"
        ],
        "Groups": [
          "whydoestheaurhavegroups"
        ],
        "CheckDepends": [
          "python"
        ],
        "MakeDepends": [
          "meson",
          "git",
          "nlohmann-json"
        ],
        "Conflicts": [
          "auracle"
        ],
        "Provides": [
          "auracle"
        ],
        "License": [
          "MIT"
        ],
        "Replaces": [
          "cower-git",
          "cower"
        ],
        "OptDepends": [
          "awesomeness"
        ],
        "Keywords": [
          "aur"
        ]
      }
    ]
  })");

  EXPECT_EQ(response.type, "multiinfo");
  EXPECT_EQ(response.version, 5);
  EXPECT_EQ(response.resultcount, 1);
  ASSERT_EQ(response.results.size(), 1);

  const auto& result = response.results[0];
  EXPECT_EQ(result.package_id, 534056);
  EXPECT_EQ(result.name, "auracle-git");
  EXPECT_EQ(result.pkgbase_id, 123768);
  EXPECT_EQ(result.version, "r36.752e4ba-1");
  EXPECT_EQ(result.description, "A flexible client for the AUR");
  EXPECT_EQ(result.upstream_url, "https://github.com/falconindy/auracle.git");
  EXPECT_EQ(result.votes, 15);
  EXPECT_EQ(result.popularity, 0.095498);
  EXPECT_EQ(result.out_of_date, 0s);
  EXPECT_EQ(result.submitted, 1499013608s);
  EXPECT_EQ(result.modified, 1534000474s);
  EXPECT_EQ(result.maintainer, "falconindy");
  EXPECT_EQ(result.aur_urlpath, "/cgit/aur.git/snapshot/auracle-git.tar.gz");
  EXPECT_THAT(
      result.depends,
      UnorderedElementsAre(Field(&aur::Dependency::depstring, "pacman"),
                           Field(&aur::Dependency::depstring, "libarchive.so"),
                           Field(&aur::Dependency::depstring, "libcurl.so")));
  EXPECT_THAT(result.makedepends,
              UnorderedElementsAre(
                  Field(&aur::Dependency::depstring, "meson"),
                  Field(&aur::Dependency::depstring, "git"),
                  Field(&aur::Dependency::depstring, "nlohmann-json")));
  EXPECT_THAT(result.checkdepends, UnorderedElementsAre(Field(
                                       &aur::Dependency::depstring, "python")));
  EXPECT_THAT(result.optdepends, UnorderedElementsAre("awesomeness"));
  EXPECT_THAT(result.conflicts, UnorderedElementsAre("auracle"));
  EXPECT_THAT(result.replaces, UnorderedElementsAre("cower", "cower-git"));
  EXPECT_THAT(result.provides, UnorderedElementsAre("auracle"));
  EXPECT_THAT(result.licenses, UnorderedElementsAre("MIT"));
  EXPECT_THAT(result.keywords, UnorderedElementsAre("aur"));
  EXPECT_THAT(result.groups, UnorderedElementsAre("whydoestheaurhavegroups"));
}

TEST(ResponseTest, ParsesErrorResponse) {
  const aur::RpcResponse response(R"({
    "version": 5,
    "type": "error",
    "resultcount": 0,
    "results": [],
    "error": "something"
  })");

  EXPECT_EQ(response.version, 5);
  EXPECT_EQ(response.type, "error");
  EXPECT_EQ(response.resultcount, 0);
  EXPECT_THAT(response.results, testing::IsEmpty());
  EXPECT_EQ(response.error, "something");
}

TEST(ResponseTest, GracefullyHandlesInvalidJson) {
  const aur::RpcResponse response(R"({
    "version": 5,
    "type": "multiinfo,
    "resultcount": 0,
    "results": [],
    "error": "something"
  })");

  ASSERT_EQ(response.type, "error");
  ASSERT_EQ(response.error, testing::HasSubstr("parse error"));
}
<commit_msg>Fix bogus assertion from prior commit<commit_after>#include "response.hh"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using testing::Field;
using testing::UnorderedElementsAre;

TEST(ResponseTest, ParsesSuccessResponse) {
  using namespace std::chrono_literals;

  const aur::RpcResponse response(R"({
    "version": 5,
    "type": "multiinfo",
    "resultcount": 1,
    "results": [
      {
        "ID": 534056,
        "Name": "auracle-git",
        "PackageBaseID": 123768,
        "PackageBase": "auracle-git",
        "Version": "r36.752e4ba-1",
        "Description": "A flexible client for the AUR",
        "URL": "https://github.com/falconindy/auracle.git",
        "NumVotes": 15,
        "Popularity": 0.095498,
        "OutOfDate": null,
        "Maintainer": "falconindy",
        "FirstSubmitted": 1499013608,
        "LastModified": 1534000474,
        "URLPath": "/cgit/aur.git/snapshot/auracle-git.tar.gz",
        "Depends": [
          "pacman",
          "libarchive.so",
          "libcurl.so"
        ],
        "Groups": [
          "whydoestheaurhavegroups"
        ],
        "CheckDepends": [
          "python"
        ],
        "MakeDepends": [
          "meson",
          "git",
          "nlohmann-json"
        ],
        "Conflicts": [
          "auracle"
        ],
        "Provides": [
          "auracle"
        ],
        "License": [
          "MIT"
        ],
        "Replaces": [
          "cower-git",
          "cower"
        ],
        "OptDepends": [
          "awesomeness"
        ],
        "Keywords": [
          "aur"
        ]
      }
    ]
  })");

  EXPECT_EQ(response.type, "multiinfo");
  EXPECT_EQ(response.version, 5);
  EXPECT_EQ(response.resultcount, 1);
  ASSERT_EQ(response.results.size(), 1);

  const auto& result = response.results[0];
  EXPECT_EQ(result.package_id, 534056);
  EXPECT_EQ(result.name, "auracle-git");
  EXPECT_EQ(result.pkgbase_id, 123768);
  EXPECT_EQ(result.version, "r36.752e4ba-1");
  EXPECT_EQ(result.description, "A flexible client for the AUR");
  EXPECT_EQ(result.upstream_url, "https://github.com/falconindy/auracle.git");
  EXPECT_EQ(result.votes, 15);
  EXPECT_EQ(result.popularity, 0.095498);
  EXPECT_EQ(result.out_of_date, 0s);
  EXPECT_EQ(result.submitted, 1499013608s);
  EXPECT_EQ(result.modified, 1534000474s);
  EXPECT_EQ(result.maintainer, "falconindy");
  EXPECT_EQ(result.aur_urlpath, "/cgit/aur.git/snapshot/auracle-git.tar.gz");
  EXPECT_THAT(
      result.depends,
      UnorderedElementsAre(Field(&aur::Dependency::depstring, "pacman"),
                           Field(&aur::Dependency::depstring, "libarchive.so"),
                           Field(&aur::Dependency::depstring, "libcurl.so")));
  EXPECT_THAT(result.makedepends,
              UnorderedElementsAre(
                  Field(&aur::Dependency::depstring, "meson"),
                  Field(&aur::Dependency::depstring, "git"),
                  Field(&aur::Dependency::depstring, "nlohmann-json")));
  EXPECT_THAT(result.checkdepends, UnorderedElementsAre(Field(
                                       &aur::Dependency::depstring, "python")));
  EXPECT_THAT(result.optdepends, UnorderedElementsAre("awesomeness"));
  EXPECT_THAT(result.conflicts, UnorderedElementsAre("auracle"));
  EXPECT_THAT(result.replaces, UnorderedElementsAre("cower", "cower-git"));
  EXPECT_THAT(result.provides, UnorderedElementsAre("auracle"));
  EXPECT_THAT(result.licenses, UnorderedElementsAre("MIT"));
  EXPECT_THAT(result.keywords, UnorderedElementsAre("aur"));
  EXPECT_THAT(result.groups, UnorderedElementsAre("whydoestheaurhavegroups"));
}

TEST(ResponseTest, ParsesErrorResponse) {
  const aur::RpcResponse response(R"({
    "version": 5,
    "type": "error",
    "resultcount": 0,
    "results": [],
    "error": "something"
  })");

  EXPECT_EQ(response.version, 5);
  EXPECT_EQ(response.type, "error");
  EXPECT_EQ(response.resultcount, 0);
  EXPECT_THAT(response.results, testing::IsEmpty());
  EXPECT_EQ(response.error, "something");
}

TEST(ResponseTest, GracefullyHandlesInvalidJson) {
  const aur::RpcResponse response(R"({
    "version": 5,
    "type": "multiinfo,
    "resultcount": 0,
    "results": [],
    "error": "something"
  })");

  ASSERT_EQ(response.type, "error");
  ASSERT_THAT(response.error, testing::HasSubstr("parse error"));
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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 "AuthManager.h"
#include "AuthRequest.h"
#include "AclManager.h"
#include "NebulaUtil.h"
#include "PoolObjectAuth.h"
#include "Nebula.h"
#include <regex>

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const char * AuthManager::auth_driver_name = "auth_exe";

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthRequest::add_auth(Operation             op,
                           const PoolObjectAuth& ob_perms,
                           string                ob_template)
{
    ostringstream oss;
    bool          auth;
    bool          lock;

    oss << ob_perms.type_to_str() << ":";

    if ( !ob_template.empty() )
    {
        string * encoded_id = one_util::base64_encode(ob_template);

        if (encoded_id != 0)
        {
            oss << *encoded_id << ":";
            delete encoded_id;
        }
        else
        {
            oss << "-:";
        }
    }
    else
    {
        oss << ob_perms.oid << ":";
    }

    oss << operation_to_str(static_cast<AuthRequest::Operation>(op & 0x0FLL)) << ":";

    oss << ob_perms.uid << ":";

    // -------------------------------------------------------------------------
    // Authorize the request for self authorization
    // -------------------------------------------------------------------------

    // Default conditions that grants permission :
    // User is oneadmin, or is in the oneadmin group
    Nebula&     nd   = Nebula::instance();
    AclManager* aclm = nd.get_aclm();

    if ( uid == 0 || gids.count( GroupPool::ONEADMIN_ID ) == 1 )
    {
        auth = aclm->oneadmin_authorize(ob_perms, op);
        lock = true;
    }
    else
    {
        auth = aclm->authorize(uid, gids, ob_perms, op);
        lock = false;
    }

    oss << auth; // Store the ACL authorization result in the request

    self_authorize = self_authorize && auth;

    auths.push_back(oss.str());

    if ( auth == false )
    {
        oss.str("");

        if ( !message.empty() )
        {
            oss << message << "; ";
        }

        if ( !lock )
        {
            oss << "Not authorized to perform " << operation_to_str(op)
                << " " << ob_perms.type_to_str();
        }
        else
        {
            oss << ob_perms.type_to_str() << " is locked.";
        }

        if ( ob_perms.oid != -1 )
        {
            oss << " [" << ob_perms.oid << "]";
        }

        message = oss.str();
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

extern "C" void * authm_action_loop(void *arg)
{
    AuthManager *  authm;

    if ( arg == 0 )
    {
        return 0;
    }

    authm = static_cast<AuthManager *>(arg);

    NebulaLog::log("AuM",Log::INFO,"Authorization Manager started.");

    authm->am.loop(authm->timer_period);

    NebulaLog::log("AuM",Log::INFO,"Authorization Manager stopped.");

    return 0;
}

/* -------------------------------------------------------------------------- */

int AuthManager::start()
{
    int               rc;
    pthread_attr_t    pattr;

    rc = MadManager::start();

    if ( rc != 0 )
    {
        return -1;
    }

    NebulaLog::log("AuM",Log::INFO,"Starting Auth Manager...");

    pthread_attr_init (&pattr);
    pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);

    rc = pthread_create(&authm_thread,&pattr,authm_action_loop,(void *) this);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthManager::user_action(const ActionRequest& ar)
{
    const AMAction& auth_ar = static_cast<const AMAction& >(ar);
    AuthRequest * request   = auth_ar.request();

    if ( request == 0 )
    {
        return;
    }

    switch(auth_ar.action())
    {
        case AMAction::AUTHENTICATE:
            authenticate_action(request);
        break;

        case AMAction::AUTHORIZE:
            authorize_action(request);
        break;
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthManager::authenticate_action(AuthRequest * ar)
{
    const AuthManagerDriver * authm_md;

    // ------------------------------------------------------------------------
    // Get the driver
    // ------------------------------------------------------------------------

    authm_md = get();

    if (authm_md == 0)
    {
        goto error_driver;
    }

    // ------------------------------------------------------------------------
    // Sanitize the login - remove leading and trailing spaces
    // ------------------------------------------------------------------------

    ar->username = regex_replace(ar->username, regex("^(%20|%09|%0A|%0D)+"), "");
    ar->username = regex_replace(ar->username, regex("(%20|%09|%0A|%0D)+$"), "");

    // ------------------------------------------------------------------------
    // Queue the request
    // ------------------------------------------------------------------------

    add_request(ar);

    // ------------------------------------------------------------------------
    // Make the request to the driver
    // ---- --------------------------------------------------------------------

    authm_md->authenticate(ar->id,
                           ar->uid,
                           ar->driver,
                           ar->username,
                           ar->password,
                           ar->session);
    return;

error_driver:
    ar->result  = false;
    ar->message = "Could not find Authorization driver";
    ar->notify();
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthManager::authorize_action(AuthRequest * ar)
{
    const AuthManagerDriver * authm_md;
    string auths;

    // ------------------------------------------------------------------------
    // Get the driver
    // ------------------------------------------------------------------------

    authm_md = get();

    if (authm_md == 0)
    {
        ar->message = "Could not find Authorization driver";
        goto error;
    }

    // ------------------------------------------------------------------------
    // Queue the request
    // ------------------------------------------------------------------------

    add_request(ar);

    // ------------------------------------------------------------------------
    // Make the request to the driver
    // ------------------------------------------------------------------------

    auths = ar->get_auths();

    if ( auths.empty() )
    {
        ar->message = "Empty authorization string";
        goto error;
    }

    authm_md->authorize(ar->id, ar->uid, auths, ar->self_authorize);

    return;

error:
    ar->result = false;
    ar->notify();

    return;
}

/* ************************************************************************** */
/* MAD Loading                                                                */
/* ************************************************************************** */

int AuthManager::load_mads(int uid)
{
    ostringstream                   oss;
    const VectorAttribute *         vattr = 0;
    int                             rc;
    string                          name;
    AuthManagerDriver *             authm_driver = 0;

    oss << "Loading Auth. Manager driver.";

    NebulaLog::log("AuM",Log::INFO,oss);

    if ( mad_conf.size() > 0 )
    {
        vattr = static_cast<const VectorAttribute *>(mad_conf[0]);
    }

    if ( vattr == 0 )
    {
        NebulaLog::log("AuM",Log::ERROR,"Failed to load Auth. Manager driver.");
        return -1;
    }

    VectorAttribute auth_conf("AUTH_MAD",vattr->value());

    auth_conf.replace("NAME",auth_driver_name);

    oss.str("");

    string authn = auth_conf.vector_value("AUTHN");

    if ( !authn.empty() )
    {
        oss << "--authn " << authn;
    }

    string authz = auth_conf.vector_value("AUTHZ");

    if ( !authz.empty() )
    {
        authz_enabled = true;
        oss << " --authz " << authz;
    }
    else
    {
        authz_enabled = false;
    }

    auth_conf.replace("ARGUMENTS", oss.str());

    authm_driver = new AuthManagerDriver(uid,auth_conf.value(),(uid!=0),this);

    rc = add(authm_driver);

    if ( rc == 0 )
    {
        oss.str("");
        oss << "\tAuth Manager loaded";

        NebulaLog::log("AuM",Log::INFO,oss);
    }

    return rc;
}
<commit_msg>Revert "B #4590: Santize login, remove whitespace (#4655)"<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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 "AuthManager.h"
#include "AuthRequest.h"
#include "AclManager.h"
#include "NebulaUtil.h"
#include "PoolObjectAuth.h"
#include "Nebula.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const char * AuthManager::auth_driver_name = "auth_exe";

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthRequest::add_auth(Operation             op,
                           const PoolObjectAuth& ob_perms,
                           string                ob_template)
{
    ostringstream oss;
    bool          auth;
    bool          lock;

    oss << ob_perms.type_to_str() << ":";

    if ( !ob_template.empty() )
    {
        string * encoded_id = one_util::base64_encode(ob_template);

        if (encoded_id != 0)
        {
            oss << *encoded_id << ":";
            delete encoded_id;
        }
        else
        {
            oss << "-:";
        }
    }
    else
    {
        oss << ob_perms.oid << ":";
    }

    oss << operation_to_str(static_cast<AuthRequest::Operation>(op & 0x0FLL)) << ":";

    oss << ob_perms.uid << ":";

    // -------------------------------------------------------------------------
    // Authorize the request for self authorization
    // -------------------------------------------------------------------------

    // Default conditions that grants permission :
    // User is oneadmin, or is in the oneadmin group
    Nebula&     nd   = Nebula::instance();
    AclManager* aclm = nd.get_aclm();

    if ( uid == 0 || gids.count( GroupPool::ONEADMIN_ID ) == 1 )
    {
        auth = aclm->oneadmin_authorize(ob_perms, op);
        lock = true;
    }
    else
    {
        auth = aclm->authorize(uid, gids, ob_perms, op);
        lock = false;
    }

    oss << auth; // Store the ACL authorization result in the request

    self_authorize = self_authorize && auth;

    auths.push_back(oss.str());

    if ( auth == false )
    {
        oss.str("");

        if ( !message.empty() )
        {
            oss << message << "; ";
        }

        if ( !lock )
        {
            oss << "Not authorized to perform " << operation_to_str(op)
                << " " << ob_perms.type_to_str();
        }
        else
        {
            oss << ob_perms.type_to_str() << " is locked.";
        }

        if ( ob_perms.oid != -1 )
        {
            oss << " [" << ob_perms.oid << "]";
        }

        message = oss.str();
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

extern "C" void * authm_action_loop(void *arg)
{
    AuthManager *  authm;

    if ( arg == 0 )
    {
        return 0;
    }

    authm = static_cast<AuthManager *>(arg);

    NebulaLog::log("AuM",Log::INFO,"Authorization Manager started.");

    authm->am.loop(authm->timer_period);

    NebulaLog::log("AuM",Log::INFO,"Authorization Manager stopped.");

    return 0;
}

/* -------------------------------------------------------------------------- */

int AuthManager::start()
{
    int               rc;
    pthread_attr_t    pattr;

    rc = MadManager::start();

    if ( rc != 0 )
    {
        return -1;
    }

    NebulaLog::log("AuM",Log::INFO,"Starting Auth Manager...");

    pthread_attr_init (&pattr);
    pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);

    rc = pthread_create(&authm_thread,&pattr,authm_action_loop,(void *) this);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthManager::user_action(const ActionRequest& ar)
{
    const AMAction& auth_ar = static_cast<const AMAction& >(ar);
    AuthRequest * request   = auth_ar.request();

    if ( request == 0 )
    {
        return;
    }

    switch(auth_ar.action())
    {
        case AMAction::AUTHENTICATE:
            authenticate_action(request);
        break;

        case AMAction::AUTHORIZE:
            authorize_action(request);
        break;
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthManager::authenticate_action(AuthRequest * ar)
{
    const AuthManagerDriver * authm_md;

    // ------------------------------------------------------------------------
    // Get the driver
    // ------------------------------------------------------------------------

    authm_md = get();

    if (authm_md == 0)
    {
        goto error_driver;
    }

    // ------------------------------------------------------------------------
    // Queue the request
    // ------------------------------------------------------------------------

    add_request(ar);

    // ------------------------------------------------------------------------
    // Make the request to the driver
    // ---- --------------------------------------------------------------------

    authm_md->authenticate(ar->id,
                           ar->uid,
                           ar->driver,
                           ar->username,
                           ar->password,
                           ar->session);
    return;

error_driver:
    ar->result  = false;
    ar->message = "Could not find Authorization driver";
    ar->notify();
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AuthManager::authorize_action(AuthRequest * ar)
{
    const AuthManagerDriver * authm_md;
    string auths;

    // ------------------------------------------------------------------------
    // Get the driver
    // ------------------------------------------------------------------------

    authm_md = get();

    if (authm_md == 0)
    {
        ar->message = "Could not find Authorization driver";
        goto error;
    }

    // ------------------------------------------------------------------------
    // Queue the request
    // ------------------------------------------------------------------------

    add_request(ar);

    // ------------------------------------------------------------------------
    // Make the request to the driver
    // ------------------------------------------------------------------------

    auths = ar->get_auths();

    if ( auths.empty() )
    {
        ar->message = "Empty authorization string";
        goto error;
    }

    authm_md->authorize(ar->id, ar->uid, auths, ar->self_authorize);

    return;

error:
    ar->result = false;
    ar->notify();

    return;
}

/* ************************************************************************** */
/* MAD Loading                                                                */
/* ************************************************************************** */

int AuthManager::load_mads(int uid)
{
    ostringstream                   oss;
    const VectorAttribute *         vattr = 0;
    int                             rc;
    string                          name;
    AuthManagerDriver *             authm_driver = 0;

    oss << "Loading Auth. Manager driver.";

    NebulaLog::log("AuM",Log::INFO,oss);

    if ( mad_conf.size() > 0 )
    {
        vattr = static_cast<const VectorAttribute *>(mad_conf[0]);
    }

    if ( vattr == 0 )
    {
        NebulaLog::log("AuM",Log::ERROR,"Failed to load Auth. Manager driver.");
        return -1;
    }

    VectorAttribute auth_conf("AUTH_MAD",vattr->value());

    auth_conf.replace("NAME",auth_driver_name);

    oss.str("");

    string authn = auth_conf.vector_value("AUTHN");

    if ( !authn.empty() )
    {
        oss << "--authn " << authn;
    }

    string authz = auth_conf.vector_value("AUTHZ");

    if ( !authz.empty() )
    {
        authz_enabled = true;
        oss << " --authz " << authz;
    }
    else
    {
        authz_enabled = false;
    }

    auth_conf.replace("ARGUMENTS", oss.str());

    authm_driver = new AuthManagerDriver(uid,auth_conf.value(),(uid!=0),this);

    rc = add(authm_driver);

    if ( rc == 0 )
    {
        oss.str("");
        oss << "\tAuth Manager loaded";

        NebulaLog::log("AuM",Log::INFO,oss);
    }

    return rc;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// bb_toposort_sccs LLVM sample. Demonstrates:
//
//
// Eli Bendersky (eliben@gmail.com)
// This code is in the public domain
//------------------------------------------------------------------------------
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"

using namespace llvm;

class TopoSorter {
public:
  void runToposort(const Function &F) {
    // Initialize the color map by marking all the vertices white.
    for (Function::const_iterator I = F.begin(), IE = F.end(); I != IE; ++I) {
      ColorMap[I] = TopoSorter::WHITE;
    }

    // The BB graph has a single entry vertex from which the other BBs should
    // be discoverable - the function entry block.
    recursiveDFSToposort(&F.getEntryBlock());
  }
private:
  enum Color {WHITE, GREY, BLACK};
  typedef DenseMap<const BasicBlock *, Color> BBColorMap;
  typedef SmallVector<const BasicBlock *, 32> BBVector;
  BBColorMap ColorMap;
  BBVector SortedBBs;

  void recursiveDFSToposort(const BasicBlock *BB) {
  }
};

class AnalyzeBBGraph : public FunctionPass {
public:
  AnalyzeBBGraph() : FunctionPass(ID) {}

  virtual bool runOnFunction(Function &F) {
    const BasicBlock &EntryBB = F.getEntryBlock();
    EntryBB.dump();
    return false;
  }

  // The address of this member is used to uniquely identify the class. This is
  // used by the LLVM's own RTTI mechanism.
  static char ID;
};

char AnalyzeBBGraph::ID = 0;

int main(int argc, char **argv) {
  if (argc < 2) {
    errs() << "Usage: " << argv[0] << " <IR file>\n";
    return 1;
  }

  // Parse the input LLVM IR file into a module.
  SMDiagnostic Err;
  Module *Mod = ParseIRFile(argv[1], Err, getGlobalContext());
  if (!Mod) {
    Err.print(argv[0], errs());
    return 1;
  }

  // Create a pass manager and fill it with the passes we want to run.
  PassManager PM;
  PM.add(new AnalyzeBBGraph());
  PM.run(*Mod);

  return 0;
}
<commit_msg>cosmetic<commit_after>//------------------------------------------------------------------------------
// bb_toposort_sccs LLVM sample. Demonstrates:
//
//
// Eli Bendersky (eliben@gmail.com)
// This code is in the public domain
//------------------------------------------------------------------------------
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"

using namespace llvm;

class TopoSorter {
public:
  void runToposort(const Function &F) {
    // Initialize the color map by marking all the vertices white.
    for (Function::const_iterator I = F.begin(), IE = F.end(); I != IE; ++I) {
      ColorMap[I] = TopoSorter::WHITE;
    }

    // The BB graph has a single entry vertex from which the other BBs should
    // be discoverable - the function entry block.
    recursiveDFSToposort(&F.getEntryBlock());
  }
private:
  enum Color {WHITE, GREY, BLACK};
  typedef DenseMap<const BasicBlock *, Color> BBColorMap;
  typedef SmallVector<const BasicBlock *, 32> BBVector;
  BBColorMap ColorMap;
  BBVector SortedBBs;

  void recursiveDFSToposort(const BasicBlock *BB) {

  }
};

class AnalyzeBBGraph : public FunctionPass {
public:
  AnalyzeBBGraph() : FunctionPass(ID) {}

  virtual bool runOnFunction(Function &F) {
    const BasicBlock &EntryBB = F.getEntryBlock();
    EntryBB.dump();
    return false;
  }

  // The address of this member is used to uniquely identify the class. This is
  // used by the LLVM's own RTTI mechanism.
  static char ID;
};

char AnalyzeBBGraph::ID = 0;

int main(int argc, char **argv) {
  if (argc < 2) {
    errs() << "Usage: " << argv[0] << " <IR file>\n";
    return 1;
  }

  // Parse the input LLVM IR file into a module.
  SMDiagnostic Err;
  Module *Mod = ParseIRFile(argv[1], Err, getGlobalContext());
  if (!Mod) {
    Err.print(argv[0], errs());
    return 1;
  }

  // Create a pass manager and fill it with the passes we want to run.
  PassManager PM;
  PM.add(new AnalyzeBBGraph());
  PM.run(*Mod);

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2016 The Bitcoin Core developers
// Copyright (c) 2021 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <bls/bls_wrapper.h>
#include <crypto/sha256.h>
#include <key.h>
#include <validation.h>
#include <random.h>

#include <boost/lexical_cast.hpp>

#include <memory>

static const int64_t DEFAULT_BENCH_EVALUATIONS = 5;
static const char* DEFAULT_BENCH_FILTER = ".*";
static const char* DEFAULT_BENCH_SCALING = "1.0";
static const char* DEFAULT_BENCH_PRINTER = "console";
static const char* DEFAULT_PLOT_PLOTLYURL = "https://cdn.plot.ly/plotly-latest.min.js";
static const int64_t DEFAULT_PLOT_WIDTH = 1024;
static const int64_t DEFAULT_PLOT_HEIGHT = 768;

void InitBLSTests();
void CleanupBLSTests();
void CleanupBLSDkgTests();

int main(int argc, char** argv)
{
    gArgs.ParseParameters(argc, argv);

    if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help")) {
        std::cout << HelpMessageGroup(_("Options:"))
                  << HelpMessageOpt("-?", _("Print this help message and exit"))
                  << HelpMessageOpt("-list", _("List benchmarks without executing them. Can be combined with -scaling and -filter"))
                  << HelpMessageOpt("-evals=<n>", strprintf(_("Number of measurement evaluations to perform. (default: %u)"), DEFAULT_BENCH_EVALUATIONS))
                  << HelpMessageOpt("-filter=<regex>", strprintf(_("Regular expression filter to select benchmark by name (default: %s)"), DEFAULT_BENCH_FILTER))
                  << HelpMessageOpt("-scaling=<n>", strprintf(_("Scaling factor for benchmark's runtime (default: %u)"), DEFAULT_BENCH_SCALING))
                  << HelpMessageOpt("-printer=(console|plot)", strprintf(_("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)"), DEFAULT_BENCH_PRINTER))
                  << HelpMessageOpt("-plot-plotlyurl=<uri>", strprintf(_("URL to use for plotly.js (default: %s)"), DEFAULT_PLOT_PLOTLYURL))
                  << HelpMessageOpt("-plot-width=<x>", strprintf(_("Plot width in pixel (default: %u)"), DEFAULT_PLOT_WIDTH))
                  << HelpMessageOpt("-plot-height=<x>", strprintf(_("Plot height in pixel (default: %u)"), DEFAULT_PLOT_HEIGHT));

        return 0;
    }

    RandomInit();
    ECC_Start();
    ECCVerifyHandle globalVerifyHandle;
    RandomInit();
    BLSInit();
    InitBLSTests();
    SetupEnvironment();
    g_logger->m_print_to_file = false; // don't want to write to debug.log file

    int64_t evaluations = gArgs.GetArg("-evals", DEFAULT_BENCH_EVALUATIONS);
    std::string regex_filter = gArgs.GetArg("-filter", DEFAULT_BENCH_FILTER);
    std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING);
    bool is_list_only = gArgs.GetBoolArg("-list", false);

    double scaling_factor = boost::lexical_cast<double>(scaling_str);

    std::unique_ptr<benchmark::Printer> printer(new benchmark::ConsolePrinter());
    std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER);
    if ("plot" == printer_arg) {
        printer.reset(new benchmark::PlotlyPrinter(
            gArgs.GetArg("-plot-plotlyurl", DEFAULT_PLOT_PLOTLYURL),
            gArgs.GetArg("-plot-width", DEFAULT_PLOT_WIDTH),
            gArgs.GetArg("-plot-height", DEFAULT_PLOT_HEIGHT)));
    }

    benchmark::BenchRunner::RunAll(*printer, evaluations, scaling_factor, regex_filter, is_list_only);

    // need to be called before global destructors kick in (PoolAllocator is needed due to many BLSSecretKeys)
    CleanupBLSDkgTests();
    CleanupBLSTests();

    ECC_Stop();
}
<commit_msg>bench: Use non-throwing ParseDouble()<commit_after>// Copyright (c) 2015-2016 The Bitcoin Core developers
// Copyright (c) 2021 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <bls/bls_wrapper.h>
#include <crypto/sha256.h>
#include <key.h>
#include <random.h>
#include <utilstrencodings.h>
#include <validation.h>

#include <memory>

static const int64_t DEFAULT_BENCH_EVALUATIONS = 5;
static const char* DEFAULT_BENCH_FILTER = ".*";
static const char* DEFAULT_BENCH_SCALING = "1.0";
static const char* DEFAULT_BENCH_PRINTER = "console";
static const char* DEFAULT_PLOT_PLOTLYURL = "https://cdn.plot.ly/plotly-latest.min.js";
static const int64_t DEFAULT_PLOT_WIDTH = 1024;
static const int64_t DEFAULT_PLOT_HEIGHT = 768;

void InitBLSTests();
void CleanupBLSTests();
void CleanupBLSDkgTests();

int main(int argc, char** argv)
{
    gArgs.ParseParameters(argc, argv);

    if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help")) {
        std::cout << HelpMessageGroup(_("Options:"))
                  << HelpMessageOpt("-?", _("Print this help message and exit"))
                  << HelpMessageOpt("-list", _("List benchmarks without executing them. Can be combined with -scaling and -filter"))
                  << HelpMessageOpt("-evals=<n>", strprintf(_("Number of measurement evaluations to perform. (default: %u)"), DEFAULT_BENCH_EVALUATIONS))
                  << HelpMessageOpt("-filter=<regex>", strprintf(_("Regular expression filter to select benchmark by name (default: %s)"), DEFAULT_BENCH_FILTER))
                  << HelpMessageOpt("-scaling=<n>", strprintf(_("Scaling factor for benchmark's runtime (default: %u)"), DEFAULT_BENCH_SCALING))
                  << HelpMessageOpt("-printer=(console|plot)", strprintf(_("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)"), DEFAULT_BENCH_PRINTER))
                  << HelpMessageOpt("-plot-plotlyurl=<uri>", strprintf(_("URL to use for plotly.js (default: %s)"), DEFAULT_PLOT_PLOTLYURL))
                  << HelpMessageOpt("-plot-width=<x>", strprintf(_("Plot width in pixel (default: %u)"), DEFAULT_PLOT_WIDTH))
                  << HelpMessageOpt("-plot-height=<x>", strprintf(_("Plot height in pixel (default: %u)"), DEFAULT_PLOT_HEIGHT));

        return 0;
    }

    RandomInit();
    ECC_Start();
    ECCVerifyHandle globalVerifyHandle;
    RandomInit();
    BLSInit();
    InitBLSTests();
    SetupEnvironment();
    g_logger->m_print_to_file = false; // don't want to write to debug.log file

    int64_t evaluations = gArgs.GetArg("-evals", DEFAULT_BENCH_EVALUATIONS);
    std::string regex_filter = gArgs.GetArg("-filter", DEFAULT_BENCH_FILTER);
    std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING);
    bool is_list_only = gArgs.GetBoolArg("-list", false);

    double scaling_factor;
    if (!ParseDouble(scaling_str, &scaling_factor)) {
        fprintf(stderr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str());
        return EXIT_FAILURE;
    }

    std::unique_ptr<benchmark::Printer> printer(new benchmark::ConsolePrinter());
    std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER);
    if ("plot" == printer_arg) {
        printer.reset(new benchmark::PlotlyPrinter(
            gArgs.GetArg("-plot-plotlyurl", DEFAULT_PLOT_PLOTLYURL),
            gArgs.GetArg("-plot-width", DEFAULT_PLOT_WIDTH),
            gArgs.GetArg("-plot-height", DEFAULT_PLOT_HEIGHT)));
    }

    benchmark::BenchRunner::RunAll(*printer, evaluations, scaling_factor, regex_filter, is_list_only);

    // need to be called before global destructors kick in (PoolAllocator is needed due to many BLSSecretKeys)
    CleanupBLSDkgTests();
    CleanupBLSTests();

    ECC_Stop();
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench.h"

#include "chainparams.h"
#include "validation.h"
#include "streams.h"
#include "consensus/validation.h"

namespace block_bench {
#include "bench/data/block413567.raw.h"
} // namespace block_bench

// These are the two major time-sinks which happen after we have fully received
// a block off the wire, but before we can relay the block on to peers using
// compact block relay.

static void DeserializeBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::block413567,
            (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a = '\0';
    stream.write(&a, 1); // Prevent compaction

    while (state.KeepRunning()) {
        CBlock block;
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::block413567)));
    }
}

static void DeserializeAndCheckBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::block413567,
            (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a = '\0';
    stream.write(&a, 1); // Prevent compaction

    const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);

    while (state.KeepRunning()) {
        CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::block413567)));

        CValidationState validationState;
        assert(CheckBlock(block, validationState, chainParams->GetConsensus()));
    }
}

BENCHMARK(DeserializeBlockTest);
BENCHMARK(DeserializeAndCheckBlockTest);
<commit_msg>Update block bench header<commit_after>// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench.h"

#include "chainparams.h"
#include "validation.h"
#include "streams.h"
#include "consensus/validation.h"

namespace block_bench {
#include "bench/data/blockbench.raw.h"
} // namespace block_bench

// These are the two major time-sinks which happen after we have fully received
// a block off the wire, but before we can relay the block on to peers using
// compact block relay.

static void DeserializeBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::blockbench,
            (const char*)&block_bench::blockbench[sizeof(block_bench::blockbench)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a = '\0';
    stream.write(&a, 1); // Prevent compaction

    while (state.KeepRunning()) {
        CBlock block;
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::blockbench)));
    }
}

static void DeserializeAndCheckBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::blockbench,
            (const char*)&block_bench::blockbench[sizeof(block_bench::blockbench)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a = '\0';
    stream.write(&a, 1); // Prevent compaction

    const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);

    while (state.KeepRunning()) {
        CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::blockbench)));

        CValidationState validationState;
        assert(CheckBlock(block, validationState, chainParams->GetConsensus()));
    }
}

BENCHMARK(DeserializeBlockTest);
BENCHMARK(DeserializeAndCheckBlockTest);
<|endoftext|>