graph_apis.cc 11.5 KB
Newer Older
Minjie Wang's avatar
Minjie Wang committed
1
2
3
#include <dgl/runtime/packed_func.h>
#include <dgl/runtime/registry.h>
#include <dgl/graph.h>
Minjie Wang's avatar
Minjie Wang committed
4
#include <dgl/graph_op.h>
Minjie Wang's avatar
Minjie Wang committed
5
6
7
8
9

using tvm::runtime::TVMArgs;
using tvm::runtime::TVMArgValue;
using tvm::runtime::TVMRetValue;
using tvm::runtime::PackedFunc;
Minjie Wang's avatar
Minjie Wang committed
10
using tvm::runtime::NDArray;
Minjie Wang's avatar
Minjie Wang committed
11
12

namespace dgl {
Minjie Wang's avatar
Minjie Wang committed
13
14
15
16

// Graph handler type
typedef void* GraphHandle;

Minjie Wang's avatar
Minjie Wang committed
17
namespace {
Minjie Wang's avatar
Minjie Wang committed
18
// Convert EdgeArray structure to PackedFunc.
19
20
PackedFunc ConvertEdgeArrayToPackedFunc(const Graph::EdgeArray& ea) {
  auto body = [ea] (TVMArgs args, TVMRetValue* rv) {
Minjie Wang's avatar
Minjie Wang committed
21
      int which = args[0];
22
      if (which == 0) {
Minjie Wang's avatar
Minjie Wang committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        *rv = std::move(ea.src);
      } else if (which == 1) {
        *rv = std::move(ea.dst);
      } else if (which == 2) {
        *rv = std::move(ea.id);
      } else {
        LOG(FATAL) << "invalid choice";
      }
    };
  return PackedFunc(body);
}

// Convert Subgraph structure to PackedFunc.
PackedFunc ConvertSubgraphToPackedFunc(const Subgraph& sg) {
  auto body = [sg] (TVMArgs args, TVMRetValue* rv) {
      int which = args[0];
      if (which == 0) {
        Graph* gptr = new Graph();
        *gptr = std::move(sg.graph);
        GraphHandle ghandle = gptr;
        *rv = ghandle;
44
      } else if (which == 1) {
Minjie Wang's avatar
Minjie Wang committed
45
        *rv = std::move(sg.induced_vertices);
46
      } else if (which == 2) {
Minjie Wang's avatar
Minjie Wang committed
47
        *rv = std::move(sg.induced_edges);
48
49
50
      } else {
        LOG(FATAL) << "invalid choice";
      }
Minjie Wang's avatar
Minjie Wang committed
51
52
53
    };
  return PackedFunc(body);
}
Minjie Wang's avatar
Minjie Wang committed
54

Minjie Wang's avatar
Minjie Wang committed
55
// Convert the given DLTensor to a temporary DLManagedTensor that does not own memory.
Minjie Wang's avatar
Minjie Wang committed
56
57
58
59
60
61
62
63
64
DLManagedTensor* CreateTmpDLManagedTensor(const TVMArgValue& arg) {
  const DLTensor* dl_tensor = arg;
  DLManagedTensor* ret = new DLManagedTensor();
  ret->deleter = [] (DLManagedTensor* self) { delete self; };
  ret->manager_ctx = nullptr;
  ret->dl_tensor = *dl_tensor;
  return ret;
}

Minjie Wang's avatar
Minjie Wang committed
65
}  // namespace
Minjie Wang's avatar
Minjie Wang committed
66

Minjie Wang's avatar
Minjie Wang committed
67
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphCreate")
Minjie Wang's avatar
Minjie Wang committed
68
69
70
71
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = new Graph();
    *rv = ghandle;
  });
Minjie Wang's avatar
Minjie Wang committed
72

Minjie Wang's avatar
Minjie Wang committed
73
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphFree")
Minjie Wang's avatar
Minjie Wang committed
74
75
76
77
78
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    Graph* gptr = static_cast<Graph*>(ghandle);
    delete gptr;
  });
Minjie Wang's avatar
Minjie Wang committed
79

Minjie Wang's avatar
Minjie Wang committed
80
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphAddVertices")
Minjie Wang's avatar
Minjie Wang committed
81
82
83
84
85
86
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    Graph* gptr = static_cast<Graph*>(ghandle);
    uint64_t num_vertices = args[1];
    gptr->AddVertices(num_vertices);
  });
Minjie Wang's avatar
Minjie Wang committed
87

Minjie Wang's avatar
Minjie Wang committed
88
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphAddEdge")
Minjie Wang's avatar
Minjie Wang committed
89
90
91
92
93
94
95
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t src = args[1];
    const dgl_id_t dst = args[2];
    gptr->AddEdge(src, dst);
  });
Minjie Wang's avatar
Minjie Wang committed
96

Minjie Wang's avatar
Minjie Wang committed
97
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphAddEdges")
Minjie Wang's avatar
Minjie Wang committed
98
99
100
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
101
102
    const IdArray src = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
    const IdArray dst = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[2]));
Minjie Wang's avatar
Minjie Wang committed
103
104
105
    gptr->AddEdges(src, dst);
  });

Minjie Wang's avatar
Minjie Wang committed
106
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphClear")
Minjie Wang's avatar
Minjie Wang committed
107
108
109
110
111
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    Graph* gptr = static_cast<Graph*>(ghandle);
    gptr->Clear();
  });
Minjie Wang's avatar
Minjie Wang committed
112

Minjie Wang's avatar
Minjie Wang committed
113
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphNumVertices")
Minjie Wang's avatar
Minjie Wang committed
114
115
116
117
118
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    *rv = static_cast<int64_t>(gptr->NumVertices());
  });
Minjie Wang's avatar
Minjie Wang committed
119

Minjie Wang's avatar
Minjie Wang committed
120
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphNumEdges")
Minjie Wang's avatar
Minjie Wang committed
121
122
123
124
125
126
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    *rv = static_cast<int64_t>(gptr->NumEdges());
  });

Minjie Wang's avatar
Minjie Wang committed
127
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasVertex")
Minjie Wang's avatar
Minjie Wang committed
128
129
130
131
132
133
134
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
    *rv = gptr->HasVertex(vid);
  });

Minjie Wang's avatar
Minjie Wang committed
135
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasVertices")
Minjie Wang's avatar
Minjie Wang committed
136
137
138
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
139
    const IdArray vids = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
Minjie Wang's avatar
Minjie Wang committed
140
141
142
    *rv = gptr->HasVertices(vids);
  });

Minjie Wang's avatar
Minjie Wang committed
143
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasEdge")
Minjie Wang's avatar
Minjie Wang committed
144
145
146
147
148
149
150
151
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t src = args[1];
    const dgl_id_t dst = args[2];
    *rv = gptr->HasEdge(src, dst);
  });

Minjie Wang's avatar
Minjie Wang committed
152
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphHasEdges")
Minjie Wang's avatar
Minjie Wang committed
153
154
155
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
156
157
    const IdArray src = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
    const IdArray dst = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[2]));
Minjie Wang's avatar
Minjie Wang committed
158
159
160
    *rv = gptr->HasEdges(src, dst);
  });

Minjie Wang's avatar
Minjie Wang committed
161
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphPredecessors")
Minjie Wang's avatar
Minjie Wang committed
162
163
164
165
166
167
168
169
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
    const uint64_t radius = args[2];
    *rv = gptr->Predecessors(vid, radius);
  });

Minjie Wang's avatar
Minjie Wang committed
170
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphSuccessors")
Minjie Wang's avatar
Minjie Wang committed
171
172
173
174
175
176
177
178
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
    const uint64_t radius = args[2];
    *rv = gptr->Successors(vid, radius);
  });

Minjie Wang's avatar
Minjie Wang committed
179
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdgeId")
Minjie Wang's avatar
Minjie Wang committed
180
181
182
183
184
185
186
187
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t src = args[1];
    const dgl_id_t dst = args[2];
    *rv = static_cast<int64_t>(gptr->EdgeId(src, dst));
  });

Minjie Wang's avatar
Minjie Wang committed
188
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdgeIds")
Minjie Wang's avatar
Minjie Wang committed
189
190
191
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
192
193
    const IdArray src = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
    const IdArray dst = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[2]));
Minjie Wang's avatar
Minjie Wang committed
194
195
196
    *rv = gptr->EdgeIds(src, dst);
  });

Minjie Wang's avatar
Minjie Wang committed
197
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInEdges_1")
Minjie Wang's avatar
Minjie Wang committed
198
199
200
201
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
202
    *rv = ConvertEdgeArrayToPackedFunc(gptr->InEdges(vid));
Minjie Wang's avatar
Minjie Wang committed
203
204
  });

Minjie Wang's avatar
Minjie Wang committed
205
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInEdges_2")
Minjie Wang's avatar
Minjie Wang committed
206
207
208
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
209
    const IdArray vids = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
210
    *rv = ConvertEdgeArrayToPackedFunc(gptr->InEdges(vids));
Minjie Wang's avatar
Minjie Wang committed
211
212
  });

Minjie Wang's avatar
Minjie Wang committed
213
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutEdges_1")
Minjie Wang's avatar
Minjie Wang committed
214
215
216
217
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
218
    *rv = ConvertEdgeArrayToPackedFunc(gptr->OutEdges(vid));
Minjie Wang's avatar
Minjie Wang committed
219
220
  });

Minjie Wang's avatar
Minjie Wang committed
221
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutEdges_2")
Minjie Wang's avatar
Minjie Wang committed
222
223
224
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
225
    const IdArray vids = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
226
    *rv = ConvertEdgeArrayToPackedFunc(gptr->OutEdges(vids));
Minjie Wang's avatar
Minjie Wang committed
227
228
  });

Minjie Wang's avatar
Minjie Wang committed
229
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphEdges")
Minjie Wang's avatar
Minjie Wang committed
230
231
232
233
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const bool sorted = args[1];
234
    *rv = ConvertEdgeArrayToPackedFunc(gptr->Edges(sorted));
Minjie Wang's avatar
Minjie Wang committed
235
236
  });

Minjie Wang's avatar
Minjie Wang committed
237
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInDegree")
Minjie Wang's avatar
Minjie Wang committed
238
239
240
241
242
243
244
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
    *rv = static_cast<int64_t>(gptr->InDegree(vid));
  });

Minjie Wang's avatar
Minjie Wang committed
245
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphInDegrees")
Minjie Wang's avatar
Minjie Wang committed
246
247
248
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
249
    const IdArray vids = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
Minjie Wang's avatar
Minjie Wang committed
250
251
252
    *rv = gptr->InDegrees(vids);
  });

Minjie Wang's avatar
Minjie Wang committed
253
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutDegree")
Minjie Wang's avatar
Minjie Wang committed
254
255
256
257
258
259
260
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const dgl_id_t vid = args[1];
    *rv = static_cast<int64_t>(gptr->OutDegree(vid));
  });

Minjie Wang's avatar
Minjie Wang committed
261
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutDegrees")
Minjie Wang's avatar
Minjie Wang committed
262
263
264
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
Minjie Wang's avatar
Minjie Wang committed
265
    const IdArray vids = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
Minjie Wang's avatar
Minjie Wang committed
266
267
    *rv = gptr->OutDegrees(vids);
  });
Minjie Wang's avatar
Minjie Wang committed
268

Minjie Wang's avatar
Minjie Wang committed
269
270
271
272
273
274
275
276
277
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphVertexSubgraph")
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const IdArray vids = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
    *rv = ConvertSubgraphToPackedFunc(gptr->VertexSubgraph(vids));
  });

TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLDisjointUnion")
278
279
280
281
282
283
284
285
286
287
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    void* list = args[0];
    GraphHandle* inhandles = static_cast<GraphHandle*>(list);
    int list_size = args[1];
    std::vector<const Graph*> graphs;
    for (int i = 0; i < list_size; ++i) {
      const Graph* gr = static_cast<const Graph*>(inhandles[i]);
      graphs.push_back(gr);
    }
    Graph* gptr = new Graph();
Minjie Wang's avatar
Minjie Wang committed
288
    *gptr = GraphOp::DisjointUnion(std::move(graphs));
289
290
291
292
    GraphHandle ghandle = gptr;
    *rv = ghandle;
  });

Minjie Wang's avatar
Minjie Wang committed
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLDisjointPartitionByNum")
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    int64_t num = args[1];
    std::vector<Graph>&& rst = GraphOp::DisjointPartitionByNum(gptr, num);
    // return the pointer array as an integer array
    const int64_t len = rst.size();
    NDArray ptr_array = NDArray::Empty({len}, DLDataType{kDLInt, 64, 1}, DLContext{kDLCPU, 0});
    int64_t* ptr_array_data = static_cast<int64_t*>(ptr_array->data);
    for (size_t i = 0; i < rst.size(); ++i) {
      Graph* ptr = new Graph();
      *ptr = std::move(rst[i]);
      ptr_array_data[i] = reinterpret_cast<std::intptr_t>(ptr);
    }
    *rv = ptr_array;
  });

TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLDisjointPartitionBySizes")
.set_body([] (TVMArgs args, TVMRetValue* rv) {
    GraphHandle ghandle = args[0];
    const Graph* gptr = static_cast<Graph*>(ghandle);
    const IdArray sizes = IdArray::FromDLPack(CreateTmpDLManagedTensor(args[1]));
    std::vector<Graph>&& rst = GraphOp::DisjointPartitionBySizes(gptr, sizes);
    // return the pointer array as an integer array
    const int64_t len = rst.size();
    NDArray ptr_array = NDArray::Empty({len}, DLDataType{kDLInt, 64, 1}, DLContext{kDLCPU, 0});
    int64_t* ptr_array_data = static_cast<int64_t*>(ptr_array->data);
    for (size_t i = 0; i < rst.size(); ++i) {
      Graph* ptr = new Graph();
      *ptr = std::move(rst[i]);
      ptr_array_data[i] = reinterpret_cast<std::intptr_t>(ptr);
    }
    *rv = ptr_array;
  });
Minjie Wang's avatar
Minjie Wang committed
328
}  // namespace dgl