dmlc--dgl
653428bdc7
* [Kernel] Minigun integration and fused kernel support (#519) * kernel interface * add minigun * Add cuda build * functors * working on binary elewise * binary reduce * change kernel interface * WIP * wip * fix minigun * compile * binary reduce kernels * compile * simple test passed * more reducers * fix thrust problem * fix cmake * fix cmake; add proper guard for atomic * WIP: bcast * WIP * bcast kernels * update to new minigun pass-by-value practice * broadcasting dim * add copy src and copy edge * fix linking * fix none array problem * fix copy edge * add device_type and device_id to backend operator * cache csr adj, remove cache for adjmat and incmat * custom ops in backend and pytorch impl * change dgl-mg kernel python interface * add id_mapping var * clean up plus v2e spmv schedule * spmv schedule & clean up fall back * symbolic message and reduce func, remove bundle func * new executors * new backend interface for dgl kernels and pytorch impl * minor fix * fix * fix docstring, comments, func names * nodeflow * fix message id mapping and bugs... * pytorch test case & fix * backward binary reduce * fix bug * WIP: cusparse * change to int32 csr for cusparse workaround * disable cusparse * change back to int64 * broadcasting backward * cusparse; WIP: add rev_csr * unit test for kernels * pytorch backward with dgl kernel * edge softmax * fix backward * improve softmax * cache edge on device * cache mappings on device * fix partial forward code * cusparse done * copy_src_sum with cusparse * rm id getter * reduce grad for broadcast * copy edge reduce backward * kernel unit test for broadcasting * full kernel unit test * add cpu kernels * edge softmax unit test * missing ref * fix compile and small bugs * fix bug in bcast * Add backward both * fix torch utests * expose infershape * create out tensor in python * fix c++ lint * [Kernel] Add GPU utest and kernel utest (#524) * fix gpu utest * cuda utest runnable * temp disable test nodeflow; unified test for kernel * cuda test kernel done * [Kernel] Update kernel branch (#550) * [Model] add multiprocessing training with sampling. (#484) * reorganize sampling code. * add multi-process training. * speed up gcn_cv * fix graphsage_cv. * add new API in graph store. * update barrier impl. * support both local and distributed training. * fix multiprocess train. * fix. * fix barrier. * add script for loading data. * multiprocessing sampling. * accel training. * replace pull with spmv for speedup. * nodeflow copy from parent with context. * enable GPU. * fix a bug in graph store. * enable multi-GPU training. * fix lint. * add comments. * rename to run_store_server.py * fix gcn_cv. * fix a minor bug in sampler. * handle error better in graph store. * improve graphsage_cv for distributed mode. * update README. * fix. * update. * [Tutorial] add sampling tutorial. (#522) * add sampling tutorial. * add readme * update author list. * fix indent in the code. * rename the file. * update tutorial. * fix the last API. * update image. * [BUGFIX] fix the problems in the sampling tutorial. (#523) * add index. * update. * update tutorial. * fix gpu utest * cuda utest runnable * temp disable test nodeflow; unified test for kernel * cuda test kernel done * Fixing typo in JTNN after interface change (#536) * [BugFix] Fix getting src and dst id of ALL edges in NodeFlow.apply_block (#515) * [Bug Fix] Fix inplace op at backend (#546) * Fix inplace operation * fix line seprator * [Feature] Add batch and unbatch for immutable graph (#539) * Add batch and unbatch for immutable graph * fix line seprator * fix lintr * remove unnecessary include * fix code review * [BUGFix] Improve multi-processing training (#526) * fix. * add comment. * remove. * temp fix. * initialize for shared memory. * fix graphsage. * fix gcn. * add more unit tests. * add more tests. * avoid creating shared-memory exclusively. * redefine remote initializer. * improve initializer. * fix unit test. * fix lint. * fix lint. * initialize data in the graph store server properly. * fix test. * fix test. * fix test. * small fix. * add comments. * cleanup server. * test graph store with a random port. * print. * print to stderr. * test1 * test2 * remove comment. * adjust the initializer signature. * [API] update graph store API. (#549) * add init_ndata and init_edata in DGLGraph. * adjust SharedMemoryGraph API. * print warning. * fix comment. * update example * fix. * fix examples. * add unit tests. * add comments. * [Refactor] Immutable graph index (#543) * WIP * header * WIP .cc * WIP * transpose * wip * immutable graph .h and .cc * WIP: nodeflow.cc * compile * remove all tmp dl managed ctx; they caused refcount issue * one simple test * WIP: testing * test_graph * fix graph index * fix bug in sampler; pass pytorch utest * WIP on mxnet * fix lint * fix mxnet unittest w/ unfortunate workaround * fix msvc * fix lint * SliceRows and test_nodeflow * resolve reviews * resolve reviews * try fix win ci * try fix win ci * poke win ci again * poke * lazy multigraph flag; stackoverflow error * revert node subgraph test * lazy object * try fix win build * try fix win build * poke ci * fix build script * fix compile * add a todo * fix reviews * fix compile * [Kernel] Update kernel branch (#576) * [Model] add multiprocessing training with sampling. (#484) * reorganize sampling code. * add multi-process training. * speed up gcn_cv * fix graphsage_cv. * add new API in graph store. * update barrier impl. * support both local and distributed training. * fix multiprocess train. * fix. * fix barrier. * add script for loading data. * multiprocessing sampling. * accel training. * replace pull with spmv for speedup. * nodeflow copy from parent with context. * enable GPU. * fix a bug in graph store. * enable multi-GPU training. * fix lint. * add comments. * rename to run_store_server.py * fix gcn_cv. * fix a minor bug in sampler. * handle error better in graph store. * improve graphsage_cv for distributed mode. * update README. * fix. * update. * [Tutorial] add sampling tutorial. (#522) * add sampling tutorial. * add readme * update author list. * fix indent in the code. * rename the file. * update tutorial. * fix the last API. * update image. * [BUGFIX] fix the problems in the sampling tutorial. (#523) * add index. * update. * update tutorial. * fix gpu utest * cuda utest runnable * temp disable test nodeflow; unified test for kernel * cuda test kernel done * Fixing typo in JTNN after interface change (#536) * [BugFix] Fix getting src and dst id of ALL edges in NodeFlow.apply_block (#515) * [Bug Fix] Fix inplace op at backend (#546) * Fix inplace operation * fix line seprator * [Feature] Add batch and unbatch for immutable graph (#539) * Add batch and unbatch for immutable graph * fix line seprator * fix lintr * remove unnecessary include * fix code review * [BUGFix] Improve multi-processing training (#526) * fix. * add comment. * remove. * temp fix. * initialize for shared memory. * fix graphsage. * fix gcn. * add more unit tests. * add more tests. * avoid creating shared-memory exclusively. * redefine remote initializer. * improve initializer. * fix unit test. * fix lint. * fix lint. * initialize data in the graph store server properly. * fix test. * fix test. * fix test. * small fix. * add comments. * cleanup server. * test graph store with a random port. * print. * print to stderr. * test1 * test2 * remove comment. * adjust the initializer signature. * [API] update graph store API. (#549) * add init_ndata and init_edata in DGLGraph. * adjust SharedMemoryGraph API. * print warning. * fix comment. * update example * fix. * fix examples. * add unit tests. * add comments. * [Refactor] Immutable graph index (#543) * WIP * header * WIP .cc * WIP * transpose * wip * immutable graph .h and .cc * WIP: nodeflow.cc * compile * remove all tmp dl managed ctx; they caused refcount issue * one simple test * WIP: testing * test_graph * fix graph index * fix bug in sampler; pass pytorch utest * WIP on mxnet * fix lint * fix mxnet unittest w/ unfortunate workaround * fix msvc * fix lint * SliceRows and test_nodeflow * resolve reviews * resolve reviews * try fix win ci * try fix win ci * poke win ci again * poke * lazy multigraph flag; stackoverflow error * revert node subgraph test * lazy object * try fix win build * try fix win build * poke ci * fix build script * fix compile * add a todo * fix reviews * fix compile * all demo use python-3 (#555) * [DEMO] Reproduce numbers of distributed training in AMLC giant graph paper (#556) * update * update * update * update num_hops * fix bug * update * report numbers of distributed training in AMLC giant graph paper * [DEMO] Remove duplicate code for sampling (#557) * update * update * re-use single-machine code * update * use relative path * update * update * update * add __init__.py * add __init__.py * import sys, os * fix typo * update * [Perf] Improve performance of graph store. (#554) * fix. * use inplace. * move to shared memory graph store. * fix. * add more unit tests. * fix. * fix test. * fix test. * disable test. * fix. * [BUGIFX] fix a bug in edge_ids (#560) * add test. * fix compute. * fix test. * turn on test. * fix a bug. * add test. * fix. * disable test. * [DEMO] Add Pytorch demo for distributed sampler (#562) * update * update * update * add sender * update * remove duplicate cpde * [Test] Add gtest to project (#547) * add gtest module * add gtest * fix * Update CMakeLists.txt * Update README.md * [Perf] lazily create msg_index. (#563) * lazily create msg_index. * update test. * [BUGFIX] fix bugs for running GCN on giant graphs. (#561) * load mxnet csr. * enable load large csr. * fix * fix. * fix int overflow. * fix test. * [BugFix] Fix error when bfs_level = 0 in Entity Classification with RGCN (#559) * [DEMO] Update demo of distributed sampler (#564) * update * update * update demo * add network cpp test (#565) * Add unittest for C++ RPC (#566) * [CI] Fix CI for cpp test (#570) * fix CI for cpp test * update port number * [Docker] update docker image (#575) * update docker image * specify lint version * rm torch import from unified tests * [Kernel][Scheduler][MXNet] Scheduler for DGL kernels and MXNet backend support (#541) * [Model] add multiprocessing training with sampling. (#484) * reorganize sampling code. * add multi-process training. * speed up gcn_cv * fix graphsage_cv. * add new API in graph store. * update barrier impl. * support both local and distributed training. * fix multiprocess train. * fix. * fix barrier. * add script for loading data. * multiprocessing sampling. * accel training. * replace pull with spmv for speedup. * nodeflow copy from parent with context. * enable GPU. * fix a bug in graph store. * enable multi-GPU training. * fix lint. * add comments. * rename to run_store_server.py * fix gcn_cv. * fix a minor bug in sampler. * handle error better in graph store. * improve graphsage_cv for distributed mode. * update README. * fix. * update. * [Tutorial] add sampling tutorial. (#522) * add sampling tutorial. * add readme * update author list. * fix indent in the code. * rename the file. * update tutorial. * fix the last API. * update image. * [BUGFIX] fix the problems in the sampling tutorial. (#523) * add index. * update. * update tutorial. * fix gpu utest * cuda utest runnable * temp disable test nodeflow; unified test for kernel * cuda test kernel done * edge softmax module * WIP * Fixing typo in JTNN after interface change (#536) * mxnet backend support * improve reduce grad * add max to unittest backend * fix kernel unittest * [BugFix] Fix getting src and dst id of ALL edges in NodeFlow.apply_block (#515) * lint * lint * win build * [Bug Fix] Fix inplace op at backend (#546) * Fix inplace operation * fix line seprator * [Feature] Add batch and unbatch for immutable graph (#539) * Add batch and unbatch for immutable graph * fix line seprator * fix lintr * remove unnecessary include * fix code review * [BUGFix] Improve multi-processing training (#526) * fix. * add comment. * remove. * temp fix. * initialize for shared memory. * fix graphsage. * fix gcn. * add more unit tests. * add more tests. * avoid creating shared-memory exclusively. * redefine remote initializer. * improve initializer. * fix unit test. * fix lint. * fix lint. * initialize data in the graph store server properly. * fix test. * fix test. * fix test. * small fix. * add comments. * cleanup server. * test graph store with a random port. * print. * print to stderr. * test1 * test2 * remove comment. * adjust the initializer signature. * try * fix * fix * fix * fix * fix * try * test * test * test * try * try * try * test * fix * try gen_target * fix gen_target * fix msvc var_args expand issue * fix * [API] update graph store API. (#549) * add init_ndata and init_edata in DGLGraph. * adjust SharedMemoryGraph API. * print warning. * fix comment. * update example * fix. * fix examples. * add unit tests. * add comments. * [Refactor] Immutable graph index (#543) * WIP * header * WIP .cc * WIP * transpose * wip * immutable graph .h and .cc * WIP: nodeflow.cc * compile * remove all tmp dl managed ctx; they caused refcount issue * one simple test * WIP: testing * test_graph * fix graph index * fix bug in sampler; pass pytorch utest * WIP on mxnet * fix lint * fix mxnet unittest w/ unfortunate workaround * fix msvc * fix lint * SliceRows and test_nodeflow * resolve reviews * resolve reviews * try fix win ci * try fix win ci * poke win ci again * poke * lazy multigraph flag; stackoverflow error * revert node subgraph test * lazy object * try fix win build * try fix win build * poke ci * fix build script * fix compile * add a todo * fix reviews * fix compile * WIP * WIP * all demo use python-3 (#555) * ToImmutable and CopyTo * [DEMO] Reproduce numbers of distributed training in AMLC giant graph paper (#556) * update * update * update * update num_hops * fix bug * update * report numbers of distributed training in AMLC giant graph paper * [DEMO] Remove duplicate code for sampling (#557) * update * update * re-use single-machine code * update * use relative path * update * update * update * add __init__.py * add __init__.py * import sys, os * fix typo * update * [Perf] Improve performance of graph store. (#554) * fix. * use inplace. * move to shared memory graph store. * fix. * add more unit tests. * fix. * fix test. * fix test. * disable test. * fix. * [BUGIFX] fix a bug in edge_ids (#560) * add test. * fix compute. * fix test. * turn on test. * fix a bug. * add test. * fix. * disable test. * DGLRetValue DGLContext conversion * [DEMO] Add Pytorch demo for distributed sampler (#562) * update * update * update * add sender * update * remove duplicate cpde * [Test] Add gtest to project (#547) * add gtest module * add gtest * fix * Update CMakeLists.txt * Update README.md * Add support to convert immutable graph to 32 bits * [Perf] lazily create msg_index. (#563) * lazily create msg_index. * update test. * fix binary reduce following new minigun template * enable both int64 and int32 kernels * [BUGFIX] fix bugs for running GCN on giant graphs. (#561) * load mxnet csr. * enable load large csr. * fix * fix. * fix int overflow. * fix test. * new kernel interface done for CPU * docstring * rename & docstring * copy reduce and backward * [BugFix] Fix error when bfs_level = 0 in Entity Classification with RGCN (#559) * [DEMO] Update demo of distributed sampler (#564) * update * update * update demo * adapt cuda kernels to the new interface * add network cpp test (#565) * fix bug * Add unittest for C++ RPC (#566) * [CI] Fix CI for cpp test (#570) * fix CI for cpp test * update port number * [Docker] update docker image (#575) * update docker image * specify lint version * rm torch import from unified tests * remove pytorch-specific test_function * fix unittest * fix * fix unittest backend bug in converting tensor to numpy array * fix * mxnet version * [BUGFIX] fix for MXNet 1.5. (#552) * remove clone. * turn on numpy compatible. * Revert "remove clone." This reverts commit 17bbf76ed72ff178df6b3f35addc428048672457. * revert format changes * fix mxnet api name * revert mistakes in previous revert * roll back CI to 20190523 build * fix unittest * disable test_shared_mem_store.py for now * remove mxnet/test_specialization.py * sync win64 test script * fix lowercase * missing backend in gpu unit test * transpose to get forward graph * pass update all * add sanity check * passing test_specialization.py * fix and pass test_function * fix check * fix pytorch softmax * mxnet kernels * c++ lint * pylint * try * win build * fix * win * ci enable gpu build * init submodule recursively * backend docstring * try * test win dev * doc string * disable pytorch test_nn * try to fix windows issue * bug fixed, revert changes * [Test] fix CI. (#586) * disable unit test in mxnet tutorial. * retry socket connection. * roll back to set_np_compat * try to fix multi-processing test hangs when it fails. * fix test. * fix. * doc string * doc string and clean up * missing field in ctypes * fix node flow schedule and unit test * rename * pylint * copy from parent default context * fix unit test script * fix * demo bug in nodeflow gpu test * [Kernel][Bugfix] fix nodeflow bug (#604) * fix nodeflow bug * remove debug code * add build gtest option * fix cmake; fix graph index bug in spmv.py * remove clone * fix div rhs grad bug * [Kernel] Support full builtin method, edge softmax and unit tests (#605) * add full builtin support * unit test * unit test backend * edge softmax * apply edge with builtin * fix kernel unit test * disable mxnet test_shared_mem_store * gen builtin reduce * enable mxnet gpu unittest * revert some changes * docstring * add note for the hack * [Kernel][Unittest][CI] Fix MXNet GPU CI (#607) * update docker image for MXNet GPU CI * force all dgl graph input and output on CPU * fix gpu unittest * speedup compilation * add some comments * lint * add more comments * fix as requested * add some comments * comment * lint * lint * update pylint * fix as requested * lint * lint * lint * docstrings of python DGL kernel entries * disable lint warnings on arguments in kernel.py * fix docstring in scheduler * fix some bug in unittest; try again * Revert "Merge branch 'kernel' of github.com:zzhang-cn/dgl into kernel" This reverts commit 1d2299e68b004182ea6130b088de1f1122b18a49, reversing changes made to ddc97fbf1bec2b7815c0da7c74f7ecb2f428889b. * Revert "fix some bug in unittest; try again" This reverts commit ddc97fbf1bec2b7815c0da7c74f7ecb2f428889b. * more comprehensive kernel test * remove shape check in test_specialization
368 行
11 KiB
Python
368 行
11 KiB
Python
import numpy as np
|
|
from dgl.frame import Frame, FrameRef
|
|
from dgl.utils import Index, toindex
|
|
import backend as F
|
|
|
|
N = 10
|
|
D = 5
|
|
|
|
def check_fail(fn):
|
|
try:
|
|
fn()
|
|
return False
|
|
except:
|
|
return True
|
|
|
|
def create_test_data(grad=False):
|
|
c1 = F.randn((N, D))
|
|
c2 = F.randn((N, D))
|
|
c3 = F.randn((N, D))
|
|
if grad:
|
|
c1 = F.attach_grad(c1)
|
|
c2 = F.attach_grad(c2)
|
|
c3 = F.attach_grad(c3)
|
|
return {'a1' : c1, 'a2' : c2, 'a3' : c3}
|
|
|
|
def test_create():
|
|
data = create_test_data()
|
|
f1 = Frame(num_rows=N)
|
|
for k, v in data.items():
|
|
f1.update_column(k, v)
|
|
print(f1.schemes)
|
|
assert f1.keys() == set(data.keys())
|
|
assert f1.num_columns == 3
|
|
assert f1.num_rows == N
|
|
f2 = Frame(data)
|
|
assert f2.keys() == set(data.keys())
|
|
assert f2.num_columns == 3
|
|
assert f2.num_rows == N
|
|
f1.clear()
|
|
assert len(f1.schemes) == 0
|
|
assert f1.num_rows == 0
|
|
|
|
def test_column1():
|
|
# Test frame column getter/setter
|
|
data = create_test_data()
|
|
f = Frame(data)
|
|
assert f.num_rows == N
|
|
assert len(f) == 3
|
|
assert F.allclose(f['a1'].data, data['a1'])
|
|
f['a1'] = data['a2']
|
|
assert F.allclose(f['a2'].data, data['a2'])
|
|
# add a different length column should fail
|
|
def failed_add_col():
|
|
f['a4'] = F.zeros([N+1, D])
|
|
assert check_fail(failed_add_col)
|
|
# delete all the columns
|
|
del f['a1']
|
|
del f['a2']
|
|
assert len(f) == 1
|
|
del f['a3']
|
|
assert len(f) == 0
|
|
|
|
def test_column2():
|
|
# Test frameref column getter/setter
|
|
data = Frame(create_test_data())
|
|
f = FrameRef(data, toindex([3, 4, 5, 6, 7]))
|
|
assert f.num_rows == 5
|
|
assert len(f) == 3
|
|
assert F.allclose(f['a1'], F.narrow_row(data['a1'].data, 3, 8))
|
|
# set column should reflect on the referenced data
|
|
f['a1'] = F.zeros([5, D])
|
|
assert F.allclose(F.narrow_row(data['a1'].data, 3, 8), F.zeros([5, D]))
|
|
# add new partial column should fail with error initializer
|
|
f.set_initializer(lambda shape, dtype : assert_(False))
|
|
def failed_add_col():
|
|
f['a4'] = F.ones([5, D])
|
|
assert check_fail(failed_add_col)
|
|
|
|
def test_append1():
|
|
# test append API on Frame
|
|
data = create_test_data()
|
|
f1 = Frame()
|
|
f2 = Frame(data)
|
|
f1.append(data)
|
|
assert f1.num_rows == N
|
|
f1.append(f2)
|
|
assert f1.num_rows == 2 * N
|
|
c1 = f1['a1']
|
|
assert tuple(F.shape(c1.data)) == (2 * N, D)
|
|
truth = F.cat([data['a1'], data['a1']], 0)
|
|
assert F.allclose(truth, c1.data)
|
|
# append dict of different length columns should fail
|
|
f3 = {'a1' : F.zeros((3, D)), 'a2' : F.zeros((3, D)), 'a3' : F.zeros((2, D))}
|
|
def failed_append():
|
|
f1.append(f3)
|
|
assert check_fail(failed_append)
|
|
|
|
def test_append2():
|
|
# test append on FrameRef
|
|
data = Frame(create_test_data())
|
|
f = FrameRef(data)
|
|
assert f.is_contiguous()
|
|
assert f.is_span_whole_column()
|
|
assert f.num_rows == N
|
|
# append on the underlying frame should not reflect on the ref
|
|
data.append(data)
|
|
assert f.is_contiguous()
|
|
assert not f.is_span_whole_column()
|
|
assert f.num_rows == N
|
|
# append on the FrameRef should work
|
|
f.append(data)
|
|
assert not f.is_contiguous()
|
|
assert not f.is_span_whole_column()
|
|
assert f.num_rows == 3 * N
|
|
new_idx = list(range(N)) + list(range(2*N, 4*N))
|
|
assert F.array_equal(f._index.tousertensor(), F.copy_to(F.tensor(new_idx, dtype=F.int64), F.cpu()))
|
|
assert data.num_rows == 4 * N
|
|
|
|
def test_append3():
|
|
# test append on empty frame
|
|
f = Frame(num_rows=5)
|
|
data = {'h' : F.ones((3, 2))}
|
|
f.append(data)
|
|
assert f.num_rows == 8
|
|
ans = F.cat([F.zeros((5, 2)), F.ones((3, 2))], 0)
|
|
assert F.allclose(f['h'].data, ans)
|
|
# test append with new column
|
|
data = {'h' : 2 * F.ones((3, 2)), 'w' : 2 * F.ones((3, 2))}
|
|
f.append(data)
|
|
assert f.num_rows == 11
|
|
ans1 = F.cat([ans, 2 * F.ones((3, 2))], 0)
|
|
ans2 = F.cat([F.zeros((8, 2)), 2 * F.ones((3, 2))], 0)
|
|
assert F.allclose(f['h'].data, ans1)
|
|
assert F.allclose(f['w'].data, ans2)
|
|
|
|
def test_row1():
|
|
# test row getter/setter
|
|
data = create_test_data()
|
|
f = FrameRef(Frame(data))
|
|
|
|
# getter
|
|
# test non-duplicate keys
|
|
rowid = Index(F.tensor([0, 2]))
|
|
rows = f[rowid]
|
|
for k, v in rows.items():
|
|
assert tuple(F.shape(v)) == (len(rowid), D)
|
|
assert F.allclose(v, F.gather_row(data[k], F.tensor(rowid.tousertensor())))
|
|
# test duplicate keys
|
|
rowid = Index(F.tensor([8, 2, 2, 1]))
|
|
rows = f[rowid]
|
|
for k, v in rows.items():
|
|
assert tuple(F.shape(v)) == (len(rowid), D)
|
|
assert F.allclose(v, F.gather_row(data[k], F.tensor(rowid.tousertensor())))
|
|
|
|
# setter
|
|
rowid = Index(F.tensor([0, 2, 4]))
|
|
vals = {'a1' : F.zeros((len(rowid), D)),
|
|
'a2' : F.zeros((len(rowid), D)),
|
|
'a3' : F.zeros((len(rowid), D)),
|
|
}
|
|
f[rowid] = vals
|
|
for k, v in f[rowid].items():
|
|
assert F.allclose(v, F.zeros((len(rowid), D)))
|
|
|
|
# setting rows with new column should raise error with error initializer
|
|
f.set_initializer(lambda shape, dtype : assert_(False))
|
|
def failed_update_rows():
|
|
vals['a4'] = F.ones((len(rowid), D))
|
|
f[rowid] = vals
|
|
assert check_fail(failed_update_rows)
|
|
|
|
def test_row2():
|
|
# test row getter/setter autograd compatibility
|
|
data = create_test_data(grad=True)
|
|
f = FrameRef(Frame(data))
|
|
|
|
with F.record_grad():
|
|
# getter
|
|
c1 = f['a1']
|
|
# test non-duplicate keys
|
|
rowid = Index(F.tensor([0, 2]))
|
|
rows = f[rowid]
|
|
y = rows['a1']
|
|
F.backward(y, F.ones((len(rowid), D)))
|
|
assert F.allclose(F.grad(c1)[:,0], F.tensor([1., 0., 1., 0., 0., 0., 0., 0., 0., 0.]))
|
|
|
|
f['a1'] = F.attach_grad(f['a1'])
|
|
with F.record_grad():
|
|
c1 = f['a1']
|
|
# test duplicate keys
|
|
rowid = Index(F.tensor([8, 2, 2, 1]))
|
|
rows = f[rowid]
|
|
y = rows['a1']
|
|
F.backward(y, F.ones((len(rowid), D)))
|
|
assert F.allclose(F.grad(c1)[:,0], F.tensor([0., 1., 2., 0., 0., 0., 0., 0., 1., 0.]))
|
|
|
|
f['a1'] = F.attach_grad(f['a1'])
|
|
with F.record_grad():
|
|
# setter
|
|
c1 = f['a1']
|
|
rowid = Index(F.tensor([0, 2, 4]))
|
|
vals = {'a1' : F.attach_grad(F.zeros((len(rowid), D))),
|
|
'a2' : F.attach_grad(F.zeros((len(rowid), D))),
|
|
'a3' : F.attach_grad(F.zeros((len(rowid), D))),
|
|
}
|
|
f[rowid] = vals
|
|
c11 = f['a1']
|
|
F.backward(c11, F.ones((N, D)))
|
|
assert F.allclose(F.grad(c1)[:,0], F.tensor([0., 1., 0., 1., 0., 1., 1., 1., 1., 1.]))
|
|
assert F.allclose(F.grad(vals['a1']), F.ones((len(rowid), D)))
|
|
assert F.is_no_grad(vals['a2'])
|
|
|
|
def test_row3():
|
|
# test row delete
|
|
data = Frame(create_test_data())
|
|
f = FrameRef(data)
|
|
assert f.is_contiguous()
|
|
assert f.is_span_whole_column()
|
|
assert f.num_rows == N
|
|
del f[toindex(F.tensor([2, 3]))]
|
|
assert not f.is_contiguous()
|
|
assert not f.is_span_whole_column()
|
|
# delete is lazy: only reflect on the ref while the
|
|
# underlying storage should not be touched
|
|
assert f.num_rows == N - 2
|
|
assert data.num_rows == N
|
|
newidx = list(range(N))
|
|
newidx.pop(2)
|
|
newidx.pop(2)
|
|
newidx = toindex(newidx)
|
|
for k, v in f.items():
|
|
assert F.allclose(v, data[k][newidx])
|
|
|
|
def test_row4():
|
|
# test updating row with empty frame but has preset num_rows
|
|
f = FrameRef(Frame(num_rows=5))
|
|
rowid = Index(F.tensor([0, 2, 4]))
|
|
f[rowid] = {'h' : F.ones((3, 2))}
|
|
ans = F.zeros((5, 2))
|
|
ans[F.tensor([0, 2, 4])] = F.ones((3, 2))
|
|
assert F.allclose(f['h'], ans)
|
|
|
|
def test_sharing():
|
|
data = Frame(create_test_data())
|
|
f1 = FrameRef(data, index=toindex([0, 1, 2, 3]))
|
|
f2 = FrameRef(data, index=toindex([2, 3, 4, 5, 6]))
|
|
# test read
|
|
for k, v in f1.items():
|
|
assert F.allclose(F.narrow_row(data[k].data, 0, 4), v)
|
|
for k, v in f2.items():
|
|
assert F.allclose(F.narrow_row(data[k].data, 2, 7), v)
|
|
f2_a1 = f2['a1']
|
|
# test write
|
|
# update own ref should not been seen by the other.
|
|
f1[Index(F.tensor([0, 1]))] = {
|
|
'a1' : F.zeros([2, D]),
|
|
'a2' : F.zeros([2, D]),
|
|
'a3' : F.zeros([2, D]),
|
|
}
|
|
assert F.allclose(f2['a1'], f2_a1)
|
|
# update shared space should been seen by the other.
|
|
f1[Index(F.tensor([2, 3]))] = {
|
|
'a1' : F.ones([2, D]),
|
|
'a2' : F.ones([2, D]),
|
|
'a3' : F.ones([2, D]),
|
|
}
|
|
F.narrow_row_set(f2_a1, 0, 2, F.ones([2, D]))
|
|
assert F.allclose(f2['a1'], f2_a1)
|
|
|
|
def test_slicing():
|
|
data = Frame(create_test_data(grad=True))
|
|
f1 = FrameRef(data, index=toindex(slice(1, 5)))
|
|
f2 = FrameRef(data, index=toindex(slice(3, 8)))
|
|
# test read
|
|
for k, v in f1.items():
|
|
assert F.allclose(F.narrow_row(data[k].data, 1, 5), v)
|
|
f2_a1 = f2['a1'] # is a tensor
|
|
# test write
|
|
f1[Index(F.tensor([0, 1]))] = {
|
|
'a1': F.zeros([2, D]),
|
|
'a2': F.zeros([2, D]),
|
|
'a3': F.zeros([2, D]),
|
|
}
|
|
assert F.allclose(f2['a1'], f2_a1)
|
|
|
|
f1[Index(F.tensor([2, 3]))] = {
|
|
'a1': F.ones([2, D]),
|
|
'a2': F.ones([2, D]),
|
|
'a3': F.ones([2, D]),
|
|
}
|
|
F.narrow_row_set(f2_a1, 0, 2, 1)
|
|
assert F.allclose(f2['a1'], f2_a1)
|
|
|
|
f1[toindex(slice(2, 4))] = {
|
|
'a1': F.zeros([2, D]),
|
|
'a2': F.zeros([2, D]),
|
|
'a3': F.zeros([2, D]),
|
|
}
|
|
F.narrow_row_set(f2_a1, 0, 2, 0)
|
|
assert F.allclose(f2['a1'], f2_a1)
|
|
|
|
def test_add_rows():
|
|
data = Frame()
|
|
f1 = FrameRef(data)
|
|
f1.add_rows(4)
|
|
x = F.randn((1, 4))
|
|
f1[Index(F.tensor([0]))] = {'x': x}
|
|
ans = F.cat([x, F.zeros((3, 4))], 0)
|
|
assert F.allclose(f1['x'], ans)
|
|
f1.add_rows(4)
|
|
f1[toindex(slice(4, 8))] = {'x': F.ones((4, 4)), 'y': F.ones((4, 5))}
|
|
ans = F.cat([ans, F.ones((4, 4))], 0)
|
|
assert F.allclose(f1['x'], ans)
|
|
ans = F.cat([F.zeros((4, 5)), F.ones((4, 5))], 0)
|
|
assert F.allclose(f1['y'], ans)
|
|
|
|
def test_inplace():
|
|
f = FrameRef(Frame(create_test_data()))
|
|
print(f.schemes)
|
|
a1addr = id(f['a1'])
|
|
a2addr = id(f['a2'])
|
|
a3addr = id(f['a3'])
|
|
|
|
# column updates are always out-of-place
|
|
f['a1'] = F.ones((N, D))
|
|
newa1addr = id(f['a1'])
|
|
assert a1addr != newa1addr
|
|
a1addr = newa1addr
|
|
# full row update that becomes column update
|
|
f[toindex(slice(0, N))] = {'a1' : F.ones((N, D))}
|
|
assert id(f['a1']) != a1addr
|
|
|
|
# row update (outplace) w/ slice
|
|
f[toindex(slice(1, 4))] = {'a2' : F.ones((3, D))}
|
|
newa2addr = id(f['a2'])
|
|
assert a2addr != newa2addr
|
|
a2addr = newa2addr
|
|
# row update (outplace) w/ list
|
|
f[toindex([1, 3, 5])] = {'a2' : F.ones((3, D))}
|
|
newa2addr = id(f['a2'])
|
|
assert a2addr != newa2addr
|
|
a2addr = newa2addr
|
|
|
|
# row update (inplace) w/ slice
|
|
f.update_data(toindex(slice(1, 4)), {'a2' : F.ones((3, D))}, True)
|
|
newa2addr = id(f['a2'])
|
|
assert a2addr == newa2addr
|
|
# row update (inplace) w/ list
|
|
f.update_data(toindex([1, 3, 5]), {'a2' : F.ones((3, D))}, True)
|
|
newa2addr = id(f['a2'])
|
|
assert a2addr == newa2addr
|
|
|
|
if __name__ == '__main__':
|
|
test_create()
|
|
test_column1()
|
|
test_column2()
|
|
test_append1()
|
|
test_append2()
|
|
test_append3()
|
|
test_row1()
|
|
test_row2()
|
|
test_row3()
|
|
test_row4()
|
|
test_sharing()
|
|
test_slicing()
|
|
test_add_rows()
|
|
test_inplace()
|