You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by lx...@apache.org on 2017/07/07 15:58:34 UTC
[21/50] [abbrv] incubator-mxnet-test git commit: [R] fix concat for
symbol and NDArray. close #6650 (#6696)
[R] fix concat for symbol and NDArray. close #6650 (#6696)
Project: http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/commit/bfb79bd2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/tree/bfb79bd2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/diff/bfb79bd2
Branch: refs/heads/master
Commit: bfb79bd2d7adf2fdde8266fe62565f6b3ff6ec40
Parents: aec0460
Author: Qiang Kou (KK) <qk...@qkou.info>
Authored: Thu Jun 29 19:17:54 2017 -0700
Committer: GitHub <no...@github.com>
Committed: Thu Jun 29 19:17:54 2017 -0700
----------------------------------------------------------------------
Jenkinsfile | 2 +
R-package/R/symbol.R | 40 +++++++++-
R-package/src/export.cc | 2 +-
R-package/src/ndarray.cc | 10 ++-
R-package/src/symbol.cc | 8 ++
R-package/src/symbol.h | 6 ++
R-package/tests/testthat/test_ndarray.R | 106 +++++++++++++++++++++------
R-package/tests/testthat/test_symbol.R | 57 ++++++++++----
8 files changed, 190 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/Jenkinsfile
----------------------------------------------------------------------
diff --git a/Jenkinsfile b/Jenkinsfile
index cd6ab31..881fef5 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -277,6 +277,7 @@ stage('Unit Test') {
init_git()
unpack_lib('cpu')
timeout(time: max_time, unit: 'MINUTES') {
+ sh "${docker_run} cpu rm -rf .Renviron"
sh "${docker_run} cpu mkdir -p /workspace/ut-r-cpu/site-library"
sh "${docker_run} cpu make rpkg USE_BLAS=openblas R_LIBS=/workspace/ut-r-cpu/site-library"
sh "${docker_run} cpu R CMD INSTALL --library=/workspace/ut-r-cpu/site-library mxnet_current_r.tar.gz"
@@ -291,6 +292,7 @@ stage('Unit Test') {
init_git()
unpack_lib('gpu')
timeout(time: max_time, unit: 'MINUTES') {
+ sh "${docker_run} cpu rm -rf .Renviron"
sh "${docker_run} gpu mkdir -p /workspace/ut-r-gpu/site-library"
sh "${docker_run} gpu make rpkg USE_BLAS=openblas R_LIBS=/workspace/ut-r-gpu/site-library"
sh "${docker_run} gpu R CMD INSTALL --library=/workspace/ut-r-gpu/site-library mxnet_current_r.tar.gz"
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/R/symbol.R
----------------------------------------------------------------------
diff --git a/R-package/R/symbol.R b/R-package/R/symbol.R
index 091a646..f222c55 100644
--- a/R-package/R/symbol.R
+++ b/R-package/R/symbol.R
@@ -32,14 +32,32 @@ mx.symbol.Group <- function(...) {
#' @return out The result mx.symbol
#'
#' @export
-mx.symbol.Concat <- function(data, num.args, dim = NULL, name = NULL) {
+mx.symbol.concat <- function(data, num.args, dim = NULL, name = NULL) {
data[['num.args']] <- num.args
if(!is.null(dim)) data[['dim']] <- dim
if(!is.null(name)) data[['name']] <- name
- mx.varg.symbol.Concat(data)
+ mx.varg.symbol.concat(data)
+}
+
+#' Perform an feature concat on channel dim (dim 1) over all the inputs.
+#'
+#' @param data list, required
+#' List of tensors to concatenate
+#' @param num.args int, required
+#' Number of inputs to be concated.
+#' @param dim int, optional, default='1'
+#' the dimension to be concated.
+#' @param name string, optional
+#' Name of the resulting symbol.
+#' @return out The result mx.symbol
+#'
+#' @export
+mx.symbol.Concat <- function(data, num.args, dim = NULL, name = NULL) {
+ warning("mx.symbol.Concat is deprecated. Use mx.symbol.concat instead.")
+ mx.symbol.concat(data, num.args, dim, name)
}
#' Save an mx.symbol object
@@ -123,6 +141,24 @@ mx.apply <- function(x, ...) {
x$apply(list(...))
}
+#' Get a symbol that contains all the internals
+#' @param x The input symbol
+#'
+#' @export
+internals <- function(x) {
+ if (!is.MXSymbol(x)) stop("only for MXSymbol type")
+ x$get.internals()
+}
+
+#' Gets a new grouped symbol whose output contains inputs to output nodes of the original symbol.
+#' @param x The input symbol
+#'
+#' @export
+children <- function(x) {
+ if (!is.MXSymbol(x)) stop("only for MXSymbol type")
+ x$get.children()
+}
+
#' Get the outputs of a symbol.
#' @param x The input symbol
#'
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/src/export.cc
----------------------------------------------------------------------
diff --git a/R-package/src/export.cc b/R-package/src/export.cc
index ed8f4bc..0e77c1c 100644
--- a/R-package/src/export.cc
+++ b/R-package/src/export.cc
@@ -93,7 +93,7 @@ void Exporter::Export(const std::string& path) {
std::string fname = Rcpp::as<std::string>(func_names[i]);
// skip internal functions
if (fname.find("internal.") != std::string::npos) continue;
- if (fname == "mx.varg.symbol.Concat") continue;
+ if (fname == "mx.varg.symbol.Concat" || fname == "mx.varg.symbol.concat") continue;
Rcpp::List func_info(scope->get_function(fname));
std::string docstr = Rcpp::as<std::string>(func_info[2]);
if (docstr.find("@export") == std::string::npos) continue;
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/src/ndarray.cc
----------------------------------------------------------------------
diff --git a/R-package/src/ndarray.cc b/R-package/src/ndarray.cc
index c2bfe0c..d270a30 100644
--- a/R-package/src/ndarray.cc
+++ b/R-package/src/ndarray.cc
@@ -398,10 +398,16 @@ SEXP NDArrayFunction::operator() (SEXP* args) {
std::vector<const char*> param_vals;
std::vector<NDArrayHandle> out_args;
-
for (mx_uint i = 0; i < arg_names_.size() - 1; ++i) {
if (arg_nd_array_[i]) {
- nd_args.push_back(NDArray(args[i])->handle);
+ if (TYPEOF(args[i]) == 22) {
+ nd_args.push_back(NDArray(args[i])->handle);
+ } else if (TYPEOF(args[i]) == 19) {
+ Rcpp::List data_lst = Rcpp::as<Rcpp::List>(args[i]);
+ for (size_t k = 0; k < data_lst.size(); k++) {
+ nd_args.push_back(NDArray((SEXP)data_lst[k])->handle);
+ }
+ }
} else {
if (args[i] != R_NilValue) {
param_keys.push_back(arg_names_[i].c_str());
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/src/symbol.cc
----------------------------------------------------------------------
diff --git a/R-package/src/symbol.cc b/R-package/src/symbol.cc
index aa901ff..b5d6eca 100644
--- a/R-package/src/symbol.cc
+++ b/R-package/src/symbol.cc
@@ -134,6 +134,12 @@ Symbol::RObjectType Symbol::GetInternals() const {
return Symbol::RObject(out);
}
+Symbol::RObjectType Symbol::GetChildren() const {
+ SymbolHandle out;
+ MX_CALL(MXSymbolGetChildren(handle_, &out));
+ return Symbol::RObject(out);
+}
+
Symbol::RObjectType Symbol::GetOutput(mx_uint index) const {
SymbolHandle out;
MX_CALL(MXSymbolGetOutput(handle_, index - 1, &out));
@@ -344,6 +350,8 @@ void Symbol::InitRcppModule() {
"List the auxiliary state names of the symbol")
.method("get.internals", &Symbol::GetInternals,
"Get a symbol that contains all the internals")
+ .method("get.children", &Symbol::GetChildren,
+ "Get a symbol that contains all the children")
.method("get.output", &Symbol::GetOutput,
"Get index-th output symbol of current one")
.method("[[", &Symbol::GetOutput,
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/src/symbol.h
----------------------------------------------------------------------
diff --git a/R-package/src/symbol.h b/R-package/src/symbol.h
index a361bdf..4bfdebf 100644
--- a/R-package/src/symbol.h
+++ b/R-package/src/symbol.h
@@ -70,6 +70,12 @@ class Symbol {
*/
RObjectType GetInternals() const;
/*!
+ * \brief Gets a new grouped symbol whose output contains
+ * inputs to output nodes of the original symbol.
+ * \return The children of the symbol.
+ */
+ RObjectType GetChildren() const;
+ /*!
* \brief Get index-th outputs of the symbol.
* \param symbol The symbol
* \param index the Index of the output.
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/tests/testthat/test_ndarray.R
----------------------------------------------------------------------
diff --git a/R-package/tests/testthat/test_ndarray.R b/R-package/tests/testthat/test_ndarray.R
index a6b85da..e574ea7 100644
--- a/R-package/tests/testthat/test_ndarray.R
+++ b/R-package/tests/testthat/test_ndarray.R
@@ -6,34 +6,39 @@ test_that("element-wise calculation for vector", {
x = 1:10
mat = mx.nd.array(as.array(x), mx.cpu(0))
expect_equal(x, as.array(mat))
- expect_equal(x+1, as.array(mat+1))
- expect_equal(x-10, as.array(mat-10))
- expect_equal(x*20, as.array(mat*20))
- expect_equal(x/3, as.array(mat/3), tolerance = 1e-5)
- expect_equal(-1-x, as.array(-1-mat))
- expect_equal(-5/x, as.array(-5/mat), tolerance = 1e-5)
- expect_equal(x+x, as.array(mat+mat))
- expect_equal(x/x, as.array(mat/mat))
- expect_equal(x*x, as.array(mat*mat))
- expect_equal(x-x, as.array(mat-mat))
- expect_equal(as.array(1-mat), as.array(1-mat))
+ expect_equal(x + 1, as.array(mat + 1))
+ expect_equal(x - 10, as.array(mat - 10))
+ expect_equal(x * 20, as.array(mat * 20))
+ expect_equal(x / 3, as.array(mat / 3), tolerance = 1e-5)
+ expect_equal(-1 - x, as.array(-1 - mat))
+ expect_equal(-5 / x, as.array(-5 / mat), tolerance = 1e-5)
+ expect_equal(x + x, as.array(mat + mat))
+ expect_equal(x / x, as.array(mat / mat))
+ expect_equal(x * x, as.array(mat * mat))
+ expect_equal(x - x, as.array(mat - mat))
+ expect_equal(as.array(1 - mat), as.array(1 - mat))
+
+ x <- runif(10,-10, 10)
+ nd = mx.nd.array(as.array(x))
+ expect_equal(sqrt(abs(x)), as.array(mx.nd.sqrt(mx.nd.abs(nd))), tolerance = 1e-6)
+ expect_equal(x ^ 2, as.array(mx.nd.square(nd)), tolerance = 1e-6)
})
-test_that("element-wise calculation for matrix", {
+test_that("element-wise calculation for matrix", {
x = matrix(1:4, 2, 2)
mat = mx.nd.array(as.array(x), mx.cpu(0))
expect_equal(x, as.array(mat))
- expect_equal(x+1, as.array(mat+1))
- expect_equal(x-10, as.array(mat-10))
- expect_equal(x*20, as.array(mat*20))
- expect_equal(x/3, as.array(mat/3), tolerance = 1e-5)
- expect_equal(-1-x, as.array(-1-mat))
- expect_equal(-5/x, as.array(-5/mat), tolerance = 1e-5)
- expect_equal(x+x, as.array(mat+mat))
- expect_equal(x/x, as.array(mat/mat))
- expect_equal(x*x, as.array(mat*mat))
- expect_equal(x-x, as.array(mat-mat))
- expect_equal(as.array(1-mat), as.array(1-mat))
+ expect_equal(x + 1, as.array(mat + 1))
+ expect_equal(x - 10, as.array(mat - 10))
+ expect_equal(x * 20, as.array(mat * 20))
+ expect_equal(x / 3, as.array(mat / 3), tolerance = 1e-5)
+ expect_equal(-1 - x, as.array(-1 - mat))
+ expect_equal(-5 / x, as.array(-5 / mat), tolerance = 1e-5)
+ expect_equal(x + x, as.array(mat + mat))
+ expect_equal(x / x, as.array(mat / mat))
+ expect_equal(x * x, as.array(mat * mat))
+ expect_equal(x - x, as.array(mat - mat))
+ expect_equal(as.array(1 - mat), as.array(1 - mat))
})
test_that("ndarray ones, zeros, save and load", {
@@ -48,3 +53,58 @@ test_that("ndarray ones, zeros, save and load", {
expect_equal(as.array(mat), as.array(mat2[[1]]))
file.remove('temp.mat')
})
+
+test_that("ndarray concatenate", {
+ shapes <- matrix(c(2, 3, 4, 2, 2, 2, 4, 2, 2, 1, 4, 2), nrow = 3, byrow = TRUE)
+ array_r <- apply(shapes, 2, function(s) { runif(s, -10, 10) })
+ array_nd <- apply(array_r, 1, function(s) { mx.nd.array(matrix(s, nrow = 1)) })
+ array_nd_concat <- mx.nd.concat(data = array_nd, num_args = 3, dim = 1)
+ expect_equal(array_r, as.matrix(array_nd_concat), tolerance = 1e-6)
+
+ x1 <- mx.nd.array(c(1:24))
+ x2 <- mx.nd.array(c(25:48))
+ x3 <- mx.nd.concat(data = c(x1, x2), num_args = 2, dim = 0)
+ expect_equal(c(1:48), as.array(x3))
+ expect_equal(dim(x3), 48)
+
+ x1 <- array(1:24, dim = c(4, 3, 2))
+ x2 <- array(25:48, dim = c(4, 3, 2))
+ x3 <- c(1:4, 25:28, 5:8, 29:32, 9:12, 33:36, 13:16, 37:40, 17:20, 41:44, 21:24, 45:48)
+ y1 <- mx.nd.array(x1)
+ y2 <- mx.nd.array(x2)
+ y3 <- mx.nd.concat(data = c(y1, y2), num_args = 2, dim = 2)
+ expect_equal(dim(y3), c(8, 3, 2))
+ expect_equal(as.array(y3), array(x3, dim = c(8, 3, 2)))
+})
+
+test_that("ndarray clip", {
+ nd <- mx.nd.array(runif(10,-10, 10))
+ nd2 <- mx.nd.clip(nd,-2, 3)
+ arr <- as.array(nd2)
+ expect_equal(arr >= -2 | arr <= 3, rep(TRUE, length(arr)))
+})
+
+test_that("ndarray dot", {
+ a <- matrix(runif(12), nrow = 3)
+ b <- matrix(runif(20), nrow = 4)
+ c <- a %*% b
+
+ A <- mx.nd.array(t(a))
+ B <- mx.nd.array(t(b))
+ C <- mx.nd.dot(A, B)
+
+ expect_equal(c, t(as.matrix(C)), tolerance = 1e-6)
+})
+
+test_that("ndarray crop", {
+ x <- mx.nd.ones(c(2, 3, 4))
+ y <- mx.nd.crop(x, begin = c(0, 0, 0), end = c(2, 1, 3))
+ expect_equal(array(1, dim = c(2, 1, 3)), as.array(y))
+
+ z <- mx.nd.zeros(c(2, 1, 3))
+ x <- mxnet:::mx.nd.internal.crop.assign(x, z, begin = c(0, 0, 0), end = c(2, 1, 3))
+ arr_x <- array(1, dim = dim(x))
+ arr_x[c(1:2), 1 , c(1:3)] <- 0
+
+ expect_equal(as.array(x), arr_x)
+})
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mxnet-test/blob/bfb79bd2/R-package/tests/testthat/test_symbol.R
----------------------------------------------------------------------
diff --git a/R-package/tests/testthat/test_symbol.R b/R-package/tests/testthat/test_symbol.R
index be38762..656d146 100644
--- a/R-package/tests/testthat/test_symbol.R
+++ b/R-package/tests/testthat/test_symbol.R
@@ -4,17 +4,17 @@ context("symbol")
test_that("basic symbol operation", {
data = mx.symbol.Variable('data')
- net1 = mx.symbol.FullyConnected(data=data, name='fc1', num_hidden=10)
- net1 = mx.symbol.FullyConnected(data=net1, name='fc2', num_hidden=100)
+ net1 = mx.symbol.FullyConnected(data = data, name = 'fc1', num_hidden = 10)
+ net1 = mx.symbol.FullyConnected(data = net1, name = 'fc2', num_hidden = 100)
expect_equal(arguments(net1), c('data', 'fc1_weight', 'fc1_bias', 'fc2_weight', 'fc2_bias'))
expect_equal(outputs(net1), 'fc2_output')
- net2 = mx.symbol.FullyConnected(name='fc3', num_hidden=10)
- net2 = mx.symbol.Activation(data=net2, act_type='relu')
- net2 = mx.symbol.FullyConnected(data=net2, name='fc4', num_hidden=20)
+ net2 = mx.symbol.FullyConnected(name = 'fc3', num_hidden = 10)
+ net2 = mx.symbol.Activation(data = net2, act_type = 'relu')
+ net2 = mx.symbol.FullyConnected(data = net2, name = 'fc4', num_hidden = 20)
- composed = mx.apply(net2, fc3_data=net1, name='composed')
+ composed = mx.apply(net2, fc3_data = net1, name = 'composed')
expect_equal(arguments(composed), c('data', 'fc1_weight', 'fc1_bias', 'fc2_weight', 'fc2_bias', 'fc3_weight', 'fc3_bias', 'fc4_weight', 'fc4_bias'))
expect_equal(outputs(composed), 'composed_output')
@@ -25,17 +25,35 @@ test_that("basic symbol operation", {
test_that("symbol internal", {
data = mx.symbol.Variable('data')
- oldfc = mx.symbol.FullyConnected(data=data, name='fc1', num_hidden=10)
- net1 = mx.symbol.FullyConnected(data=oldfc, name='fc2', num_hidden=100)
+ oldfc = mx.symbol.FullyConnected(data = data, name = 'fc1', num_hidden = 10)
+ net1 = mx.symbol.FullyConnected(data = oldfc, name = 'fc2', num_hidden = 100)
expect_equal(arguments(net1), c("data", "fc1_weight", "fc1_bias", "fc2_weight", "fc2_bias"))
- internal = net1$get.internals()
+ internal = internals(net1)
fc1 = internal[[match("fc1_output", internal$outputs)]]
expect_equal(arguments(fc1), arguments(oldfc))
})
+test_that("symbol children", {
+ data = mx.symbol.Variable('data')
+ oldfc = mx.symbol.FullyConnected(data = data,
+ name = 'fc1',
+ num_hidden = 10)
+ net1 = mx.symbol.FullyConnected(data = oldfc, name = 'fc2', num_hidden = 100)
+
+ expect_equal(outputs(children(net1)), c('fc1_output', 'fc2_weight', 'fc2_bias'))
+ expect_equal(outputs(children(children(net1))), c('data', 'fc1_weight', 'fc1_bias'))
+
+ net2 = net1$get.children()
+ expect_equal(net2[[match('fc2_weight', net2$outputs)]]$arguments, 'fc2_weight')
+
+ data = mx.symbol.Variable('data')
+ sliced = mx.symbol.SliceChannel(data, num_outputs = 3, name = 'slice')
+ expect_equal(outputs(children(sliced)), 'data')
+})
+
test_that("symbol infer type", {
num_hidden = 128
num_dim = 64
@@ -43,10 +61,10 @@ test_that("symbol infer type", {
data = mx.symbol.Variable('data')
prev = mx.symbol.Variable('prevstate')
- x2h = mx.symbol.FullyConnected(data=data, name='x2h', num_hidden=num_hidden)
- h2h = mx.symbol.FullyConnected(data=prev, name='h2h', num_hidden=num_hidden)
+ x2h = mx.symbol.FullyConnected(data = data, name = 'x2h', num_hidden = num_hidden)
+ h2h = mx.symbol.FullyConnected(data = prev, name = 'h2h', num_hidden = num_hidden)
- out = mx.symbol.Activation(data=mx.symbol.elemwise_add(x2h, h2h), name='out', act_type='relu')
+ out = mx.symbol.Activation(data = mx.symbol.elemwise_add(x2h, h2h), name = 'out', act_type = 'relu')
# shape inference will fail because information is not available for h2h
ret = mx.symbol.infer.shape(out, data = c(num_dim, num_sample))
@@ -56,7 +74,7 @@ test_that("symbol infer type", {
test_that("symbol save/load", {
data <- mx.symbol.Variable("data")
- fc1 <- mx.symbol.FullyConnected(data, num_hidden=1)
+ fc1 <- mx.symbol.FullyConnected(data, num_hidden = 1)
lro <- mx.symbol.LinearRegressionOutput(fc1)
mx.symbol.save(lro, "tmp_r_sym.json")
data2 = mx.symbol.load("tmp_r_sym.json")
@@ -78,3 +96,16 @@ test_that("symbol attributes access", {
expect_equal(y$attributes$`__shape__`, str)
})
+test_that("symbol concat", {
+ s1 <- mx.symbol.Variable("data1")
+ s2 <- mx.symbol.Variable("data2")
+ s3 <- mx.symbol.concat(data = c(s1, s2), num.args = 2, name = "concat")
+ expect_equal(outputs(s3), "concat_output")
+ expect_equal(outputs(children(s3)), c("data1", "data2"))
+ expect_equal(arguments(s3), c("data1", "data2"))
+
+ s4 <- mx.symbol.Concat(data = c(s1, s2), num.args = 2, name = "concat")
+ expect_equal(outputs(s3), outputs(s4))
+ expect_equal(outputs(children(s3)), outputs(children(s4)))
+ expect_equal(arguments(s3), arguments(s4))
+})