Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JGF reader support #521

Merged
merged 11 commits into from
Oct 9, 2019
101 changes: 101 additions & 0 deletions resource/readers/resource_reader_base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*****************************************************************************\
* Copyright (c) 2019 Lawrence Livermore National Security, LLC. Produced at
* the Lawrence Livermore National Laboratory (cf, AUTHORS, DISCLAIMER.LLNS).
* LLNL-CODE-658032 All rights reserved.
*
* This file is part of the Flux resource manager framework.
* For details, see https://github.com/flux-framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the license, or (at your option)
* any later version.
*
* Flux is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the terms and conditions of the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
* See also: http://www.gnu.org/licenses/
\*****************************************************************************/

#include "resource/readers/resource_reader_base.hpp"
#include "resource/store/resource_graph_store.hpp"

extern "C" {
#if HAVE_CONFIG_H
#include "config.h"
#endif
}

using namespace std;
using namespace Flux::resource_model;


/********************************************************************************
* *
* Private Base Reader API *
* *
********************************************************************************/

bool resource_reader_base_t::in_whitelist (const std::string &resource)
{
return whitelist.empty ()
|| (whitelist.find (resource) != whitelist.end ());
}


/********************************************************************************
* *
* Public Base Reader API *
* *
********************************************************************************/

int resource_reader_base_t::set_whitelist (const std::string &csl)
{
if (csl == "")
return 0;

int rc = -1;
size_t pos = 0;
std::string csl_copy = csl;
std::string sep = ",";

try {
while ((pos = csl_copy.find (sep)) != std::string::npos) {
std::string resource = csl_copy.substr (0, pos);
if (resource != "")
whitelist.insert (resource);
csl_copy.erase (0, pos + sep.length ());
}
if (csl_copy != "")
whitelist.insert (csl_copy);
errno = EINVAL;
rc = whitelist.empty ()? -1 : 0;
} catch (std::out_of_range &e) {
errno = EINVAL;
rc = -1;
} catch (std::bad_alloc &e) {
errno = ENOMEM;
rc = -1;
}

return rc;
}

const std::string &resource_reader_base_t::err_message () const
{
return m_err_msg;
}

void resource_reader_base_t::clear_err_message ()
{
m_err_msg = "";
}

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/
102 changes: 102 additions & 0 deletions resource/readers/resource_reader_base.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*****************************************************************************\
* Copyright (c) 2019 Lawrence Livermore National Security, LLC. Produced at
* the Lawrence Livermore National Laboratory (cf, AUTHORS, DISCLAIMER.LLNS).
* LLNL-CODE-658032 All rights reserved.
*
* This file is part of the Flux resource manager framework.
* For details, see https://github.com/flux-framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the license, or (at your option)
* any later version.
*
* Flux is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the terms and conditions of the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
* See also: http://www.gnu.org/licenses/
\*****************************************************************************/

#ifndef RESOURCE_READER_BASE_HPP
#define RESOURCE_READER_BASE_HPP

#include <set>
#include <string>
#include <cerrno>
#include "resource/schema/resource_graph.hpp"
#include "resource/store/resource_graph_store.hpp"

namespace Flux {
namespace resource_model {


/*! Base resource reader class.
*/
class resource_reader_base_t {
public:
/*! Unpack str into a resource graph.
*
* \param g resource graph
* \param m resource graph meta data
* \param str resource set string
* \param rank assign rank to all of the newly created resource vertices
* \return 0 on success; non-zero integer on an error
*/
virtual int unpack (resource_graph_t &g, resource_graph_metadata_t &m,
const std::string &str, int rank = -1) = 0;

/*! Unpack str into a resource graph and graft
* the top-level vertices to vtx.
*
* \param g resource graph
* \param m resource graph meta data
* \param vtx parent vtx at which to graft the deserialized graph
* \param str resource set string
* \param rank assign rank to all of the newly created resource vertices
* \return 0 on success; non-zero integer on an error
*/
virtual int unpack_at (resource_graph_t &g, resource_graph_metadata_t &m,
vtx_t &vtx, const std::string &str, int rank = -1) = 0;
Comment on lines +53 to +64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

param vtx will have edges to and/or from each of the subsystem roots of the unpacked resource graph, correct? Also, is vtx in the original graph but not in the unpacked graph?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@milroy: great question. Easy one first:

Also, is vtx in the original graph but not in the unpacked graph?

Yes, it is a vertex that should only be in the original graph. This interface is currently only wired with the hwloc reader to attach a new set of subgraph created by each of the ranked hwloc xml objects into the root vertex: the cluster vertex.

param vtx will have edges to and/or from each of the subsystem roots of the unpacked resource graph, correct?

The intent is broader than this.

Say, the unpacked graph is node10->core0. While node10 is the root of the subgraph, it is not the root of the overall graph. I detect the root of the subgraph by parsing each vertex's paths field. If node10 vertex's paths has containment: /cluster/node10, it won't be identified as the root of the containment subsystem.

Also if the unpacked graph is node10->core0, node20->core30, I expect that this interface attach both node10 and node20 to the vtx. (We don't currently have this use case as hwloc reader reads one rank at a time.) If this were to work, it is almost like the caller should specify what those vertices are, which need to be attached to vtx. ..

If you want to propose something more general than this interface, which can help your work, maybe we can work on an interface revision after this PR lands?

Copy link
Member

@milroy milroy Oct 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface is currently only wired with the hwloc reader to attach a new set of subgraph created by each of the ranked hwloc xml objects into the root vertex: the cluster vertex.

But the intention is that eventually vtx can be any vertex in the original graph?

While node10 is the root of the subgraph, it is not the root of the overall graph. I detect the root of the subgraph by parsing each vertex's paths field.

That's sensible. I was abusing the term "subsystem roots" as referring to the top-level node(s) in the unpacked graph (the subgraph). Can the subgraph have multiple roots (i.e. the subgraph contains vertices in multiple subsystems)?

Also if the unpacked graph is node10->core0, node20->core30, I expect that this interface attach both node10 and node20 to the vtx. (We don't currently have this use case as hwloc reader reads one rank at a time.) If this were to work, it is almost like the caller should specify what those vertices are, which need to be attached to vtx. ..

This is my main curiosity. The path to vertex mapping is many-to-one since each vertex can have a path per subsystem: g[v].paths[subsys] = prefix + "/" + g[v].name;. This suggests to me that node10 could be attached to one vtx from each subsys where g[node10].paths[subsys] is defined.

If you want to propose something more general than this interface, which can help your work, maybe we can work on an interface revision after this PR lands?

Yes, I think we will need a more general interface which accepts a node to vertex map. I agree, that work is out of scope for this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we will need a more general interface which accepts a node to vertex map. I agree, that work is out of scope for this PR.

Do you want to track the idea with a new issue?


/*! Set the whitelist: only resources that are part of this whitelist
* will be unpacked into the graph.
*
* \param csl comma separated whitelist string
* \return 0 on success; non-zero integer on an error
*/
int set_whitelist (const std::string &csl);

/*! Is the selected reader format support whitelist
*
* \return true when supported
*/
virtual bool is_whitelist_supported () = 0;

/*! Return the error message string.
*/
const std::string &err_message () const;

/*! Clear the error message string.
*/
void clear_err_message ();

protected:
bool in_whitelist (const std::string &resource);
std::set<std::string> whitelist;
std::string m_err_msg = "";
};

} // namesapce resource_model
} // namespace Flux


#endif // RESOURCE_READER_BASE_HPP

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/
52 changes: 52 additions & 0 deletions resource/store/resource_graph_store.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*****************************************************************************\
* Copyright (c) 2019 Lawrence Livermore National Security, LLC. Produced at
* the Lawrence Livermore National Laboratory (cf, AUTHORS, DISCLAIMER.LLNS).
* LLNL-CODE-658032 All rights reserved.
*
* This file is part of the Flux resource manager framework.
* For details, see https://github.com/flux-framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the license, or (at your option)
* any later version.
*
* Flux is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the terms and conditions of the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
* See also: http://www.gnu.org/licenses/
\*****************************************************************************/

#include "resource/store/resource_graph_store.hpp"
#include "resource/readers/resource_reader_base.hpp"

using namespace Flux;
using namespace Flux::resource_model;

bool resource_graph_db_t::known_subsystem (const std::string &s)
{
return (metadata.roots.find (s) != metadata.roots.end ())? true : false;
}

int resource_graph_db_t::load (const std::string &str,
std::shared_ptr<resource_reader_base_t> &reader,
int rank)
{
return reader->unpack (resource_graph, metadata, str, rank);
};

int resource_graph_db_t::load (const std::string &str,
std::shared_ptr<resource_reader_base_t> &reader,
vtx_t &vtx_at, int rank)
{
return reader->unpack_at (resource_graph, metadata, vtx_at, str, rank);
};

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/
97 changes: 97 additions & 0 deletions resource/store/resource_graph_store.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*****************************************************************************\
* Copyright (c) 2019 Lawrence Livermore National Security, LLC. Produced at
* the Lawrence Livermore National Laboratory (cf, AUTHORS, DISCLAIMER.LLNS).
* LLNL-CODE-658032 All rights reserved.
*
* This file is part of the Flux resource manager framework.
* For details, see https://github.com/flux-framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the license, or (at your option)
* any later version.
*
* Flux is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the terms and conditions of the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
* See also: http://www.gnu.org/licenses/
\*****************************************************************************/

#ifndef RESOURCE_GRAPH_STORE_HPP
#define RESOURCE_GRAPH_STORE_HPP

#include <string>
#include <memory>
#include "resource/schema/resource_graph.hpp"

namespace Flux {
namespace resource_model {

class resource_reader_base_t;

/*! Resource graph data metadata.
* Adjacency_list graph, roots of this graph and various indexing.
*/
struct resource_graph_metadata_t {
std::map<subsystem_t, vtx_t> roots;
std::map<std::string, std::vector <vtx_t>> by_type;
std::map<std::string, std::vector <vtx_t>> by_name;
std::map<std::string, std::vector <vtx_t>> by_path;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by_path eventually should be changed to std::map<std::string, vtx_t> or the like (see issue #518). That's beyond the scope of this PR, but I'm noting it here for future reference. I'll try to address it in my upcoming PR based on issue #511.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed! The changes like this are now lumped into either hardening and/or optimization project in my kanban board.

};

/*! Resource graph data store.
* Adjacency_list graph, roots of this graph and various indexing.
*/
struct resource_graph_db_t {
resource_graph_t resource_graph;
resource_graph_metadata_t metadata;

/*! Return true if s is known subsystem
*/
bool known_subsystem (const std::string &s);

/*! Load str into the resource graph
*
* \param str string containing a GRUG specification
* \param reader resource reader base class object
* \param rank assign this rank to all the newly created resource vertices
* \return 0 on success; non-zero integer on an error
* ENOMEM: out of memory
* EINVAL: invalid input or operation (e.g.
* hwloc version or json string load error)
* EPROTO: str violates the schema
*/
int load (const std::string &str,
std::shared_ptr<resource_reader_base_t> &reader,
int rank = -1);

/*! Load str into the resource graph and graft the top-level
* vertices to vtx_at.
* \param str string containing a GRUG specification
* \param reader resource reader base class object
* \param vtx_at parent vtx at which to graft the deserialized graph
* \param rank assign this rank to all the newly created resource vertices
* \return 0 on success; non-zero integer on an error
* ENOMEM: out of memory
* EINVAL: invalid input or operation (e.g.
* hwloc version or json string load error)
* EPROTO: str violates the schema
*/
int load (const std::string &str,
std::shared_ptr<resource_reader_base_t> &reader,
vtx_t &vtx_at, int rank = -1);
};

}
}

#endif // RESOURCE_GRAPH_STORE_HPP

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/