graph_apis.cc 10.7 KB
Newer Older
1
2
3
4
5
/*!
 *  Copyright (c) 2018 by Contributors
 * \file graph/graph.cc
 * \brief DGL graph index APIs
 */
6
#include <dgl/packed_func_ext.h>
Minjie Wang's avatar
Minjie Wang committed
7
#include <dgl/graph.h>
8
#include <dgl/immutable_graph.h>
Minjie Wang's avatar
Minjie Wang committed
9
#include <dgl/graph_op.h>
Da Zheng's avatar
Da Zheng committed
10
#include <dgl/sampler.h>
11
#include <dgl/nodeflow.h>
Lingfan Yu's avatar
Lingfan Yu committed
12
#include "../c_api_common.h"
Minjie Wang's avatar
Minjie Wang committed
13

14
15
16
17
18
using dgl::runtime::DGLArgs;
using dgl::runtime::DGLArgValue;
using dgl::runtime::DGLRetValue;
using dgl::runtime::PackedFunc;
using dgl::runtime::NDArray;
Minjie Wang's avatar
Minjie Wang committed
19
20

namespace dgl {
Minjie Wang's avatar
Minjie Wang committed
21

Minjie Wang's avatar
Minjie Wang committed
22
namespace {
23

Minjie Wang's avatar
Minjie Wang committed
24
25
// Convert Subgraph structure to PackedFunc.
PackedFunc ConvertSubgraphToPackedFunc(const Subgraph& sg) {
26
  auto body = [sg] (DGLArgs args, DGLRetValue* rv) {
Minjie Wang's avatar
Minjie Wang committed
27
      const int which = args[0];
Minjie Wang's avatar
Minjie Wang committed
28
      if (which == 0) {
29
        *rv = GraphRef(sg.graph);
30
      } else if (which == 1) {
Minjie Wang's avatar
Minjie Wang committed
31
        *rv = std::move(sg.induced_vertices);
32
      } else if (which == 2) {
Minjie Wang's avatar
Minjie Wang committed
33
        *rv = std::move(sg.induced_edges);
34
35
36
      } else {
        LOG(FATAL) << "invalid choice";
      }
Minjie Wang's avatar
Minjie Wang committed
37
38
39
    };
  return PackedFunc(body);
}
Minjie Wang's avatar
Minjie Wang committed
40

Minjie Wang's avatar
Minjie Wang committed
41
}  // namespace
Minjie Wang's avatar
Minjie Wang committed
42

43
44
45
///////////////////////////// Graph API ///////////////////////////////////

DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphCreateMutable")
46
.set_body([] (DGLArgs args, DGLRetValue* rv) {
47
48
    bool multigraph = args[0];
    *rv = GraphRef(Graph::Create(multigraph));
Minjie Wang's avatar
Minjie Wang committed
49
  });
Minjie Wang's avatar
Minjie Wang committed
50

51

52
53
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphCreate")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
54
55
    const IdArray src_ids = args[0];
    const IdArray dst_ids = args[1];
56
57
58
    const int multigraph = args[2];
    const int64_t num_nodes = args[3];
    const bool readonly = args[4];
59
    if (readonly) {
60
      if (multigraph == kBoolUnknown) {
61
        *rv = GraphRef(ImmutableGraph::CreateFromCOO(num_nodes, src_ids, dst_ids));
62
      } else {
63
        *rv = GraphRef(ImmutableGraph::CreateFromCOO(num_nodes, src_ids, dst_ids, multigraph));
64
      }
65
    } else {
66
      CHECK_NE(multigraph, kBoolUnknown);
67
      *rv = GraphRef(Graph::CreateFromCOO(num_nodes, src_ids, dst_ids, multigraph));
68
    }
69
70
  });

71
72
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphCSRCreate")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
73
74
    const IdArray indptr = args[0];
    const IdArray indices = args[1];
75
    const std::string shared_mem_name = args[2];
76
    const int multigraph = args[3];
77
78
79
80
81
82
83
    const std::string edge_dir = args[4];

    IdArray edge_ids = IdArray::Empty({indices->shape[0]},
                                      DLDataType{kDLInt, 64, 1}, DLContext{kDLCPU, 0});
    int64_t *edge_data = static_cast<int64_t *>(edge_ids->data);
    for (size_t i = 0; i < edge_ids->shape[0]; i++)
      edge_data[i] = i;
84
85
    if (shared_mem_name.empty()) {
      if (multigraph == kBoolUnknown) {
86
        *rv = GraphRef(ImmutableGraph::CreateFromCSR(indptr, indices, edge_ids, edge_dir));
87
      } else {
88
89
        *rv = GraphRef(ImmutableGraph::CreateFromCSR(
            indptr, indices, edge_ids, multigraph, edge_dir));
90
91
92
      }
    } else {
      if (multigraph == kBoolUnknown) {
93
94
        *rv = GraphRef(ImmutableGraph::CreateFromCSR(
            indptr, indices, edge_ids, edge_dir, shared_mem_name));
95
      } else {
96
97
        *rv = GraphRef(ImmutableGraph::CreateFromCSR(indptr, indices, edge_ids,
            multigraph, edge_dir, shared_mem_name));
98
99
      }
    }
100
101
102
103
104
105
106
  });

DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphCSRCreateMMap")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
    const std::string shared_mem_name = args[0];
    const int64_t num_vertices = args[1];
    const int64_t num_edges = args[2];
107
    const bool multigraph = args[3];
108
    const std::string edge_dir = args[4];
109
    // TODO(minjie): how to know multigraph
110
    *rv = GraphRef(ImmutableGraph::CreateFromCSR(
111
      shared_mem_name, num_vertices, num_edges, multigraph, edge_dir));
Minjie Wang's avatar
Minjie Wang committed
112
  });
Minjie Wang's avatar
Minjie Wang committed
113

114
115
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphAddVertices")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
116
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
117
    uint64_t num_vertices = args[1];
118
    g->AddVertices(num_vertices);
Minjie Wang's avatar
Minjie Wang committed
119
  });
Minjie Wang's avatar
Minjie Wang committed
120

121
122
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphAddEdge")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
123
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
124
125
    const dgl_id_t src = args[1];
    const dgl_id_t dst = args[2];
126
    g->AddEdge(src, dst);
Minjie Wang's avatar
Minjie Wang committed
127
  });
Minjie Wang's avatar
Minjie Wang committed
128

129
130
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphAddEdges")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
131
    GraphRef g = args[0];
132
133
    const IdArray src = args[1];
    const IdArray dst = args[2];
134
    g->AddEdges(src, dst);
Minjie Wang's avatar
Minjie Wang committed
135
136
  });

137
138
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphClear")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
139
140
    GraphRef g = args[0];
    g->Clear();
Minjie Wang's avatar
Minjie Wang committed
141
  });
Minjie Wang's avatar
Minjie Wang committed
142

143
144
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphIsMultigraph")
.set_body([] (DGLArgs args, DGLRetValue *rv) {
145
146
    GraphRef g = args[0];
    *rv = g->IsMultigraph();
147
148
  });

149
150
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphIsReadonly")
.set_body([] (DGLArgs args, DGLRetValue *rv) {
151
152
    GraphRef g = args[0];
    *rv = g->IsReadonly();
153
154
  });

155
156
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphNumVertices")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
157
158
    GraphRef g = args[0];
    *rv = static_cast<int64_t>(g->NumVertices());
Minjie Wang's avatar
Minjie Wang committed
159
  });
Minjie Wang's avatar
Minjie Wang committed
160

161
162
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphNumEdges")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
163
164
    GraphRef g = args[0];
    *rv = static_cast<int64_t>(g->NumEdges());
Minjie Wang's avatar
Minjie Wang committed
165
166
  });

167
168
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasVertex")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
169
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
170
    const dgl_id_t vid = args[1];
171
    *rv = g->HasVertex(vid);
Minjie Wang's avatar
Minjie Wang committed
172
173
  });

174
175
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasVertices")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
176
    GraphRef g = args[0];
177
    const IdArray vids = args[1];
178
    *rv = g->HasVertices(vids);
179
180
  });

181
182
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasEdgeBetween")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
183
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
184
185
    const dgl_id_t src = args[1];
    const dgl_id_t dst = args[2];
186
    *rv = g->HasEdgeBetween(src, dst);
Minjie Wang's avatar
Minjie Wang committed
187
188
  });

189
190
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasEdgesBetween")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
191
    GraphRef g = args[0];
192
193
    const IdArray src = args[1];
    const IdArray dst = args[2];
194
    *rv = g->HasEdgesBetween(src, dst);
Minjie Wang's avatar
Minjie Wang committed
195
196
  });

197
198
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphPredecessors")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
199
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
200
201
    const dgl_id_t vid = args[1];
    const uint64_t radius = args[2];
202
    *rv = g->Predecessors(vid, radius);
Minjie Wang's avatar
Minjie Wang committed
203
204
  });

205
206
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphSuccessors")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
207
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
208
209
    const dgl_id_t vid = args[1];
    const uint64_t radius = args[2];
210
    *rv = g->Successors(vid, radius);
Minjie Wang's avatar
Minjie Wang committed
211
212
  });

213
214
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdgeId")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
215
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
216
217
    const dgl_id_t src = args[1];
    const dgl_id_t dst = args[2];
218
    *rv = g->EdgeId(src, dst);
Minjie Wang's avatar
Minjie Wang committed
219
220
  });

221
222
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdgeIds")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
223
    GraphRef g = args[0];
224
225
    const IdArray src = args[1];
    const IdArray dst = args[2];
226
    *rv = ConvertEdgeArrayToPackedFunc(g->EdgeIds(src, dst));
227
228
  });

229
230
231
232
233
234
235
236
237
238
239
240
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphFindEdge")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
    GraphRef g = args[0];
    const dgl_id_t eid = args[1];
    const auto& pair = g->FindEdge(eid);
    *rv = PackedFunc([pair] (DGLArgs args, DGLRetValue* rv) {
        const int choice = args[0];
        const int64_t ret = (choice == 0? pair.first : pair.second);
        *rv = ret;
      });
  });

241
242
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphFindEdges")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
243
    GraphRef g = args[0];
244
    const IdArray eids = args[1];
245
    *rv = ConvertEdgeArrayToPackedFunc(g->FindEdges(eids));
Minjie Wang's avatar
Minjie Wang committed
246
247
  });

248
249
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInEdges_1")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
250
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
251
    const dgl_id_t vid = args[1];
252
    *rv = ConvertEdgeArrayToPackedFunc(g->InEdges(vid));
Minjie Wang's avatar
Minjie Wang committed
253
254
  });

255
256
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInEdges_2")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
257
    GraphRef g = args[0];
258
    const IdArray vids = args[1];
259
    *rv = ConvertEdgeArrayToPackedFunc(g->InEdges(vids));
Minjie Wang's avatar
Minjie Wang committed
260
261
  });

262
263
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutEdges_1")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
264
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
265
    const dgl_id_t vid = args[1];
266
    *rv = ConvertEdgeArrayToPackedFunc(g->OutEdges(vid));
Minjie Wang's avatar
Minjie Wang committed
267
268
  });

269
270
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutEdges_2")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
271
    GraphRef g = args[0];
272
    const IdArray vids = args[1];
273
    *rv = ConvertEdgeArrayToPackedFunc(g->OutEdges(vids));
Minjie Wang's avatar
Minjie Wang committed
274
275
  });

276
277
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdges")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
278
    GraphRef g = args[0];
279
    std::string order = args[1];
280
    *rv = ConvertEdgeArrayToPackedFunc(g->Edges(order));
Minjie Wang's avatar
Minjie Wang committed
281
282
  });

283
284
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInDegree")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
285
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
286
    const dgl_id_t vid = args[1];
287
    *rv = static_cast<int64_t>(g->InDegree(vid));
Minjie Wang's avatar
Minjie Wang committed
288
289
  });

290
291
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInDegrees")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
292
    GraphRef g = args[0];
293
    const IdArray vids = args[1];
294
    *rv = g->InDegrees(vids);
Minjie Wang's avatar
Minjie Wang committed
295
296
  });

297
298
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutDegree")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
299
    GraphRef g = args[0];
Minjie Wang's avatar
Minjie Wang committed
300
    const dgl_id_t vid = args[1];
301
    *rv = static_cast<int64_t>(g->OutDegree(vid));
Minjie Wang's avatar
Minjie Wang committed
302
303
  });

304
305
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutDegrees")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
306
    GraphRef g = args[0];
307
    const IdArray vids = args[1];
308
    *rv = g->OutDegrees(vids);
Minjie Wang's avatar
Minjie Wang committed
309
  });
Minjie Wang's avatar
Minjie Wang committed
310

311
312
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphVertexSubgraph")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
313
    GraphRef g = args[0];
314
    const IdArray vids = args[1];
315
    *rv = ConvertSubgraphToPackedFunc(g->VertexSubgraph(vids));
Minjie Wang's avatar
Minjie Wang committed
316
317
  });

318
319
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdgeSubgraph")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
320
    GraphRef g = args[0];
321
    const IdArray eids = args[1];
322
    bool preserve_nodes = args[2];
323
    *rv = ConvertSubgraphToPackedFunc(g->EdgeSubgraph(eids, preserve_nodes));
GaiYu0's avatar
cpp lg  
GaiYu0 committed
324
  });
GaiYu0's avatar
GaiYu0 committed
325

326
327
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphGetAdj")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
328
    GraphRef g = args[0];
329
330
    bool transpose = args[1];
    std::string format = args[2];
331
    auto res = g->GetAdj(transpose, format);
332
    *rv = ConvertNDArrayVectorToPackedFunc(res);
333
334
  });

335
336
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphContext")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
337
338
    GraphRef g = args[0];
    *rv = g->Context();
339
340
  });

341
342
DGL_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphNumBits")
.set_body([] (DGLArgs args, DGLRetValue* rv) {
343
344
    GraphRef g = args[0];
    *rv = g->NumBits();
345
346
  });

Minjie Wang's avatar
Minjie Wang committed
347
}  // namespace dgl