You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by zh...@apache.org on 2019/06/13 03:06:58 UTC
[incubator-mxnet] branch master updated: Make MXNDArrayFromDLPack
backward compatible (#15227)
This is an automated email from the ASF dual-hosted git repository.
zhasheng 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 a862270 Make MXNDArrayFromDLPack backward compatible (#15227)
a862270 is described below
commit a862270beb2d796c1ba311183f7f4a766a18ad6c
Author: Anirudh Subramanian <an...@ufl.edu>
AuthorDate: Wed Jun 12 20:06:13 2019 -0700
Make MXNDArrayFromDLPack backward compatible (#15227)
* Upgrade archive utility and add back FC improvement
This reverts commit 65434886f6caa7210ed3ff39cd4e950c023d8328.
* Make MXNDArrayFromDLPack C API backward compatible
* Fix to comment
* Add tests for dlpack
* Revert "Upgrade archive utility and add back FC improvement"
This reverts commit 40beeb2a7453f262e2820ff8faa6621abf81a88d.
* Fix C API call
---
include/mxnet/c_api.h | 22 +++++++++++++++--
python/mxnet/ndarray/ndarray.py | 4 +--
src/c_api/c_api.cc | 7 +++++-
tests/python/unittest/test_dlpack.py | 48 ++++++++++++++++++++++++++++++++++++
4 files changed, 76 insertions(+), 5 deletions(-)
diff --git a/include/mxnet/c_api.h b/include/mxnet/c_api.h
index 1b1c10e..2d5122c 100644
--- a/include/mxnet/c_api.h
+++ b/include/mxnet/c_api.h
@@ -809,7 +809,8 @@ MXNET_DLL int MXNDArrayToDLPack(NDArrayHandle handle,
DLManagedTensorHandle *out_dlpack);
/*!
-* \brief Create a NDArray backed by a dlpack tensor.
+* \brief DEPRECATED. Use MXNDArrayFromDLPackEx instead.
+
*
* This allows us to create a NDArray using the memory
* allocated by an external deep learning framework
@@ -823,10 +824,27 @@ MXNET_DLL int MXNDArrayToDLPack(NDArrayHandle handle,
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXNDArrayFromDLPack(DLManagedTensorHandle dlpack,
- const bool transient_handle,
NDArrayHandle *out_handle);
/*!
+* \brief Create a NDArray backed by a dlpack tensor.
+*
+* This allows us to create a NDArray using the memory
+* allocated by an external deep learning framework
+* that is DLPack compatible.
+*
+* The memory is retained until the NDArray went out of scope.
+*
+* \param dlpack the pointer of the input DLManagedTensor
+* \param transient_handle whether the handle will be destructed before calling the deleter
+* \param out_handle pointer holder to get pointer of NDArray
+* \return 0 when success, -1 when failure happens
+*/
+MXNET_DLL int MXNDArrayFromDLPackEx(DLManagedTensorHandle dlpack,
+ const bool transient_handle,
+ NDArrayHandle *out_handle);
+
+/*!
* \brief Delete a dlpack tensor
* \param dlpack the pointer of the input DLManagedTensor
* \return 0 when success, -1 when failure happens
diff --git a/python/mxnet/ndarray/ndarray.py b/python/mxnet/ndarray/ndarray.py
index 4b717e2..7e21dae 100644
--- a/python/mxnet/ndarray/ndarray.py
+++ b/python/mxnet/ndarray/ndarray.py
@@ -4156,7 +4156,7 @@ def from_dlpack(dlpack):
assert ctypes.pythonapi.PyCapsule_IsValid(dlpack, _c_str_dltensor), ValueError(
'Invalid DLPack Tensor. DLTensor capsules can be consumed only once.')
dlpack_handle = ctypes.c_void_p(ctypes.pythonapi.PyCapsule_GetPointer(dlpack, _c_str_dltensor))
- check_call(_LIB.MXNDArrayFromDLPack(dlpack_handle, False, ctypes.byref(handle)))
+ check_call(_LIB.MXNDArrayFromDLPackEx(dlpack_handle, False, ctypes.byref(handle)))
# Rename PyCapsule (DLPack)
ctypes.pythonapi.PyCapsule_SetName(dlpack, _c_str_used_dltensor)
# delete the deleter of the old dlpack
@@ -4269,5 +4269,5 @@ def from_numpy(ndarray, zero_copy=True):
ndarray.flags['WRITEABLE'] = False
c_obj = _make_dl_managed_tensor(ndarray)
handle = NDArrayHandle()
- check_call(_LIB.MXNDArrayFromDLPack(ctypes.byref(c_obj), True, ctypes.byref(handle)))
+ check_call(_LIB.MXNDArrayFromDLPackEx(ctypes.byref(c_obj), True, ctypes.byref(handle)))
return NDArray(handle=handle)
diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc
index f5d72d5..a9a49b0 100644
--- a/src/c_api/c_api.cc
+++ b/src/c_api/c_api.cc
@@ -562,8 +562,13 @@ int MXNDArrayToDLPack(NDArrayHandle handle,
}
int MXNDArrayFromDLPack(DLManagedTensorHandle dlpack,
- const bool transient_handle,
NDArrayHandle *out_handle) {
+ return MXNDArrayFromDLPackEx(dlpack, false, out_handle);
+}
+
+int MXNDArrayFromDLPackEx(DLManagedTensorHandle dlpack,
+ const bool transient_handle,
+ NDArrayHandle *out_handle) {
API_BEGIN();
*out_handle = new NDArray(NDArray::FromDLPack(
static_cast<DLManagedTensor*>(dlpack),
diff --git a/tests/python/unittest/test_dlpack.py b/tests/python/unittest/test_dlpack.py
new file mode 100644
index 0000000..fb64f8d
--- /dev/null
+++ b/tests/python/unittest/test_dlpack.py
@@ -0,0 +1,48 @@
+# 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.
+
+import ctypes
+import mxnet as mx
+from mxnet.base import NDArrayHandle, _LIB, c_str, check_call
+from mxnet.test_utils import assert_almost_equal
+
+def test_from_dlpack_backward_compatibility():
+ def from_dlpack_old(dlpack):
+
+ PyCapsuleDestructor = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
+ _c_str_dltensor = c_str('dltensor')
+ _c_str_used_dltensor = c_str('used_dltensor')
+ handle = NDArrayHandle()
+ dlpack = ctypes.py_object(dlpack)
+ assert ctypes.pythonapi.PyCapsule_IsValid(dlpack, _c_str_dltensor), ValueError(
+ 'Invalid DLPack Tensor. DLTensor capsules can be consumed only once.')
+ dlpack_handle = ctypes.c_void_p(ctypes.pythonapi.PyCapsule_GetPointer(dlpack, _c_str_dltensor))
+ check_call(_LIB.MXNDArrayFromDLPack(dlpack_handle, ctypes.byref(handle)))
+ # Rename PyCapsule (DLPack)
+ ctypes.pythonapi.PyCapsule_SetName(dlpack, _c_str_used_dltensor)
+ # delete the deleter of the old dlpack
+ ctypes.pythonapi.PyCapsule_SetDestructor(dlpack, None)
+ return mx.nd.NDArray(handle=handle)
+
+ x = mx.nd.ones((2,3))
+ y = mx.nd.to_dlpack_for_read(x)
+ z = from_dlpack_old(y)
+ assert_almost_equal(x.asnumpy(), z.asnumpy(), rtol=1e-5, atol=1e-5)
+
+if __name__ == '__main__':
+ import nose
+ nose.runmodule()