Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dgl
Commits
4baed964
Unverified
Commit
4baed964
authored
Oct 10, 2018
by
GaiYu0
Committed by
GitHub
Oct 10, 2018
Browse files
Merge branch 'cpp' into line-graph
parents
885f5e73
7603b8c3
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
135 additions
and
37 deletions
+135
-37
include/dgl/runtime/ndarray.h
include/dgl/runtime/ndarray.h
+6
-1
python/dgl/_ffi/_ctypes/ndarray.py
python/dgl/_ffi/_ctypes/ndarray.py
+12
-4
python/dgl/backend/pytorch.py
python/dgl/backend/pytorch.py
+20
-2
python/dgl/ndarray.py
python/dgl/ndarray.py
+1
-18
python/dgl/utils.py
python/dgl/utils.py
+12
-12
src/runtime/ndarray.cc
src/runtime/ndarray.cc
+7
-0
tests/pytorch/test_index.py
tests/pytorch/test_index.py
+77
-0
No files found.
include/dgl/runtime/ndarray.h
View file @
4baed964
...
...
@@ -249,9 +249,14 @@ struct NDArray::Container {
friend
class
RPCWrappedFunc
;
/*!
* \brief The shape container,
* can be used
used
for shape data.
* can be used for shape data.
*/
std
::
vector
<
int64_t
>
shape_
;
/*!
* \brief The stride container,
* can be used for stride data.
*/
std
::
vector
<
int64_t
>
stride_
;
/*! \brief The internal array object */
std
::
atomic
<
int
>
ref_counter_
{
0
};
};
...
...
python/dgl/_ffi/_ctypes/ndarray.py
View file @
4baed964
...
...
@@ -24,6 +24,10 @@ def _from_dlpack(dltensor):
dltensor
=
ctypes
.
py_object
(
dltensor
)
if
ctypes
.
pythonapi
.
PyCapsule_IsValid
(
dltensor
,
_c_str_dltensor
):
ptr
=
ctypes
.
pythonapi
.
PyCapsule_GetPointer
(
dltensor
,
_c_str_dltensor
)
# XXX(minjie): The below cast should be unnecessary given the code to
# set restype of PyCapsule calls. But weirdly, this does not
# work out always.
ptr
=
ctypes
.
cast
(
ptr
,
ctypes
.
c_void_p
)
handle
=
TVMArrayHandle
()
check_call
(
_LIB
.
TVMArrayFromDLPack
(
ptr
,
ctypes
.
byref
(
handle
)))
ctypes
.
pythonapi
.
PyCapsule_SetName
(
dltensor
,
_c_str_used_dltensor
)
...
...
@@ -36,8 +40,12 @@ def _dlpack_deleter(pycapsule):
pycapsule
=
ctypes
.
cast
(
pycapsule
,
ctypes
.
py_object
)
if
ctypes
.
pythonapi
.
PyCapsule_IsValid
(
pycapsule
,
_c_str_dltensor
):
ptr
=
ctypes
.
pythonapi
.
PyCapsule_GetPointer
(
pycapsule
,
_c_str_dltensor
)
# XXX(minjie): The below cast should be unnecessary given the code to
# set restype of PyCapsule calls. But weirdly, this does not
# work out always.
ptr
=
ctypes
.
cast
(
ptr
,
ctypes
.
c_void_p
)
_LIB
.
TVMDLManagedTensorCallDeleter
(
ptr
)
ctypes
.
pythonapi
.
PyCapsule_SetDestructor
(
dltensor
,
TVMPyCapsuleDestructor
(
0
))
ctypes
.
pythonapi
.
PyCapsule_SetDestructor
(
pycapsule
,
TVMPyCapsuleDestructor
(
0
))
_c_dlpack_deleter
=
TVMPyCapsuleDestructor
(
_dlpack_deleter
)
...
...
@@ -72,9 +80,9 @@ class NDArrayBase(object):
-------
dlpack : DLPack tensor view of the array data
"""
handle
=
ctypes
.
c_void_p
()
check_call
(
_LIB
.
TVMArrayToDLPack
(
self
.
handle
,
ctypes
.
byref
(
handle
)))
return
ctypes
.
pythonapi
.
PyCapsule_New
(
handle
,
_c_str_dltensor
,
_c_dlpack_deleter
)
ptr
=
ctypes
.
c_void_p
()
check_call
(
_LIB
.
TVMArrayToDLPack
(
self
.
handle
,
ctypes
.
byref
(
ptr
)))
return
ctypes
.
pythonapi
.
PyCapsule_New
(
ptr
,
_c_str_dltensor
,
_c_dlpack_deleter
)
def
_make_array
(
handle
,
is_view
):
...
...
python/dgl/backend/pytorch.py
View file @
4baed964
...
...
@@ -3,6 +3,7 @@ from __future__ import absolute_import
import
ctypes
import
scipy
as
sp
import
torch
as
th
from
torch.utils
import
dlpack
from
.._ffi.base
import
_LIB
,
check_call
,
c_array
from
.._ffi.runtime_ctypes
import
TVMType
,
TVMContext
,
TVMArray
...
...
@@ -134,8 +135,24 @@ def _typestr(arr_dtype):
else
:
raise
RuntimeError
(
'Unsupported data type:'
,
arr_dtype
)
def
astvmarray
(
arr_data
):
"""Return a TVMArray representation of the underlying data."""
def
zerocopy_to_dlpack
(
arr
):
"""Return a dlpack compatible array using zero copy."""
return
dlpack
.
to_dlpack
(
arr
)
def
zerocopy_from_dlpack
(
dlpack_arr
):
"""Return a tensor using zero copy."""
return
dlpack
.
from_dlpack
(
dlpack_arr
)
def
zerocopy_to_numpy
(
arr
):
"""Return a numpy array that shares the data."""
# TODO(minjie): zero copy
return
arr
.
numpy
()
def
zerocopy_from_numpy
(
np_data
):
"""Return a tensor that shares the numpy data."""
return
th
.
from_numpy
(
np_data
)
'''
data = arr_data
assert data.is_contiguous()
arr = TVMArray()
...
...
@@ -147,3 +164,4 @@ def astvmarray(arr_data):
arr.ndim = len(shape)
arr.ctx = get_context(data)
return arr
'''
python/dgl/ndarray.py
View file @
4baed964
...
...
@@ -72,7 +72,7 @@ def array(arr, ctx=cpu(0)):
arr
=
_np
.
array
(
arr
)
return
empty
(
arr
.
shape
,
arr
.
dtype
,
ctx
).
copyfrom
(
arr
)
def
from_numpy
(
np_data
):
def
zerocopy_
from_numpy
(
np_data
):
"""Create an array that shares the given numpy data.
Parameters
...
...
@@ -89,21 +89,4 @@ def from_numpy(np_data):
handle
=
ctypes
.
pointer
(
arr
)
return
NDArray
(
handle
,
is_view
=
True
)
def
from_user_tensor
(
data
):
"""Create an array that shares the given user tensor data.
Parameters
----------
data : F.Tensor
The user tensor data.
Returns
-------
NDArray
The array
"""
arr
=
F
.
astvmarray
(
data
)
handle
=
ctypes
.
pointer
(
arr
)
return
NDArray
(
handle
,
is_view
=
True
)
_set_class_ndarray
(
NDArray
)
python/dgl/utils.py
View file @
4baed964
...
...
@@ -35,6 +35,7 @@ class Index(object):
self
.
_list_data
=
np
.
array
(
data
).
astype
(
np
.
int64
)
except
:
raise
ValueError
(
'Error index data: %s'
%
str
(
data
))
self
.
_user_tensor_data
[
nd
.
cpu
()]
=
F
.
zerocopy_from_numpy
(
self
.
_list_data
)
def
tolist
(
self
):
"""Convert to a python-list compatible object."""
...
...
@@ -42,18 +43,20 @@ class Index(object):
if
self
.
_dgl_tensor_data
is
not
None
:
self
.
_list_data
=
self
.
_dgl_tensor_data
.
asnumpy
()
else
:
assert
len
(
self
.
_user_tensor_data
)
>
0
data
=
next
(
iter
(
self
.
_user_tensor_data
.
values
()))
self
.
_list_data
=
F
.
asnumpy
(
data
)
data
=
self
.
tousertensor
()
self
.
_list_data
=
F
.
zerocopy_to_numpy
(
data
)
return
self
.
_list_data
def
tousertensor
(
self
,
ctx
=
None
):
"""Convert to user tensor (defined in `backend`)."""
if
len
(
self
.
_user_tensor_data
)
==
0
:
self
.
_user_tensor_data
[
nd
.
cpu
()]
=
F
.
from_numpy
(
self
.
tolist
())
if
ctx
is
None
:
ctx
=
nd
.
cpu
()
if
len
(
self
.
_user_tensor_data
)
==
0
:
# zero copy from dgl tensor
dl
=
self
.
_dgl_tensor_data
.
to_dlpack
()
self
.
_user_tensor_data
[
nd
.
cpu
()]
=
F
.
zerocopy_from_dlpack
(
dl
)
if
ctx
not
in
self
.
_user_tensor_data
:
# copy from cpu to another device
data
=
next
(
iter
(
self
.
_user_tensor_data
.
values
()))
self
.
_user_tensor_data
[
ctx
]
=
F
.
to_context
(
data
,
ctx
)
return
self
.
_user_tensor_data
[
ctx
]
...
...
@@ -61,13 +64,10 @@ class Index(object):
def
todgltensor
(
self
):
"""Convert to dgl.NDArray."""
if
self
.
_dgl_tensor_data
is
None
:
if
self
.
_list_data
is
not
None
:
# create a view ndarray from numpy
self
.
_dgl_tensor_data
=
nd
.
from_numpy
(
self
.
_list_data
)
else
:
# create a view ndarray from user tensor
self
.
_dgl_tensor_data
=
nd
.
from_user_tensor
(
self
.
tousertensor
(
ctx
=
nd
.
cpu
()))
# zero copy from user tensor
tsor
=
self
.
tousertensor
()
dl
=
F
.
zerocopy_to_dlpack
(
tsor
)
self
.
_dgl_tensor_data
=
nd
.
from_dlpack
(
dl
)
return
self
.
_dgl_tensor_data
def
__iter__
(
self
):
...
...
src/runtime/ndarray.cc
View file @
4baed964
...
...
@@ -80,6 +80,13 @@ struct NDArray::Internal {
data
->
shape_
=
std
::
move
(
shape
);
data
->
dl_tensor
.
shape
=
dmlc
::
BeginPtr
(
data
->
shape_
);
data
->
dl_tensor
.
ndim
=
static_cast
<
int
>
(
data
->
shape_
.
size
());
// setup stride (this should be optional, but some framework
// does not support NULL stride and thus will crash the program).
data
->
stride_
.
resize
(
data
->
dl_tensor
.
ndim
,
1
);
for
(
int
i
=
data
->
dl_tensor
.
ndim
-
2
;
i
>=
0
;
--
i
)
{
data
->
stride_
[
i
]
=
data
->
shape_
[
i
+
1
]
*
data
->
stride_
[
i
+
1
];
}
data
->
dl_tensor
.
strides
=
dmlc
::
BeginPtr
(
data
->
stride_
);
// setup dtype
data
->
dl_tensor
.
dtype
=
dtype
;
// setup ctx
...
...
tests/pytorch/test_index.py
0 → 100644
View file @
4baed964
import
dgl
import
dgl.ndarray
as
nd
from
dgl.utils
import
toindex
import
numpy
as
np
import
torch
as
th
from
torch.utils
import
dlpack
def
test_dlpack
():
# test dlpack conversion.
def
nd2th
():
ans
=
np
.
array
([[
1.
,
1.
,
1.
,
1.
],
[
0.
,
0.
,
0.
,
0.
],
[
0.
,
0.
,
0.
,
0.
]])
x
=
nd
.
array
(
np
.
zeros
((
3
,
4
),
dtype
=
np
.
float32
))
dl
=
x
.
to_dlpack
()
y
=
dlpack
.
from_dlpack
(
dl
)
y
[
0
]
=
1
assert
np
.
allclose
(
x
.
asnumpy
(),
ans
)
def
th2nd
():
ans
=
np
.
array
([[
1.
,
1.
,
1.
,
1.
],
[
0.
,
0.
,
0.
,
0.
],
[
0.
,
0.
,
0.
,
0.
]])
x
=
th
.
zeros
((
3
,
4
))
dl
=
dlpack
.
to_dlpack
(
x
)
y
=
nd
.
from_dlpack
(
dl
)
x
[
0
]
=
1
assert
np
.
allclose
(
y
.
asnumpy
(),
ans
)
nd2th
()
th2nd
()
def
test_index
():
ans
=
np
.
ones
((
10
,),
dtype
=
np
.
int64
)
*
10
# from np data
data
=
np
.
ones
((
10
,),
dtype
=
np
.
int64
)
*
10
idx
=
toindex
(
data
)
y1
=
idx
.
tolist
()
y2
=
idx
.
tousertensor
().
numpy
()
y3
=
idx
.
todgltensor
().
asnumpy
()
assert
np
.
allclose
(
ans
,
y1
)
assert
np
.
allclose
(
ans
,
y2
)
assert
np
.
allclose
(
ans
,
y3
)
# from list
data
=
[
10
]
*
10
idx
=
toindex
(
data
)
y1
=
idx
.
tolist
()
y2
=
idx
.
tousertensor
().
numpy
()
y3
=
idx
.
todgltensor
().
asnumpy
()
assert
np
.
allclose
(
ans
,
y1
)
assert
np
.
allclose
(
ans
,
y2
)
assert
np
.
allclose
(
ans
,
y3
)
# from torch
data
=
th
.
ones
((
10
,),
dtype
=
th
.
int64
)
*
10
idx
=
toindex
(
data
)
y1
=
idx
.
tolist
()
y2
=
idx
.
tousertensor
().
numpy
()
y3
=
idx
.
todgltensor
().
asnumpy
()
assert
np
.
allclose
(
ans
,
y1
)
assert
np
.
allclose
(
ans
,
y2
)
assert
np
.
allclose
(
ans
,
y3
)
# from dgl.NDArray
data
=
dgl
.
ndarray
.
array
(
np
.
ones
((
10
,),
dtype
=
np
.
int64
)
*
10
)
idx
=
toindex
(
data
)
y1
=
idx
.
tolist
()
y2
=
idx
.
tousertensor
().
numpy
()
y3
=
idx
.
todgltensor
().
asnumpy
()
assert
np
.
allclose
(
ans
,
y1
)
assert
np
.
allclose
(
ans
,
y2
)
assert
np
.
allclose
(
ans
,
y3
)
if
__name__
==
'__main__'
:
test_dlpack
()
test_index
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment