This is an automated email from the ASF dual-hosted git repository.

haibin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/master by this push:
     new a7d17a4  add subgraph adjacency operator. (#13396)
a7d17a4 is described below

commit a7d17a42a08e6006605533a6dc2a3873040efca1
Author: BullDemonKing <[email protected]>
AuthorDate: Thu Nov 29 03:20:47 2018 +0800

    add subgraph adjacency operator. (#13396)
    
    * add adjacency.
    
    * fix lint.
    
    * add GPU impl.
    
    * retrigger
    
    * address comments.
    
    * Update dgl_graph.cc
---
 src/operator/contrib/dgl_graph-inl.h    | 68 +++++++++++++++++++++++++++++++
 src/operator/contrib/dgl_graph.cc       | 72 +++++++++++++++++++++++++++++++--
 src/operator/contrib/dgl_graph.cu       | 29 +++++++++++++
 tests/python/unittest/test_dgl_graph.py |  9 +++++
 4 files changed, 174 insertions(+), 4 deletions(-)

diff --git a/src/operator/contrib/dgl_graph-inl.h 
b/src/operator/contrib/dgl_graph-inl.h
new file mode 100644
index 0000000..f31071b
--- /dev/null
+++ b/src/operator/contrib/dgl_graph-inl.h
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef MXNET_OPERATOR_CONTRIB_DGL_GRAPH_INL_H_
+#define MXNET_OPERATOR_CONTRIB_DGL_GRAPH_INL_H_
+
+#include <dmlc/logging.h>
+#include <dmlc/parameter.h>
+#include <mxnet/operator.h>
+#include <mxnet/ndarray.h>
+#include <map>
+#include <algorithm>
+#include <vector>
+#include <string>
+#include <utility>
+#include "../operator_common.h"
+#include "../mxnet_op.h"
+#include "../mshadow_op.h"
+#include "../tensor/init_op.h"
+
+namespace mxnet {
+namespace op {
+
+template<typename xpu>
+void DGLAdjacencyForwardEx(const nnvm::NodeAttrs& attrs,
+                           const OpContext& ctx,
+                           const std::vector<NDArray>& inputs,
+                           const std::vector<OpReqType>& req,
+                           const std::vector<NDArray>& outputs) {
+  CHECK_EQ(inputs.size(), 1U);
+  CHECK_EQ(outputs.size(), 1U);
+  CHECK_EQ(req.size(), 1U);
+  CHECK_EQ(inputs[0].storage_type(), kCSRStorage);
+  CHECK_EQ(outputs[0].storage_type(), kCSRStorage);
+  CHECK_EQ(req[0], kWriteTo);
+  const TBlob &in_idx = inputs[0].aux_data(csr::kIdx);
+  const TBlob &in_indptr = inputs[0].aux_data(csr::kIndPtr);
+
+  outputs[0].CheckAndAllocData(in_idx.shape_);
+  outputs[0].CheckAndAllocAuxData(csr::kIdx, in_idx.shape_);
+  outputs[0].CheckAndAllocAuxData(csr::kIndPtr, in_indptr.shape_);
+
+  mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
+  Fill<false>(s, outputs[0].data(), req[0], 1.0);
+  mxnet_op::copy(s, outputs[0].aux_data(csr::kIdx), in_idx);
+  mxnet_op::copy(s, outputs[0].aux_data(csr::kIndPtr), in_indptr);
+}
+
+}  // namespace op
+}  // namespace mxnet
+
+#endif  // MXNET_OPERATOR_CONTRIB_DGL_GRAPH_INL_H_
diff --git a/src/operator/contrib/dgl_graph.cc 
b/src/operator/contrib/dgl_graph.cc
index bf54ed3..d9bcdd4 100644
--- a/src/operator/contrib/dgl_graph.cc
+++ b/src/operator/contrib/dgl_graph.cc
@@ -24,13 +24,10 @@
 #include <mxnet/operator_util.h>
 #include <dmlc/logging.h>
 #include <dmlc/optional.h>
-#include "../operator_common.h"
 #include "../elemwise_op_common.h"
 #include "../../imperative/imperative_utils.h"
 #include "../subgraph_op_common.h"
-#include "../mshadow_op.h"
-#include "../mxnet_op.h"
-#include "../tensor/init_op.h"
+#include "./dgl_graph-inl.h"
 
 namespace mxnet {
 namespace op {
@@ -459,6 +456,73 @@ The storage type of ``edge_id`` output depends on storage 
types of inputs
 .add_argument("u", "NDArray-or-Symbol", "u ndarray")
 .add_argument("v", "NDArray-or-Symbol", "v ndarray");
 
+///////////////////////// DGL Adjacency ///////////////////////////
+
+inline bool DGLAdjacencyShape(const nnvm::NodeAttrs& attrs,
+                              std::vector<TShape>* in_attrs,
+                              std::vector<TShape>* out_attrs) {
+  CHECK_EQ(in_attrs->size(), 1U);
+  CHECK_EQ(out_attrs->size(), 1U);
+
+  SHAPE_ASSIGN_CHECK(*out_attrs, 0, in_attrs->at(0));
+  SHAPE_ASSIGN_CHECK(*in_attrs, 0, out_attrs->at(0));
+  return out_attrs->at(0).ndim() != 0U && out_attrs->at(0).Size() != 0U;
+}
+
+inline bool DGLAdjacencyType(const nnvm::NodeAttrs& attrs,
+                             std::vector<int>* in_attrs,
+                             std::vector<int>* out_attrs) {
+  CHECK_EQ(in_attrs->size(), 1U);
+  CHECK_EQ(out_attrs->size(), 1U);
+  CHECK_EQ(in_attrs->at(0), mshadow::kInt64);
+  TYPE_ASSIGN_CHECK(*out_attrs, 0, mshadow::kFloat32);
+  return out_attrs->at(0) != -1;
+}
+
+inline bool DGLAdjacencyStorageType(const nnvm::NodeAttrs& attrs,
+                                    const int dev_mask,
+                                    DispatchMode* dispatch_mode,
+                                    std::vector<int>* in_attrs,
+                                    std::vector<int>* out_attrs) {
+  CHECK_EQ(in_attrs->size(), 1U) << "Only works for 2d arrays";
+  CHECK_EQ(out_attrs->size(), 1U);
+  int& out_stype = out_attrs->at(0);
+  bool dispatched = storage_type_assign(&out_stype, kCSRStorage,
+                                        dispatch_mode, 
DispatchMode::kFComputeEx);
+  if (!dispatched) {
+    LOG(ERROR) << "Cannot dispatch output storage type: " << 
common::stype_string(out_stype)
+        << ". dgl_adjacency only works for csr matrices";
+  }
+  return dispatched;
+}
+
+NNVM_REGISTER_OP(_contrib_dgl_adjacency)
+.describe(R"code(This operator converts a CSR matrix whose values are edge Ids
+to an adjacency matrix whose values are ones. The output CSR matrix always has
+the data value of float32.
+Example::
+
+  x = [[ 1, 0, 0 ],
+       [ 0, 2, 0 ],
+       [ 0, 0, 3 ]]
+  dgl_adjacency(x) =
+      [[ 1, 0, 0 ],
+       [ 0, 1, 0 ],
+       [ 0, 0, 1 ]]
+
+)code" ADD_FILELINE)
+.set_num_inputs(1)
+.set_num_outputs(1)
+.set_attr<nnvm::FListInputNames>("FListInputNames",
+  [](const NodeAttrs& attrs) {
+    return std::vector<std::string>{"data"};
+  })
+.set_attr<nnvm::FInferShape>("FInferShape", DGLAdjacencyShape)
+.set_attr<nnvm::FInferType>("FInferType", DGLAdjacencyType)
+.set_attr<FInferStorageType>("FInferStorageType", DGLAdjacencyStorageType)
+.set_attr<FComputeEx>("FComputeEx<cpu>", DGLAdjacencyForwardEx<cpu>)
+.add_argument("data", "NDArray-or-Symbol", "Input ndarray");
+
 
 }  // namespace op
 }  // namespace mxnet
diff --git a/src/operator/contrib/dgl_graph.cu 
b/src/operator/contrib/dgl_graph.cu
new file mode 100644
index 0000000..336e9d4
--- /dev/null
+++ b/src/operator/contrib/dgl_graph.cu
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "dgl_graph-inl.h"
+
+namespace mxnet {
+namespace op {
+
+NNVM_REGISTER_OP(_contrib_dgl_adjacency)
+.set_attr<FComputeEx>("FComputeEx<gpu>", DGLAdjacencyForwardEx<gpu>);
+
+}  // namespace op
+}  // namespace mxnet
diff --git a/tests/python/unittest/test_dgl_graph.py 
b/tests/python/unittest/test_dgl_graph.py
index 774f811..1d758b9 100644
--- a/tests/python/unittest/test_dgl_graph.py
+++ b/tests/python/unittest/test_dgl_graph.py
@@ -75,6 +75,15 @@ def test_subgraph():
             v2 = vertices[subv2]
             assert sp_g[v1, v2] == sp_subg[subv1, subv2]
 
+def test_adjacency():
+    sp_g, g = generate_graph(100)
+    adj = mx.nd.contrib.dgl_adjacency(g)
+    assert adj.dtype == np.float32
+    assert adj.shape == g.shape
+    assert_array_equal(adj.indptr, g.indptr)
+    assert_array_equal(adj.indices, g.indices)
+    assert_array_equal(adj.data, mx.nd.ones(shape=g.indices.shape))
+
 if __name__ == "__main__":
     import nose
     nose.runmodule()

Reply via email to