diff --git a/.github/workflows/latex.yml b/.github/workflows/latex.yml index 44ee443..88bb25e 100644 --- a/.github/workflows/latex.yml +++ b/.github/workflows/latex.yml @@ -16,7 +16,7 @@ jobs: submodules: recursive - name: Compile LaTeX document - uses: xu-cheng/latex-action@v3 + uses: xu-cheng/latex-action@v4 with: root_file: | D3126_Overview.tex diff --git a/D3126_Overview/tex/config.tex b/D3126_Overview/tex/config.tex index b59b07f..c3ab099 100644 --- a/D3126_Overview/tex/config.tex +++ b/D3126_Overview/tex/config.tex @@ -14,3 +14,18 @@ %% Library chapters %% \newcommand{\firstlibchapter}{language.support} %% \newcommand{\lastlibchapter}{thread} + +%% Example: Override default authors for this paper +%% \renewcommand{\paperauthors}{ +%% &Custom Author (Special Institution)\\ +%% &\href{mailto:custom@example.com}{\nolinkurl{custom@example.com}}\\ +%% &Another Author\\ +%% &\href{mailto:another@example.com}{\nolinkurl{another@example.com}}\\ +%% } + +%% Example: Add to default contributors for this paper +%% \renewcommand{\papercontributors}{% +%% \defaultcontributors\\ +%% &Special Contributor for Overview Paper\\ +%% &Additional Expert% +%% } diff --git a/D3126_Overview/tex/overview.tex b/D3126_Overview/tex/overview.tex index f12633d..d5596ed 100644 --- a/D3126_Overview/tex/overview.tex +++ b/D3126_Overview/tex/overview.tex @@ -35,9 +35,8 @@ \section{Overview} \section{Goals and Priorities} The main goal of this library is to provide a self-consistent and systematic library of software components for -graph computations, based on well-defined graph representations. it includes generic -algorithms, named requirements, views, and utilities. -views. +graph computations, based on well-defined graph representations. It includes generic +algorithms, named requirements, views, and utilities. % It is informed by the authors' past experience with the Boost Graph Library (BGL), the NWGraph library, the C++ GraphBLAS, and the library proposed in P1709. The proposed library seeks to leverage the existing Standard @@ -168,7 +167,7 @@ \section{What this proposal is \textbf{not}} \section{Impact on the Standard} This proposal is a pure \textbf{library} extension. -\section{Interaction wtih Other Papers} +\section{Interaction with Other Papers} The entirety of our proposal for graph algorithms and data structures comprises multiple companion papers: D3127 (Terminology), D3128 (Algorithms), D3129 (Views), D3130 (Container Interface), D3131 (Containers), D9903 (Operators), and D9907 (Adaptors). Other than these papers, there are no interactions with other proposals to the standard. @@ -190,7 +189,7 @@ \section{Prior Art} \textbf{boost::graph} has been an important C++ graph implementation since 2001. It was developed with the goal of providing a modern (at the time) generic library that addressed all the needs of a graph library user. It is still a viable library used today, attesting to the value it brings. -However, boost::graph was written using C++98 in an ``expert-friendly'' style, adding many abstractions and using sophisticated tempate metaprogramming, making it difficult to use by a casual developer. Particular pain-points described in ad-hoc discussions with users include: property maps, parameter-passing, visitors. +However, boost::graph was written using C++98 in an ``expert-friendly'' style, adding many abstractions and using sophisticated template metaprogramming, making it difficult to use by a casual developer. Particular pain-points described in ad-hoc discussions with users include: property maps, parameter-passing, visitors. \medskip @@ -199,7 +198,7 @@ \section{Prior Art} that was more accessible to the average developer. % with the latest algorithms. While NWGraph made important strides to introduce the idea of an adjacency list as a range-of-ranges and implemented many important algorithms, -there are some areas it didn't address that come a practical use in the field. For instance, it didn't have a well-defined API for graph +there are some areas it didn't address that are of practical use in the field. For instance, it didn't have a well-defined API for graph data structures that could be applied to existing graphs, and there wasn't a uniform approach to properties. This proposal takes the best of NWGraph, with previous work done for P1709 to define a Graph Container Interface, to provide a library that @@ -271,7 +270,7 @@ \section{Namespaces} \item[]\tcode{std::ranges/graph}, \tcode{std::ranges::graph::views} and \tcode{std::ranges::graph::edgelist} \end{itemize} The advantage of these two options are that there would be no requirement to use the ranges:: prefix for things -in the std::ranges namespace, a common occurance. +in the std::ranges namespace, a common occurrence. \section{Notes and Considerations} There are some interesting observations that can be made about graphs and how they compare and contrast to the @@ -298,7 +297,7 @@ \section{Notes and Considerations} \end{itemize} The addition of concepts to the standard library is a serious consideration because, once added, they cannot -be removed. We believe that adjacency lists as a range-of-ranges merits the addition new concepts but we recognize that it +be removed. We believe that adjacency lists as a range-of-ranges merits the addition of new concepts but we recognize that it may be a controversial decision. Toward that end, we will continue to include them to help clarify the examples given and are assumed to be "For exposition only" as suggested implementation until a clear decision to include them, or not, is made. diff --git a/D3127_Terminology/tex/terminology_0.tex b/D3127_Terminology/tex/terminology_0.tex index 1e275f1..2d8bb73 100644 --- a/D3127_Terminology/tex/terminology_0.tex +++ b/D3127_Terminology/tex/terminology_0.tex @@ -85,7 +85,7 @@ \subsection{Graph Representation: Enumerating the Vertices} We summarize some remaining terminology about vertices and edges. \begin{itemize} \item -An edge $e_k$ may be \emph{directed}, denoted as the ordered pair $e_k=(v_i, v_j)$, or it may be +An edge $e_k$ may be \emph{directed}, denoted as the ordered pair $e_k=(v_i, v_j)$, or it may be \emph{undirected}, denoted as the (unordered) set $e_k=\{v_i, v_j\}$. The edges in $E$ are either all directed or all undirected, corresponding respectively to a \emph{directed graph} or to an \emph{undirected} graph. @@ -390,7 +390,7 @@ \section{Bipartite Graphs} % Thus, a graph, as we have defined it, cannot model the IMDB. -There is a small generalization we can make to the definition of graph that will result in a suitable abstraction for modeling the IMDB. In particular, we need one set of vertices corresponding to actors, another set of vertices corresponding to movies, and then a set of edges corresponding to the relationships between actors and movies. There are two kinds of relationships to consider actors in movies or movies starring actors. To be well-defined, the edge set may only contain one kind of relationship. To capture this kind of model, we define a \emph{structurally bipartite graph} $H = \{ U, V, E \}$, where vertex sets $U$ and $V$ are enumerated $U = \{ u_0, u_1, \ldots , u_{n0} \}$ and $V = \{ v_0, v_1, \ldots v_{n1}\}$, +There is a small generalization we can make to the definition of graph that will result in a suitable abstraction for modeling the IMDB. In particular, we need one set of vertices corresponding to actors, another set of vertices corresponding to movies, and then a set of edges corresponding to the relationships between actors and movies. There are two kinds of relationships to consider: actors in movies or movies starring actors. To be well-defined, the edge set may only contain one kind of relationship. To capture this kind of model, we define a \emph{structurally bipartite graph} $H = \{ U, V, E \}$, where vertex sets $U$ and $V$ are enumerated $U = \{ u_0, u_1, \ldots , u_{n0} \}$ and $V = \{ v_0, v_1, \ldots v_{n1}\}$, and the edge set $E$ consists of pairs $(u_i, v_j)$ where $u_i$ is in $U$ and $v_j$ is in $V$. The \emph{adjacency matrix representation of a structurally bipartite graph} is @@ -404,7 +404,7 @@ \section{Bipartite Graphs} \end{array} \right. \] -From this adjacency matrix representation we can readily construct coordinate and compressed sparse representations. The only structural difference between the representations of a structurally bipartite graph and that of a unipartite graph is that of vertex cardinality. That is, in a unipartite graph, edges map from $V$ to $V$, and hence the values in the left hand column and in the right hand column of a coordinate representation would be in the same range: $[0, |V|)$. However, for a structurally bipartite graph, this is no longer the case. Although the coordinate representation still consists of pairs of vertex indices, the range of values in the left hand column is $[0, |U|)$, while in the right hand column it is $[0, |V|)$. Similarly, the compressed representation will have $|U|$ entries, but the values stored in each entry may range from $[0, |V|)$. We note that these are constraints on values, not on structure. +From this adjacency matrix representation we can readily construct coordinate and compressed sparse representations. The only structural difference between the representations of a structurally bipartite graph and that of a unipartite graph is that of vertex cardinality. That is, in a unipartite graph, edges map from $V$ to $V$, and hence the values in the left hand column and in the right hand column of a coordinate representation would be in the same range: $[0, |V|)$. However, for a structurally bipartite graph, this is no longer the case. Although the coordinate representation still consists of pairs of vertex indices, the range of values in the left hand column is $[0, |U|)$, while in the right hand column it is $[0, |V|)$. Similarly, the compressed representation will have $|U|$ entries, but the values stored in each entry may range from $[0, |V|)$. We note that these are constraints on values, not on structure. \begin{figure}[ht] @@ -474,9 +474,9 @@ \section{Partitioned Graphs} % These are definitely already covered in the examples above. % \subsection{From Edge List to Adjacency List} -% \andrew{Scan edge list and insert edgest into adjacency list. Adjacency list must support insertion.} +% \andrew{Scan edge list and insert edges into adjacency list. Adjacency list must support insertion.} % \subsection{Edge List and Adjacency List: Compressed Edge List} -% \andrew{Using a sort and group-by (or a sort, a run-length encoding, and a scan), we can compactify the edge-list reprentation and at the same time obtain an adjacency-list representation -- one that is memory and compute efficient. Best of both worlds. Has same basic structural principles as CSR / CSC matrices in linear algebra -- but much more general.} +% \andrew{Using a sort and group-by (or a sort, a run-length encoding, and a scan), we can compactify the edge-list representation and at the same time obtain an adjacency-list representation -- one that is memory and compute efficient. Best of both worlds. Has same basic structural principles as CSR / CSC matrices in linear algebra -- but much more general.} \section{Regarding Algorithms} @@ -599,7 +599,7 @@ \section{Graphs and Sparse Matrices} A sparse matrix can be considered as a structurally bipartite graph representation. Suppose that we have a sparse matrix $A$ represented as $\{(i, j, a_{ij})\}$. We can create a structurally bipartite $J = \{U, V, E\}$ such that $(i,j)$ is in $E$ if and only if $\{(i, j, a_{ij})\}$ is in $A$. The coordinate and compressed representations for a sparse matrix are the same as for the graph (and, in fact, the terminology ``coordinate'' and ``compressed sparse'' originate in sparse numerical linear algebra). For a matrix, the sets $U$ and $V$ have a particular meaning. Either the indices of $U$ consist of row numbers and $V$ of column numbers, or vice versa. In the former case, a compressed representation is known as ``compressed sparse row.'' In the latter case, it is known as ``compressed sparse column.'' \andrew{This code is from nwgraph, need to bring it up to std::graph} -The following code snippet illustrates a sparse matrix vector product when a compressed adjacency representation is interpreted as a compressed sparse row matrix. +The following code snippet illustrates a sparse matrix vector product when a compressed adjacency representation is interpreted as a compressed sparse row matrix. \begin{lstlisting}[language=C++] for (auto&& [row, u_neighbors] : make_neighbor_range(graph)) { for (auto&& [col, val] : u_neighbors) { diff --git a/D3128_Algorithms/tex/algorithms.tex b/D3128_Algorithms/tex/algorithms.tex index 784a7c1..e1f0d50 100644 --- a/D3128_Algorithms/tex/algorithms.tex +++ b/D3128_Algorithms/tex/algorithms.tex @@ -76,7 +76,7 @@ \subsection{Other Algorithms} Additional algorithms that were considered but not included in this proposal are shown in Table \ref{tab:other_algorithms}. Tier X algorithms are variations of shortest paths algorithms that complement the Single Source, Multiple Target algorithms in this proposal. -It is assumed that future proposals will include them, thought the exact mix for each proposal will depend on feedback received +It is assumed that future proposals will include them, though the exact mix for each proposal will depend on feedback received and our experience with the current proposal. \phil{We may want to revisit the Driver idea in the future after we have more algorithms.} @@ -114,7 +114,7 @@ \subsection{Other Algorithms} \end{center} \end{table} -\andrew{All Pairs: Tier 2? People bring this up alot -- but it is very expensive in terms of computation and memory.} +\andrew{All Pairs: Tier 2? People bring this up a lot -- but it is very expensive in terms of computation and memory.} \phil{If it's useful to enough people it should be included. Users can make their own determination of whether they want to use it, based on the cost.} \phil{The same variations for Shortest Paths algorithms can also be useful for topological sort.} @@ -510,7 +510,7 @@ \subsection{Initialization} \begin{itemize} \item \lstinline{shortest_path_infinite_distance()} returns the largest distance value, typically \lstinline{numeric_limits::max()} for numeric types. - \item \lstinline{shortest_path_zero()} returns a value for for a zero-length path, + \item \lstinline{shortest_path_zero()} returns a value for a zero-length path, typically \lstinline{0} for numeric types. \end{itemize} \end{itemdescr} @@ -762,7 +762,7 @@ \subsubsection{Bellman-Ford Shortest Paths} %\pnum\result \pnum\returns \begin{itemize} - \item \lstinline{optional} If no negative weight cycle is found, + \item \lstinline{optional>} If no negative weight cycle is found, there is no associated vertex id. If a negative weight cycle is found, a vertex id in the cycle is returned. \lstinline{find_negative_cycle} can be called to get the vertex ids of the cycle. @@ -824,10 +824,10 @@ \subsubsection{Bellman-Ford Shortest Distances} %\pnum\result \pnum\returns \begin{itemize} - \item \lstinline{optional} If no negative weight cycle is found, + \item \lstinline{optional>} If no negative weight cycle is found, there is no associated vertex id. If a negative weight cycle is found, a vertex id in the cycle is returned. \lstinline{bellman_ford_shortest_paths} must be used - to get the predecessors if it is importantant to get the vertex ids of the cycle + to get the predecessors if it is important to get the vertex ids of the cycle using \lstinline{find_negative_cycle}. \end{itemize} \pnum\complexity $\mathcal{O}(|E| \cdot |V|)$. Complexity may also be affected when visitor events are called. \\ @@ -1162,7 +1162,7 @@ \subsection{Connected Components} \item \lstinline{component[v]} is the connected component id of vertex \lstinline{v}. \item - There is at least one Connected Component, with compondent id of \lstinline{0}, for \lstinline{num_vertices(g) > 0}. + There is at least one Connected Component, with component id of \lstinline{0}, for \lstinline{num_vertices(g) > 0}. \end{itemize} %\pnum\result %\pnum\returns @@ -1497,7 +1497,7 @@ \subsection{Prim Minimum Spanning Tree} \item \lstinline{size(weight) >= to num_vertices(g)}. \item - \lstinline{size(predecessor >= to num_vertices(g)}. + \lstinline{size(predecessor) >= num_vertices(g)}. \end{itemize} \pnum\effects \begin{itemize} diff --git a/D3129_Views/tex/revision.tex b/D3129_Views/tex/revision.tex index 5d1f3ab..9107ddf 100644 --- a/D3129_Views/tex/revision.tex +++ b/D3129_Views/tex/revision.tex @@ -13,7 +13,7 @@ \subsection*{\paperno r1} The range returned by \tcode{edgelist_view} adheres to the \tcode{basic_sourced_index_edgelist} concept, and to the \tcode{has_edge_value} concept if a \tcode{evf(uv)} function is passed. The same applies to all \textit{sourced} versions of the BFS, DFS and Topological Sort views. - \item Restore the allocator parameters on the DFS, BFS and Toplogical Sort views, based on feedback and + \item Restore the allocator parameters on the DFS, BFS and Topological Sort views, based on feedback and by SG14/SG19 joint meeting. \item Add a note that we will be unable to support a freestanding graph library in this proposal because of the need for \tcode{stack}, \tcode{queue} and potential \tcode{bad_alloc} exception in many of diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index d4125d1..d1ba556 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -24,7 +24,7 @@ \section{Introduction} % The views in this paper provide common ways that algorithms use to traverse graphs. They are a simple as iterating -through the set of vertices, or more complex ways such as depth-first search and breadth-first search. The also +through the set of vertices, or more complex ways such as depth-first search and breadth-first search. They also provide a consistent and reliable way to access related elements using the View Return Types, and guaranteeing expected values, such as that the target is really the target on unordered edges. @@ -87,7 +87,7 @@ \subsection{\tcode{struct vertex_info}}\label{vertex-view}\mbox{} \\ \lstinputlisting{D3129_Views/src/vertex_info.hpp} } -Specializations are defined with \tcode{V=void} or \tcode{VV=void} to suppress the existance of their associated member variables, +Specializations are defined with \tcode{V=void} or \tcode{VV=void} to suppress the existence of their associated member variables, giving the following valid combinations in Table \ref{tab:vertex-view} . For instance, the second entry, \tcode{vertex_info} has one member \tcode{\{vertex_type vertex;\}} and \tcode{value_type} is \tcode{void}. \begin{table}[h!] @@ -123,7 +123,7 @@ \subsection{\tcode{struct edge_info}}\label{edge-view}\mbox \lstinputlisting{D3129_Views/src/edge_info.hpp} } -Specializations are defined with \tcode{Sourced=true|false}, \tcode{E=void} or \tcode{EV=void} to suppress the existance of the associated +Specializations are defined with \tcode{Sourced=true|false}, \tcode{E=void} or \tcode{EV=void} to suppress the existence of the associated member variables, giving the following valid combinations in Table \ref{tab:edge-view} . For instance, the second entry, \tcode{edge_info} has three members \tcode{\{source_id_type source_id; target_id_type target_id; edge_type edge;\}} and \tcode{value_type} is \tcode{void}. @@ -161,7 +161,7 @@ \subsection{\tcode{struct neighbor_info}}\label{neighbor-vi \lstinputlisting{D3129_Views/src/neighbor_info.hpp} } -Specializations are defined with \tcode{Sourced=true|false} or \tcode{EV}=void to suppress the existance of the +Specializations are defined with \tcode{Sourced=true|false} or \tcode{EV}=void to suppress the existence of the associated member variables, giving the following valid combinations in Table \ref{tab:neighbor-view} . For instance, the second entry, \tcode{neighbor_info} has two members \tcode{\{source_type source; target_type target;\}} and \tcode{value_type} is \tcode{void}. @@ -363,7 +363,7 @@ \subsection{Common Types and Functions for ``Search'' } }; // stop searching from current vertex -template void cancel(S search, cancel_search); // Returns distance from the source vertex to the current vertex, diff --git a/D3130_Container_Interface/tex/container_interface.tex b/D3130_Container_Interface/tex/container_interface.tex index 5487cf3..b73ec02 100644 --- a/D3130_Container_Interface/tex/container_interface.tex +++ b/D3130_Container_Interface/tex/container_interface.tex @@ -3,12 +3,12 @@ %% \chapter{Graph Container Interface} \section{Graph Container Interface} -The Graph Container Interface (GCI) defines the primitive concepts, traits, types and functions used to define and access an adacency lists (aka graph) +The Graph Container Interface (GCI) defines the primitive concepts, traits, types and functions used to define and access adjacency lists (aka graphs) and edgelists, no matter their internal design and organization. For instance, an adjacency list can be a vector of lists from standard containers, CSR-based graph and adjacency matrix. Likewise, an edgelist can be a range of edges from a standard container or externally defined edge types, provided they have a source\_id, target\_id and optional edge\_value. -If there is a desire to use the algorithms against externally defined data structures, the GCI exposes is functions as customization points +If there is a desire to use the algorithms against externally defined data structures, the GCI exposes its functions as customization points to be overridden as needed. Likewise, externally defined algorithms can be used to operate on other data structures that meet the GCI requirements. This achieves the same goals as the STL, where algorithms can be used on any container that meets the requirements of the algorithm. @@ -18,7 +18,7 @@ \section{Graph Container Interface} such as sparse vertex\_ids, non-integral vertex\_ids, or storing vertices in associative bi-directional containers (e.g. std::map or std::unordered\_map). Such features require specialized implementations for views and algorithms. The performance for such algorithms will be sub-optimal, but may be -preferrable to run them on the existing container rather than loading the graph into a high-performance graph container and then running the +preferable to run them on the existing container rather than loading the graph into a high-performance graph container and then running the algorithm on it, where the loading time can far outweigh the time to run the sub-optimal algorithm. To achieve this, care has been taken to make sure that the use of concepts chosen is appropriate for algorithm, view and container. @@ -36,7 +36,7 @@ \subsection{Concepts} \item \textbf{sourced} where an edge has a source id. \end{itemize} -\emph{While we belive the use of concepts is appropriate for graphs as a range-of-ranges, we are marking them as "For exposition only" +\emph{While we believe the use of concepts is appropriate for graphs as a range-of-ranges, we are marking them as "For exposition only" until we have consensus of whether they belong in the standard or not.} \subsubsection{Edge Concepts} @@ -71,7 +71,7 @@ \subsubsection{Edge Concepts} \end{lstlisting} The final option allows the compiler to report a regular error or warning if the returned value isn't what's expected in the context it's used because the types are included in the error message, making it easier to understand what the problem is. -Additionally, functions aren't distiguished by their return type, so there's little value in attempting to check it in this case. +Additionally, functions aren't distinguished by their return type, so there's little value in attempting to check it in this case. There is precedent for this design choice of not validating the return type, as can be seen in the \href{https://en.cppreference.com/w/cpp/ranges/sized_range}{\tcode{sized_range}}concept. @@ -85,7 +85,7 @@ \subsubsection{Edge Concepts} \subsubsection{Vertex Concepts} The \tcode{vertex_range} concept is the general definition used for adjacency lists while \tcode{index_vertex_range} is used for -high performance graphs where vertices typically stored in a \tcode{vector}. +high performance graphs where vertices are typically stored in a \tcode{vector}. {\small \lstinputlisting{D3130_Container_Interface/src/concepts_vertex_range.hpp} } @@ -182,13 +182,13 @@ \subsection{Classes and Structs} is only anticipated to be used by the \tcode{load} functions at this time. No additional functionality is added beyond that provided by \tcode{runtime_error}. -\emph{While we belive the use of concepts is appropriate for graphs as a range-of-ranges, we are marking them as "For exposition only" +\emph{While we believe the use of concepts is appropriate for graphs as a range-of-ranges, we are marking them as "For exposition only" until we have consensus of whether they belong in the standard or not.} \subsection{Functions} Tables \ref{tab:graph_func}, \ref{tab:vertex_func} and \ref{tab:edge_func} summarize the primitive functions in the Graph Container Interface. -used to access an adacency graph, no matter its internal design and organization. Thus, it is designed +used to access an adjacency graph, no matter its internal design and organization. Thus, it is designed to be able to reflect all forms of adjacency graphs including a vector of lists, CSR-based graph and adjacency matrix. @@ -233,7 +233,7 @@ \subsection{Functions} \hline \tcode{find_vertex(g,uid)} & \tcode{vertex_iterator_t} & constant & \tcode{begin(vertices(g)) + uid} \\ & & & \hspace{3mm}if \tcode{random_access_range>} \\ - \tcode{vertex_id(g,u)} & \tcode{vetex_id_t} & constant & (see Determining the vertex\_id type below) \\ + \tcode{vertex_id(g,u)} & \tcode{vertex_id_t} & constant & (see Determining the vertex\_id type below) \\ & & & Override to define a different \\ & & & \tcode{vertex_id_t} type (e.g. int32\_t). \\ \tcode{vertex_value(g,u)} & \tcode{vertex_value_t} & constant & n/a, optional \\ @@ -241,7 +241,7 @@ \subsection{Functions} & & & optional \\ \tcode{degree(g,u)} & \tcode{integral} & constant & \tcode{size(edges(g,u))} if \tcode{sized_range>} \\ \tcode{degree(g,uid)} & \tcode{integral} & constant & \tcode{size(edges(g,uid))} if \tcode{sized_range>} \\ - \tcode{edges(g,u)} & \tcode{vertex_edge_range_t} & constant & \tcode{u} if \tcode{forward range>}, n/a otherwise \\ + \tcode{edges(g,u)} & \tcode{vertex_edge_range_t} & constant & \tcode{u} if \tcode{forward_range>}, n/a otherwise \\ \tcode{edges(g,uid)} & \tcode{vertex_edge_range_t} & constant & \tcode{edges(g,*find_vertex(g,uid))} \\ \hdashline \tcode{partition_id(g,u)} & \tcode{partition_id_t} & constant & \\ @@ -261,32 +261,32 @@ \subsection{Functions} \begin{table}[h!] \begin{center} \resizebox{\textwidth}{!} -{\begin{tabular}{l l p{1.5cm} L{6.7cm}} +{\begin{tabular}{l l p{1.3cm} L{6.9cm}} \hline \textbf{Function} & \textbf{Return Type} & \textbf{Cmplx} & \textbf{Default Implementation} \\ \hline \tcode{target_id(g,uv)} & \tcode{vertex_id_t} & constant & (see below) \\ \tcode{target(g,uv)} & \tcode{vertex_t} & constant & \tcode{*(begin(vertices(g)) + target_id(g, uv))} \\ - & & & \hspace{3mm}if \tcode{random_access_range>} \\ - & & & \hspace{3mm}\tcode{\&\& integral} \\ + & & & if \tcode{random_access_range>} \\ + & & & \hspace{3mm}\tcode{\&\& integral} \\ \tcode{edge_value(g,uv)} & \tcode{edge_value_t} & constant & \tcode{uv} if \tcode{forward_range>}, \\ & & & n/a otherwise, optional \\ \tcode{find_vertex_edge(g,u,vid)} & \tcode{vertex_edge_t} & linear & \tcode{find(edges(g,u),} \\ - & & & \hspace{8mm}\tcode{[](uv) {target_id(g,uv)==vid;\})}} \\ + & & & \tcode{[](uv) \{ return target_id(g,uv)==vid; \})} \\ \tcode{find_vertex_edge(g,uid,vid)} & \tcode{vertex_edge_t} & linear & \tcode{find_vertex_edge(} \\ & & & \hspace{8mm}\tcode{g, *find_vertex(g,uid), vid)} \\ \tcode{contains_edge(g,uid,vid)} & \tcode{bool} & constant & \tcode{uid < size(vertices(g))} \\ - & & & \tcode{&& vid < size(vertices(g))} \\ + & & & \tcode{\&\& vid < size(vertices(g))} \\ & & & \hspace{3mm}if \tcode{is_adjacency_matrix_v}.\\ - & & linear & \tcode{find_vertex_edge(g,uid)} \\ + & & linear & \tcode{find_vertex_edge(g,uid,vid)} \\ & & & \tcode{!= end(edges(g,uid))} otherwise. \\ \hdashline \multicolumn{4}{c}{The following are only available when the optional \tcode{source_id(g,uv)} is defined for the edge} \\ \hdashline \tcode{source_id(g,uv)} & \tcode{vertex_id_t} & constant & n/a, optional \\ \tcode{source(g,uv)} & \tcode{vertex_t} & constant & \tcode{*(begin(vertices(g)) + source_id(g,uv))} \\ - & & & \hspace{3mm}if \tcode{random_access_range>} \\ - & & & \hspace{3mm}\tcode{&& integral} \\ + & & & if \tcode{random_access_range>} \\ + & & & \hspace{3mm}\tcode{\&\& integral} \\ \hline \end{tabular}} \caption{Edge Functions} @@ -302,7 +302,7 @@ \subsection{Functions} Value functions (\tcode{graph_value(g)}, \tcode{vertex_value(g,u)} and \tcode{edge_value(g,uv)}) can be optionally implemented, depending on whether the graph container supports values on the graph, vertex and edge types. They return a single value and can -be scaler, struct, class, union, or tuple. These are abstract types used by the GVF, VVF and EVF function objects to retrieve +be scalar, struct, class, union, or tuple. These are abstract types used by the GVF, VVF and EVF function objects to retrieve values used by algorithms. As such it's valid to return the "enclosing" owning class (graph, vertex or edge), or some other embedded value in those objects. @@ -320,7 +320,7 @@ \subsection{Determining the vertex\_id and its type} \item Use \tcode{size_t} in all other cases. \end{enumerate} -\tcode{vertex_id_t} is defined by the type returned by \tcode{vertex_id(g)} and it defaults to the difference\_type of the underlying container used for vertices (e.g int64\_t for 64-bit systems). +\tcode{vertex_id_t} is defined by the type returned by \tcode{vertex_id(g)} and it defaults to the difference\_type of the underlying container used for vertices (e.g. int64\_t for 64-bit systems). This is sufficient for all situations. However, there are often space and performance advantages if a smaller type is used, such as int32\_t or even int16\_t. It is recommended to consider overriding this function for optimal results, assuring that it is also large enough for the number of possible vertices and edges in the application. It will also need to be overridden if the implementation doesn't expose the vertices as a range. @@ -341,7 +341,7 @@ \subsection{Vertex and Edge Descriptor Views} a user to work with different graph types in a consistent manner. A benefit of using descriptors is that it reduces the number of functions and concepts needed for the GCI -compared to previous designs. Without them, an iterface would require additional functions and concepts, +compared to previous designs. Without them, an interface would require additional functions and concepts, and algorithms would need to be specialized for vertices stored in random-access containers compared to associative containers. @@ -358,7 +358,7 @@ \subsection{Vertex and Edge Descriptor Views} \item Ordering: Descriptors can be ordered using the \tcode{<}, \tcode{<=}, \tcode{>}, and \tcode{>=} operators, if supported by the iterators in underlying container being used. \item Copy and assignment: Descriptors can be copied and assigned, ensuring they can be used in standard algorithms and containers. - \item Default construction: Descriptors can be default-constructed, though the resulting value are not guaranteed to represent + \item Default construction: Descriptors can be default-constructed, though the resulting values are not guaranteed to represent a valid vertex or edge. \end{itemize} @@ -366,8 +366,8 @@ \subsection{Vertex and Edge Descriptor Views} in the underlying container. This is only needed for overriding the customization points when you're adapting your own graph container to the GCI. -The only vertex function that requires a vertex id \tcode{(uid)}is \tcode{find_vertex(g,uid).} All other functions -that accept vertex id are convenience functions that imply a call to \tcode{find_vertex(g,uid)}to get the vertex +The only vertex function that requires a vertex id \tcode{(uid)} is \tcode{find_vertex(g,uid).} All other functions +that accept vertex id are convenience functions that imply a call to \tcode{find_vertex(g,uid)} to get the vertex descriptor before a call. The following are the descriptor views used by \tcode{vertices(g)} and \tcode{edges(g,u)}. \tcode{descriptor_subrange_view} @@ -407,14 +407,14 @@ \section{Edgelist Interface} An edgelist is a range of values where we can get the source\_id and target\_id, and an optional edge\_value. It is similar to edges in an adjacency list or edges in the incidence view, but is a distinct range of values that are separate from the others. -Like the adjacency list, the edgelist has default implementations that use the standard library for simple implmentations out of the box. +Like the adjacency list, the edgelist has default implementations that use the standard library for simple implementations out of the box. It's also able to easily adapt to externally defined edge types by overriding the \tcode{source_id(e)}, \tcode{target_id(e)} and \tcode{edge_value(e)} functions. \subsection{Namespace} The concepts and types for the edgelist are defined in the \tcode{std::graph::edgelist} namespace to avoid conflicts with the adjacency list. -\phil{It would be nice to include them in std::graph, but I'm having difficulting figuring out how to do that based on adjlist and edgelist concepts.} +\phil{It would be nice to include them in std::graph, but I'm having difficulty figuring out how to do that based on adjlist and edgelist concepts.} \subsection{Concepts} @@ -497,7 +497,7 @@ \subsection{Functions} \hdashline \tcode{contains_edge(el,uid,vid)} & \tcode{bool} & linear & \tcode{find_if(el, [](edge_reference_t e) \{} \\ & & & \hspace{7mm}\tcode{return source_id(e)==uid} \\ - & & & \hspace{13.5mm}\tcode{&& target_id(e)==vid;\} )} \\ + & & & \hspace{13.5mm}\tcode{\&\& target_id(e)==vid; \} )} \\ \tcode{num_edges(el)} & \tcode{integral} & constant & \tcode{size(el)} \\ \tcode{has_edge(el)} & \tcode{bool} & constant & \tcode{num_edges(el)>0} \\ \hline @@ -523,7 +523,7 @@ \subsection{Determining the source\_id, target\_id and edge\_value types} The \tcode{edge_info} patterns are \begin{itemize} \item \tcode{edge_info} with \tcode{source_id(e)} and \tcode{target_id(e)}. - \item \tcode{edge_info} with \tcode{source_id(e)}, \tcode{target_id(e)} and \tcode{edge_value(e)}. + \item \tcode{edge_info} with \tcode{source_id(e)}, \tcode{target_id(e)} and \tcode{edge_value(e)}. \end{itemize} In all other cases the functions will need to be overridden for the edge type. diff --git a/D3131_Containers/tex/containers.tex b/D3131_Containers/tex/containers.tex index 5d707a4..ba799e1 100644 --- a/D3131_Containers/tex/containers.tex +++ b/D3131_Containers/tex/containers.tex @@ -8,10 +8,10 @@ \section{compressed\_graph Graph Container} (CSR) format to store its vertices, edges and associated values. Once constructed, vertices and edges cannot be added or deleted but values on vertices and edges can be modified. -There are a number of features added beyond the typical CSR implmentation: +There are a number of features added beyond the typical CSR implementation: \begin{itemize} \item \textbf{User-defined values} The typical CSR implementation stores values on edges (columns) by defining the \tcode{EV} - template paraemter. \tcode{compressed_graph} extends that to also allow values on vertices (rows) and the graph itself + template parameter. \tcode{compressed_graph} extends that to also allow values on vertices (rows) and the graph itself by defining the \tcode{VV} and \tcode{GV} template arguments respectively. If a type is void, no memory overhead is incurred. \item \textbf{Index type sizes} The size of the integral indexes into the internal vertex (row) and edge (column) structures can be controlled by the \tcode{VId} and \tcode{EIndex} template arguments respectively to give a balance between capacity, memory @@ -24,7 +24,7 @@ \section{compressed\_graph Graph Container} The listings in the following sections show the prototypes for the \tcode{compressed_graph} when the graph value type \tcode{GV} is non-\tcode{void} (section \ref{compressed_full}) and a class template specialization when it is \tcode{void} (section \ref{compressed_specialization}). -Only the constuctors and destructor shown for \tcode{compressed_graph} are public. All other types and functions related to the graph +Only the constructors and destructor shown for \tcode{compressed_graph} are public. All other types and functions related to the graph are only accessible through the types and functions in the Graph Container Interface. \begin{table}[h] @@ -35,7 +35,7 @@ \section{compressed\_graph Graph Container} \hline \textbf{vertex\_id assignment:} Contiguous & \textbf{\tcode{has_edge(g)}} $O(1)$ & \textbf{Append vertices?} No \\ \textbf{Vertices range:} Contiguous & \textbf{\tcode{num_edges(g)}} $O(1)$ & \textbf{Append edges?} No \\ - \textbf{Edge range:} Contiguous & \textbf{\tcode{partition_id(g,uid)}} $O(log(P+1))$ & \textbf{Partions?} Yes\\ + \textbf{Edge range:} Contiguous & \textbf{\tcode{partition_id(g,uid)}} $O(log(P+1))$ & \textbf{Partitions?} Yes\\ & & \textbf{is\_directed?} No \\ %O(log(P+1)) is the complexity of std::upper_bound; +1 is for the number of vertices added at the end of partition_start_ids \hline @@ -43,7 +43,7 @@ \section{compressed\_graph Graph Container} %\caption{Jaccard Coefficient Summary} \label{tab:compressed_graph_summary} \end{table} -$P$ is the number of partitions and is exepected to be small, e.g. $P = 2$ for bipartite and $P \leq 10$ for typical +$P$ is the number of partitions and is expected to be small, e.g. $P = 2$ for bipartite and $P \leq 10$ for typical multi-partite graphs. The \tcode{is_directed} trait is not supported. If \tcode{compressed_graph} is intended to be used for an undirected @@ -70,8 +70,8 @@ \subsection{compressed\_graph description} \begin{itemdescr} \pnum\mandates \begin{itemize} - \item The \tcode{EV} template argument for an edge value must be a copyable type or \tcode{void.} - \item The \tcode{VV} template argument for a vertex value must be a copyable type or \tcode{void.} + \item The \tcode{EV} template argument for an edge value must be a copyable type or \tcode{void}. + \item The \tcode{VV} template argument for a vertex value must be a copyable type or \tcode{void}. \item When the \tcode{GV} template argument for a graph value is not \tcode{void} it can be movable or copyable. It must have a default constructor if it is not passed in a \tcode{compressed_graph} constructor. \item The \tcode{EProj} template argument must be a projection that returns a value of \tcode{copyable_edge} type @@ -128,7 +128,7 @@ \subsection{Adjacency List Data Structures} \subsubsection{Using Standard Containers for an Adjacency List} When the graph is defined using standard containers, the GCI functions can be used without any function overrides. -For example this we'll use \tcode{G = vector>>} to define the graph, where \tcode{g} +In this example, we'll use \tcode{G = vector>>} to define the graph, where \tcode{g} is an instance of \tcode{G}. \tcode{tuple} defines the target\_id and weight property respectively. We can write loops to go through the vertices, and edges within each vertex, as follows. diff --git a/D3131_Containers/tex/revision.tex b/D3131_Containers/tex/revision.tex index cf538d6..f7893c7 100644 --- a/D3131_Containers/tex/revision.tex +++ b/D3131_Containers/tex/revision.tex @@ -35,9 +35,9 @@ \subsection*{\paperno r3} \item Changes related to boost::graph-like descriptors as described in \href{https://www.wg21.link/P3130r3}{P3130r3 Graph Container Interface}. Related changes that affect this paper include: \begin{itemize} - \item Rename \tcode{descriptor}structs to \tcode{info}structs for new boost::graph-like descriptors. - \item Remove \tcode{copyable_vertex}and \tcode{copyable_edge}from the \tcode{compressed_graph}\tcode{requires}clause - because decriptors are always copyable. + \item Rename \tcode{descriptor} structs to \tcode{info} structs for new boost::graph-like descriptors. + \item Remove \tcode{copyable_vertex} and \tcode{copyable_edge} from the \tcode{compressed_graph} \tcode{requires} clause + because descriptors are always copyable. \end{itemize} \end{itemize} diff --git a/D3337_Comparison.pdf b/D3337_Comparison.pdf index a528015..bfe839d 100644 Binary files a/D3337_Comparison.pdf and b/D3337_Comparison.pdf differ diff --git a/D3337_Comparison/tex/config.tex b/D3337_Comparison/tex/config.tex index 3c0f106..b939952 100644 --- a/D3337_Comparison/tex/config.tex +++ b/D3337_Comparison/tex/config.tex @@ -2,9 +2,9 @@ %%-------------------------------------------------- %% Version numbers \newcommand{\paperno}{D3337} -\newcommand{\docno}{\paperno r0} +\newcommand{\docno}{\paperno r1} \newcommand{\docname}{Graph Library: Comparison} -\newcommand{\prevdocno}{(none)} +\newcommand{\prevdocno}{D3337r0} \newcommand{\cppver}{202002L} %% Release date @@ -13,3 +13,9 @@ %% Library chapters \newcommand{\firstlibchapter}{language.support} \newcommand{\lastlibchapter}{thread} + +%%-------------------------------------------------- +%% Custom authors and contributors for this paper +%% These will override the defaults when the title system loads +%%-------------------------------------------------- + diff --git a/D3337_Comparison/tex/revision.tex b/D3337_Comparison/tex/revision.tex index 9131608..b6627b2 100644 --- a/D3337_Comparison/tex/revision.tex +++ b/D3337_Comparison/tex/revision.tex @@ -6,3 +6,9 @@ \subsection*{\paperno r0} \item New paper comparing the Graph Library to the NWGraph and Boost Graph Libraries on performance and usage syntax. \end{itemize} + +\subsection*{\paperno r1} + +\begin{itemize} + \item +\end{itemize} diff --git a/tex/default-authors.tex b/tex/default-authors.tex new file mode 100644 index 0000000..8d4d292 --- /dev/null +++ b/tex/default-authors.tex @@ -0,0 +1,78 @@ +%!TEX root = std.tex +%%-------------------------------------------------- +%% Default Authors and Contributors System +%% This file defines the default authors and contributors for all papers. +%% Individual papers can override these by defining custom commands in their config.tex files. +%%-------------------------------------------------- + +\makeatletter % Enable @ in command names for internal LaTeX commands + +%% Default authors - these appear as "Reply-to:" in the title page +\newcommand{\defaultauthors}{% +&Phil Ratzloff (SAS Institute)\\ +&\href{mailto:phil.ratzloff@sas.com}{\nolinkurl{phil.ratzloff@sas.com}}\\ +&Andrew Lumsdaine\\ +&\href{mailto:lumsdaine@gmail.com}{\nolinkurl{lumsdaine@gmail.com}}\\ +} + +%% Default contributors - these appear as "Contributors:" in the title page +\newcommand{\defaultcontributors}{% +&Kevin Deweese\\ +&Muhammad Osama (AMD, Inc)\\ +&Scott McMillan (Carnegie Mellon University)\\ +&Jesun Firoz\\ +&Michael Wong (Intel)\\ +&Jens Maurer\\ +&Richard Dosselmann (University of Regina)\\ +&Matthew Galati (Amazon)\\ +&Guy Davidson (Creative Assembly)\\ +&Oliver Rosten% +} + +%% Paper-specific authors (defaults to default authors, can be overridden) +%% Check if custom authors are defined in the paper's config, otherwise use defaults +\@ifundefined{custompaperauthors}{% + \newcommand{\paperauthors}{\defaultauthors}% +}{% + \newcommand{\paperauthors}{\custompaperauthors}% +} + +%% Paper-specific contributors (defaults to default contributors, can be overridden) +%% Check if custom contributors are defined in the paper's config, otherwise use defaults +\@ifundefined{custompapercontributors}{% + \newcommand{\papercontributors}{\defaultcontributors}% +}{% + \newcommand{\papercontributors}{\custompapercontributors}% +} + +\makeatother % Restore @ to normal behavior + +%%-------------------------------------------------- +%% Usage Instructions: +%% +%% To use default authors and contributors: +%% Just include this file and use \paperauthors and \papercontributors in your title template. +%% No configuration needed in individual papers. +%% +%% To override authors for a specific paper, add this to the paper's config.tex: +%% \newcommand{\custompaperauthors}{% +%% &Custom Author (Institution)\\ +%% &\href{mailto:custom@example.com}{\nolinkurl{custom@example.com}}\\ +%% &Another Author\\ +%% &\href{mailto:another@example.com}{\nolinkurl{another@example.com}}\\ +%% } +%% +%% To override contributors for a specific paper: +%% \newcommand{\custompapercontributors}{% +%% &Special Contributor\\ +%% &Another Expert\\ +%% &Yet Another Contributor% +%% } +%% +%% To add to the default contributors (keeping defaults plus adding more): +%% \newcommand{\custompapercontributors}{% +%% \defaultcontributors\\ +%% &Additional Contributor\\ +%% &Special Expert for This Paper% +%% } +%%-------------------------------------------------- diff --git a/tex/example-config.tex b/tex/example-config.tex new file mode 100644 index 0000000..fd20065 --- /dev/null +++ b/tex/example-config.tex @@ -0,0 +1,50 @@ +%!TEX root = std.tex +%%-------------------------------------------------- +%% Version numbers +\newcommand{\paperno}{DXXXX} +\newcommand{\docno}{\paperno r1} +\newcommand{\docname}{Example Paper Title} +\newcommand{\prevdocno}{PXXXX r0} +\newcommand{\cppver}{202002L} +\newcommand{\mailing}{} + +%% Release date +\newcommand{\reldate}{\today} + +%%-------------------------------------------------- +%% Author and Contributor Customization Examples +%%-------------------------------------------------- + +%% Example 1: Override default authors completely for this paper +%% \newcommand{\custompaperauthors}{% +%% &Custom Author (Special Institution)\\ +%% &\href{mailto:custom@example.com}{\nolinkurl{custom@example.com}}\\ +%% &Another Author\\ +%% &\href{mailto:another@example.com}{\nolinkurl{another@example.com}}\\ +%% } + +%% Example 2: Override default contributors completely for this paper +%% \newcommand{\custompapercontributors}{% +%% &Special Contributor for This Paper\\ +%% &Domain Expert\\ +%% &Technical Reviewer% +%% } + +%% Example 3: Add to default contributors (keeping defaults plus adding more) +%% \newcommand{\custompapercontributors}{% +%% \defaultcontributors\\ +%% &Additional Contributor for This Paper\\ +%% &Special Expert for This Topic% +%% } + +%% Example 4: Mix default authors with custom contributors +%% Uses default authors, but custom contributors: +%% \newcommand{\custompapercontributors}{% +%% &Paper-Specific Contributor\\ +%% &Technical Expert for This Domain% +%% } + +%%-------------------------------------------------- +%% If no customization is needed, the paper will automatically +%% use the default authors and contributors from tex/default-authors.tex +%%-------------------------------------------------- diff --git a/tex/getting_started.tex b/tex/getting_started.tex index eae1b46..5104a97 100644 --- a/tex/getting_started.tex +++ b/tex/getting_started.tex @@ -27,7 +27,7 @@ \section{Getting Started} It also discusses how to use containers in the standard library to define a graph, and how to adapt existing graph data structures.\\ %P9907 & Future & \textbf{Adaptors} containing useful utilities to create adjacency lists from other data structures.\\ - \href{https://www.wg21.link/P3337}{P3337} & In process & \textbf{Comparison to other graph libraries} on performance and usage syntax. + \href{https://www.wg21.link/P3337}{P3337} & Active & \textbf{Comparison to other graph libraries} on performance and usage syntax. Not published yet. \\ \hline \end{tabular}} diff --git a/tex/title.tex b/tex/title.tex index b25f69a..d422268 100644 --- a/tex/title.tex +++ b/tex/title.tex @@ -1,3 +1,6 @@ +%% Include default authors and contributors system +\input{tex/default-authors} + \hypersetup{ pdftitle={Test document for \docno}, colorlinks=true, @@ -22,16 +25,7 @@ Revises: &\prevdocno\\ \\ Reply-to: \@author\\ -Contributors: &Kevin Deweese\\ - &Muhammad Osama (AMD, Inc)\\ - &Scott McMillan (Carnegie Mellon University)\\ - &Jesun Firoz\\ - &Michael Wong (Intel)\\ - &Jens Maurer\\ - &Richard Dosselmann (University of Regina)\\ - &Matthew Galati (Amazon)\\ - &Guy Davidson (Creative Assembly)\\ - &Oliver Rosten +Contributors: \papercontributors \end{tabular} \end{flushright} } @@ -44,7 +38,6 @@ } \makeatother % \subtitle{Visual inspection of various features of the framework} -\author{&Phil Ratzloff (SAS Institute)\\&\href{mailto:phil.ratzloff@sas.com}{\nolinkurl{phil.ratzloff@sas.com}}\\ -&Andrew Lumsdaine\\ -&\href{mailto:lumsdaine@gmail.com}{\nolinkurl{lumsdaine@gmail.com}}\\} -\date{2025-04-13} +\author{\paperauthors} + +\date{2025-07-30}