You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by li...@apache.org on 2020/05/06 15:52:40 UTC

[incubator-mxnet] branch master updated: [numpy] fix np.random.normal/gumbel/logistic ffi (#18247)

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

liuyizhi 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 c415ce6  [numpy] fix np.random.normal/gumbel/logistic ffi (#18247)
c415ce6 is described below

commit c415ce60fcd9ee55226327f8fbb8513156852a8a
Author: Yiyan66 <57...@users.noreply.github.com>
AuthorDate: Wed May 6 23:51:40 2020 +0800

    [numpy] fix np.random.normal/gumbel/logistic ffi (#18247)
    
    * issue 18242
    
    * add test
    
    Co-authored-by: Ubuntu <ub...@ip-172-31-18-97.us-east-2.compute.internal>
---
 .../operator/numpy/random/np_location_scale_op.cc  | 39 +++++++++++-----------
 src/api/operator/random/np_normal_op.cc            | 10 +++---
 tests/python/unittest/test_numpy_op.py             |  9 +++++
 3 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/src/api/operator/numpy/random/np_location_scale_op.cc b/src/api/operator/numpy/random/np_location_scale_op.cc
index d4702fc..d163b0b 100644
--- a/src/api/operator/numpy/random/np_location_scale_op.cc
+++ b/src/api/operator/numpy/random/np_location_scale_op.cc
@@ -23,6 +23,7 @@
  */
 #include <mxnet/api_registry.h>
 #include <mxnet/runtime/packed_func.h>
+#include <vector>
 #include "../../utils.h"
 #include "../../../../operator/numpy/random/np_location_scale_op.h"
 
@@ -47,7 +48,7 @@ MXNET_REGISTER_API("_npi.gumbel")
   if (args[2].type_code() == kDLInt) {
       param.size = Tuple<int>(1, args[2].operator int64_t());
   } else if (args[2].type_code() == kNull) {
-      param.size = Tuple<int>({1});
+      param.size = dmlc::optional<mxnet::Tuple<int>>();
   } else {
       param.size = Tuple<int>(args[2].operator ObjectRef());
   }
@@ -58,7 +59,7 @@ MXNET_REGISTER_API("_npi.gumbel")
   NDArray** outputs = out == nullptr ? nullptr : &out;
   int num_outputs = out != nullptr;
   int scalar = scalar_number(args);
-  NDArray* inputs[2];
+  std::vector<NDArray*> inputs;
   int num_inputs = 0;
   if (scalar == 2) {
     param.loc = args[0].operator double();
@@ -66,24 +67,24 @@ MXNET_REGISTER_API("_npi.gumbel")
   } else if (scalar == 0) {
     param.loc = dmlc::nullopt;
     param.scale = dmlc::nullopt;
-    inputs[0] = args[0].operator mxnet::NDArray*();
-    inputs[1] = args[1].operator mxnet::NDArray*();
+    inputs.push_back(args[0].operator mxnet::NDArray*());
+    inputs.push_back(args[1].operator mxnet::NDArray*());
     num_inputs = 2;
   } else {
     if (args[0].type_code() == kDLFloat || args[0].type_code() == kDLInt) {
-      param.loc = dmlc::nullopt;
-      param.scale = args[1].operator double();
-      inputs[0] = args[0].operator mxnet::NDArray*();
-    } else {
       param.loc = args[0].operator double();
       param.scale = dmlc::nullopt;
-      inputs[0] = args[1].operator mxnet::NDArray*();
+      inputs.push_back(args[1].operator mxnet::NDArray*());
+    } else {
+      param.loc = dmlc::nullopt;
+      param.scale = args[1].operator double();
+      inputs.push_back(args[0].operator mxnet::NDArray*());
     }
     num_inputs = 1;
   }
   attrs.parsed = std::move(param);
   SetAttrDict<op::NumpyLocationScaleParam>(&attrs);
-  auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs,
+  auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs.data(),
                           &num_outputs, outputs);
   if (out) {
     *ret = PythonArg(4);
@@ -113,7 +114,7 @@ MXNET_REGISTER_API("_npi.logistic")
   NDArray** outputs = out == nullptr ? nullptr : &out;
   int num_outputs = out != nullptr;
   int scalar = scalar_number(args);
-  NDArray* inputs[2];
+  std::vector<NDArray*> inputs;
   int num_inputs = 0;
   if (scalar == 2) {
     param.loc = args[0].operator double();
@@ -121,24 +122,24 @@ MXNET_REGISTER_API("_npi.logistic")
   } else if (scalar == 0) {
     param.loc = dmlc::nullopt;
     param.scale = dmlc::nullopt;
-    inputs[0] = args[0].operator mxnet::NDArray*();
-    inputs[1] = args[1].operator mxnet::NDArray*();
+    inputs.push_back(args[0].operator mxnet::NDArray*());
+    inputs.push_back(args[1].operator mxnet::NDArray*());
     num_inputs = 2;
   } else {
     if (args[0].type_code() == kDLFloat || args[0].type_code() == kDLInt) {
-      param.loc = dmlc::nullopt;
-      param.scale = args[1].operator double();
-      inputs[0] = args[0].operator mxnet::NDArray*();
-    } else {
       param.loc = args[0].operator double();
       param.scale = dmlc::nullopt;
-      inputs[0] = args[1].operator mxnet::NDArray*();
+      inputs.push_back(args[1].operator mxnet::NDArray*());
+    } else {
+      param.loc = dmlc::nullopt;
+      param.scale = args[1].operator double();
+      inputs.push_back(args[0].operator mxnet::NDArray*());
     }
     num_inputs = 1;
   }
   attrs.parsed = std::move(param);
   SetAttrDict<op::NumpyLocationScaleParam>(&attrs);
-  auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs,
+  auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs.data(),
                           &num_outputs, outputs);
   if (out) {
     *ret = PythonArg(4);
diff --git a/src/api/operator/random/np_normal_op.cc b/src/api/operator/random/np_normal_op.cc
index a45936d..6a477ed 100644
--- a/src/api/operator/random/np_normal_op.cc
+++ b/src/api/operator/random/np_normal_op.cc
@@ -48,6 +48,7 @@ MXNET_REGISTER_API("_npi.normal")
       num_inputs = 1;
       param.loc = args[0].operator double();
       param.scale = dmlc::nullopt;
+      inputs.push_back(args[1].operator mxnet::NDArray*());
     }
   } else {
     if (args[1].type_code() == kDLFloat || args[1].type_code() == kDLInt) {
@@ -55,14 +56,14 @@ MXNET_REGISTER_API("_npi.normal")
       num_inputs = 1;
       param.loc = dmlc::nullopt;
       param.scale = args[1].operator double();
+      inputs.push_back(args[0].operator mxnet::NDArray*());
     } else {
       // nither 'loc' or 'scale' is numeric types
       num_inputs = 2;
+      inputs.push_back(args[0].operator mxnet::NDArray*());
+      inputs.push_back(args[1].operator mxnet::NDArray*());
     }
   }
-  for (int i = 0; i < num_inputs; ++i) {
-    inputs.push_back(args[i].operator mxnet::NDArray*());
-  }
   if (args[2].type_code() == kNull) {
     param.size = dmlc::optional<mxnet::Tuple<int>>();
   } else if (args[2].type_code() == kDLInt ||
@@ -85,7 +86,8 @@ MXNET_REGISTER_API("_npi.normal")
   NDArray** outputs = out == nullptr ? nullptr : &out;
   int num_outputs = out != nullptr;
   SetAttrDict<op::NumpyNormalParam>(&attrs);
-  auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs.data(), &num_outputs, outputs);
+  auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs.data(),
+                          &num_outputs, outputs);
   if (out) {
     *ret = PythonArg(5);
   } else {
diff --git a/tests/python/unittest/test_numpy_op.py b/tests/python/unittest/test_numpy_op.py
index 712a846..c82e05b 100644
--- a/tests/python/unittest/test_numpy_op.py
+++ b/tests/python/unittest/test_numpy_op.py
@@ -3939,6 +3939,15 @@ def test_np_random_grad():
                 assert scale.grad.shape == shape2
                 assert_almost_equal(loc.grad.asnumpy().sum(), _np.ones(out_shape).sum(), rtol=1e-3, atol=1e-5)
 
+        for (loc, scale) in [(2, (2,3)), ((2,3), 2), ((2,3), (2,3))]:
+            if isinstance(loc, tuple):
+                loc = np.ones(loc)
+            if isinstance(scale, tuple):
+                scale = np.ones(scale)
+            mx_out = getattr(np.random, op_name)(loc, scale)
+            np_out = getattr(_np.random, op_name)(loc, scale)
+            assert_almost_equal(mx_out.asnumpy().shape, np_out.shape)
+
 
 @with_seed()
 @use_np