def test_custom_op_gpu():
    # possible places to find library file
    if (os.name == 'posix'):
        lib = 'libcustomop_gpu_lib.so'
        if os.path.exists(lib):
            fname = lib
        elif os.path.exists('build/' + lib):
            fname = 'build/' + lib
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name == 'nt'):
        lib = 'libcustomop_gpu_lib.dll'
        if os.path.exists('windows_package\\lib\\' + lib):
            fname = 'windows_package\\lib\\' + lib
        else:
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    # load the library containing gemm custom operators
    mx.library.load(fname)

    # test symbol custom relu operator in gpu
    b = mx.nd.array([[-2, -1], [1, 2]], ctx=mx.gpu())
    c = mx.sym.Variable('c')
    d = mx.sym.Variable('d')
    e = mx.sym.my_relu(c)
    base = mx.sym.relu(d)
    in_grad = [mx.nd.empty((2, 2), ctx=mx.gpu())]
    in_grad_base = [mx.nd.empty((2, 2), ctx=mx.gpu())]
    exe = e.bind(ctx=mx.gpu(), args={'c': b}, args_grad=in_grad)
    exe_base = base.bind(ctx=mx.gpu(), args={'d': b}, args_grad=in_grad_base)
    out = exe.forward()
    out_base = exe_base.forward()
    assert_almost_equal(out_base[0].asnumpy(),
                        out[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)

    # test backward
    out_grad = mx.nd.ones((2, 2), ctx=mx.gpu())
    exe.backward([out_grad])
    exe_base.backward([out_grad])
    assert_almost_equal(in_grad_base[0].asnumpy(),
                        in_grad[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)
Exemple #2
0
def test_external_op():
    # check if operator already exists
    if hasattr(mx.nd, 'min_ex'):
        raise MXNetError('Operator already loaded')

    lib = 'libexternal_lib.so'
    fname = os.path.join(base_path,'example/extensions/lib_external_ops/build/'+lib)
    if not os.path.exists(fname):
        raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    mx.library.load(fname, False)

    # execute operator
    try:
        mx.nd.min_ex()
    except:
        raise MXNetError('Operator not loaded successfully')
def test_library_loading():
    if (os.name == 'posix'):
        lib = 'libsample_lib.so'
        if os.path.exists(lib):
            fname = lib
        elif os.path.exists('build/' + lib):
            fname = 'build/' + lib
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name == 'nt'):
        lib = 'libsample_lib.dll'
        if os.path.exists('windows_package\\lib\\' + lib):
            fname = 'windows_package\\lib\\' + lib
        else:
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    mx.library.load(fname)
Exemple #4
0
def test_custom_op_gpu():
    # possible places to find library file
    if (os.name == 'posix'):
        lib = 'libcustomop_gpu_lib.so'
        if os.path.exists(lib):
            fname = lib
        elif os.path.exists(os.path.join(base_path, 'build/' + lib)):
            fname = os.path.join(base_path, 'build/' + lib)
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name == 'nt'):
        lib = 'libcustomop_gpu_lib.dll'
        if os.path.exists('windows_package\\lib\\' + lib):
            fname = 'windows_package\\lib\\' + lib
        else:
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    # load the library containing gemm custom operators
    mx.library.load(fname)

    # test symbol custom relu operator in gpu
    b = mx.nd.array([[-2, -1], [1, 2]], ctx=mx.gpu())
    c = mx.sym.Variable('c')
    d = mx.sym.Variable('d')
    e = mx.sym.my_relu(c)
    base = mx.sym.relu(d)
    in_grad = [mx.nd.empty((2, 2), ctx=mx.gpu())]
    in_grad_base = [mx.nd.empty((2, 2), ctx=mx.gpu())]
    exe = e.bind(ctx=mx.gpu(), args={'c': b}, args_grad=in_grad)
    exe_base = base.bind(ctx=mx.gpu(), args={'d': b}, args_grad=in_grad_base)
    out = exe.forward()
    out_base = exe_base.forward()
    assert_almost_equal(out_base[0].asnumpy(),
                        out[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)

    # test custom relu backward
    out_grad = mx.nd.ones((2, 2), ctx=mx.gpu())
    exe.backward([out_grad])
    exe_base.backward([out_grad])
    assert_almost_equal(in_grad_base[0].asnumpy(),
                        in_grad[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)

    # test custom noisy relu producing deterministic result given same seed managed by mxnet
    d1 = mx.nd.ones(shape=(10, 10, 10), ctx=mx.cpu())
    d2 = mx.nd.ones(shape=(10, 10, 10), ctx=mx.gpu())

    mx.random.seed(128, ctx=mx.cpu())
    r1 = mx.nd.my_noisy_relu(d1)
    mx.random.seed(128, ctx=mx.cpu())
    r2 = mx.nd.my_noisy_relu(d1)
    assert_almost_equal(r1.asnumpy(), r2.asnumpy(), rtol=1e-3, atol=1e-3)

    mx.random.seed(128, ctx=mx.gpu())
    r3 = mx.nd.my_noisy_relu(d2)
    mx.random.seed(128, ctx=mx.gpu())
    r4 = mx.nd.my_noisy_relu(d2)
    assert_almost_equal(r3.asnumpy(), r4.asnumpy(), rtol=1e-3, atol=1e-3)
Exemple #5
0
def test_custom_op():
    # possible places to find library file
    if (os.name=='posix'):
        lib = 'libcustomop_lib.so'
        if os.path.exists(lib):
            fname = lib
        elif os.path.exists(os.path.join(base_path,'build/'+lib)):
            fname = os.path.join(base_path,'build/'+lib)
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name=='nt'):
        lib = 'libcustomop_lib.dll'
        if os.path.exists('windows_package\\lib\\'+lib):
            fname = 'windows_package\\lib\\'+lib
        else:
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    # load the library containing gemm custom operators
    mx.library.load(fname)

    # test symbol 2D gemm custom operators
    s = mx.sym.Variable('s')
    t = mx.sym.Variable('t')
    c = mx.sym.my_gemm(s,t)
    d = mx.sym.state_gemm(s,t)
    # baseline gemm from MXNet
    base = mx.sym.linalg.gemm2(s,t)

    # get some random input matrices
    dim_n, dim_k, dim_m = tuple(np.random.randint(1, 5, size=3))
    mat1 = mx.nd.random.uniform(-10, 10, shape=(dim_n, dim_k), ctx=mx.cpu())
    mat2 = mx.nd.random.uniform(-10, 10, shape=(dim_k, dim_m), ctx=mx.cpu())

    # intermediate ndarrays to be populated by gradient compute
    in_grad1 = [mx.nd.empty((dim_n,dim_k),ctx=mx.cpu()),mx.nd.empty((dim_k,dim_m),ctx=mx.cpu())]
    in_grad2 = [mx.nd.empty((dim_n,dim_k),ctx=mx.cpu()),mx.nd.empty((dim_k,dim_m),ctx=mx.cpu())]
    in_grad_base = [mx.nd.empty((dim_n,dim_k),ctx=mx.cpu()),mx.nd.empty((dim_k,dim_m),ctx=mx.cpu())]

    exe1 = c._bind(ctx=mx.cpu(),args={'s':mat1,'t':mat2},args_grad=in_grad1)
    exe2 = d._bind(ctx=mx.cpu(),args={'s':mat1,'t':mat2},args_grad=in_grad2)
    exe_base = base._bind(ctx=mx.cpu(),args={'s':mat1,'t':mat2},args_grad=in_grad_base)

    out1 = exe1.forward()
    out2 = exe2.forward()
    # test stateful operator by calling it multiple times
    out2 = exe2.forward()
    out_base = exe_base.forward()

    # check that forward compute matches one executed by MXNet
    assert_almost_equal(out_base[0].asnumpy(), out1[0].asnumpy(), rtol=1e-3, atol=1e-3)
    assert_almost_equal(out_base[0].asnumpy(), out2[0].asnumpy(), rtol=1e-3, atol=1e-3)

    # random output grad ndarray for gradient update
    out_grad = mx.nd.ones((dim_n, dim_m), ctx=mx.cpu())
    exe1.backward([out_grad])
    exe2.backward([out_grad])
    exe_base.backward([out_grad])

    # check that gradient compute matches one executed by MXNet
    assert_almost_equal(in_grad_base[0].asnumpy(), in_grad1[0].asnumpy(), rtol=1e-3, atol=1e-3)
    assert_almost_equal(in_grad_base[0].asnumpy(), in_grad2[0].asnumpy(), rtol=1e-3, atol=1e-3)
Exemple #6
0
def test_subgraph():
    # possible places to find library file
    if (os.name=='posix'):
        lib = 'libsubgraph_lib.so'
        if os.path.exists(lib):
            # plain make build, when run in the CI
            fname = lib
        elif os.path.exists(os.path.join(base_path, 'build/'+lib)):
            # plain cmake build when run in the CI
            fname = os.path.join(base_path, 'build/'+lib)
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name=='nt'):
        lib = 'libsubgraph_lib.dll'
        if os.path.exists('windows_package\\lib\\'+lib):
            # plain make build, when run in the CI
            fname = 'windows_package\\lib\\'+lib
        else:
            # plain cmake build when run in the CI
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    mx.library.load(fname)

    # test simple graph with add, exp and log operators, library supports exp/log
    a = mx.sym.var('a')
    b = mx.sym.var('b')
    c = a + b
    d = mx.sym.exp(c)
    sym = mx.sym.log(d)

    args = {'a':mx.nd.ones((3,2),ctx=mx.cpu()), 'b':mx.nd.ones((3,2),ctx=mx.cpu())}

    # baseline - regular execution in MXNet
    exe = sym._bind(ctx=mx.cpu(), args=args)
    out = exe.forward()

    # without propogating shapes/types, passing a custom option to subgraph prop "myOpt"
    # should not create subgraph since subgraph prop requires type info
    mysym1 = sym.optimize_for("myProp", myOpt='yello')
    exe1 = mysym1._bind(ctx=mx.cpu(), args=args)
    out1 = exe1.forward()
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(), out1[0].asnumpy(), rtol=1e-3, atol=1e-3)

    # with propogating shapes/types, rejecting subgraph
    # this tests creating the subgraph and having the subgraph prop reject it
    mysym2 = sym.optimize_for("myProp", args, reject=True)
    exe2 = mysym2._bind(ctx=mx.cpu(), args=args)
    out2 = exe2.forward()
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(), out2[0].asnumpy(), rtol=1e-3, atol=1e-3)

    # with propogating shapes/types
    mysym3 = sym.optimize_for("myProp",args)
    exe3 = mysym3._bind(ctx=mx.cpu(), args=args)
    out3 = exe3.forward()
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(), out3[0].asnumpy(), rtol=1e-3, atol=1e-3)

    # Gluon Hybridize partitioning with shapes/types
    sym_block = nn.SymbolBlock(sym, [a,b])
    sym_block.initialize()
    sym_block.optimize_for(mx.nd.ones((3,2)),mx.nd.ones((3,2)),backend='myProp')
    out4 = sym_block(mx.nd.ones((3,2)),mx.nd.ones((3,2)))
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(), out4[0].asnumpy(), rtol=1e-3, atol=1e-3)

    # Gluon Hybridize partitioning with sym.var
    sym_block2 = nn.SymbolBlock(sym, [a,b])
    sym_block2.initialize()
    a_var = mx.sym.var('a',shape=(3,2))
    b_var = mx.sym.var('b',shape=(3,2))
    sym_block2.optimize_for(a_var, b_var, backend='myProp')

    # Gluon Hybridize partitioning with shapes/types
    sym_block3 = nn.SymbolBlock(sym, [a,b])
    sym_block3.initialize()
    a_data = mx.nd.ones((3,2))
    b_data = mx.nd.ones((3,2))
    sym_block3.optimize_for(a_data, b_data, backend='myProp')
    sym_filename, params_filename = sym_block3.export('optimized')
    assert sym_filename == 'optimized-symbol.json'
    assert params_filename is None
    sym_block4 = nn.SymbolBlock.imports(sym_filename, ['a','b'], params_filename)

    out5 = sym_block4(a_data, b_data)
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(), out5[0].asnumpy(), rtol=1e-3, atol=1e-3)
def test_custom_op():
    if (os.name == 'posix'):
        lib = 'libsample_lib.so'
        if os.path.exists(lib):
            fname = lib
        elif os.path.exists('build/' + lib):
            fname = 'build/' + lib
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name == 'nt'):
        lib = 'libsample_lib.dll'
        if os.path.exists('windows_package\\lib\\' + lib):
            fname = 'windows_package\\lib\\' + lib
        else:
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    mx.library.load(fname)

    # test simple 2D gemm custom op loaded from sample library
    s = mx.sym.Variable('s')
    t = mx.sym.Variable('t')
    c = mx.sym.my_gemm(s, t)
    d = mx.sym.state_gemm(s, t)
    base = mx.sym.linalg.gemm2(s, t)  # baseline

    dim_n, dim_k, dim_m = tuple(np.random.randint(1, 5, size=3))

    mat1 = mx.nd.random.uniform(-10, 10, shape=(dim_n, dim_k), ctx=mx.cpu())
    mat2 = mx.nd.random.uniform(-10, 10, shape=(dim_k, dim_m), ctx=mx.cpu())

    in_grad1 = [
        mx.nd.empty((dim_n, dim_k), ctx=mx.cpu()),
        mx.nd.empty((dim_k, dim_m), ctx=mx.cpu())
    ]
    in_grad2 = [
        mx.nd.empty((dim_n, dim_k), ctx=mx.cpu()),
        mx.nd.empty((dim_k, dim_m), ctx=mx.cpu())
    ]
    in_grad_base = [
        mx.nd.empty((dim_n, dim_k), ctx=mx.cpu()),
        mx.nd.empty((dim_k, dim_m), ctx=mx.cpu())
    ]

    exe1 = c.bind(ctx=mx.cpu(),
                  args={
                      's': mat1,
                      't': mat2
                  },
                  args_grad=in_grad1)
    exe2 = d.bind(ctx=mx.cpu(),
                  args={
                      's': mat1,
                      't': mat2
                  },
                  args_grad=in_grad2)
    exe_base = base.bind(ctx=mx.cpu(),
                         args={
                             's': mat1,
                             't': mat2
                         },
                         args_grad=in_grad_base)

    out1 = exe1.forward()
    out2 = exe2.forward()
    out2 = exe2.forward()  # stateful
    out_base = exe_base.forward()

    assert_almost_equal(out_base[0].asnumpy(),
                        out1[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)
    assert_almost_equal(out_base[0].asnumpy(),
                        out2[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)

    out_grad = mx.nd.ones((dim_n, dim_m), ctx=mx.cpu())
    exe1.backward([out_grad])
    exe2.backward([out_grad])
    exe_base.backward([out_grad])

    assert_almost_equal(in_grad_base[0].asnumpy(),
                        in_grad1[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)
    assert_almost_equal(in_grad_base[0].asnumpy(),
                        in_grad2[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)
def test_subgraph():
    # possible places to find library file
    if (os.name == 'posix'):
        lib = 'libsubgraph_lib.so'
        if os.path.exists(lib):
            # plain make build, when run in the CI
            fname = lib
        elif os.path.exists('build/' + lib):
            # plain cmake build when run in the CI
            fname = 'build/' + lib
        else:
            raise MXNetError("library %s not found " % lib)
    elif (os.name == 'nt'):
        lib = 'libsubgraph_lib.dll'
        if os.path.exists('windows_package\\lib\\' + lib):
            # plain make build, when run in the CI
            fname = 'windows_package\\lib\\' + lib
        else:
            # plain cmake build when run in the CI
            raise MXNetError("library %s not found " % lib)

    fname = os.path.abspath(fname)
    mx.library.load(fname)

    # test simple graph with add, exp and log operators, library supports exp/log
    a = mx.sym.var('a')
    b = mx.sym.var('b')
    c = a + b
    d = mx.sym.exp(c)
    sym = mx.sym.log(d)

    args = {
        'a': mx.nd.ones((3, 2), ctx=mx.cpu()),
        'b': mx.nd.ones((3, 2), ctx=mx.cpu())
    }
    arg_array = [
        mx.nd.ones((3, 2), dtype='float32', ctx=mx.cpu()),
        mx.nd.ones((3, 2), dtype='float32', ctx=mx.cpu())
    ]

    # baseline - regular execution in MXNet
    exe = sym.bind(ctx=mx.cpu(), args=args)
    out = exe.forward()

    # without propogating shapes/types, passing a custom option to subgraph prop "myOpt"
    # should not create subgraph since subgraph prop requires type info
    mysym1 = sym.optimize_for("myProp", myOpt='yello')
    exe1 = mysym1.bind(ctx=mx.cpu(), args=args)
    out1 = exe1.forward()
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(),
                        out1[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)

    # with propogating shapes/types, rejecting subgraph
    # this tests creating the subgraph and having the subgraph prop reject it
    mysym2 = sym.optimize_for("myProp", arg_array, reject=True)
    exe2 = mysym2.bind(ctx=mx.cpu(), args=args)
    out2 = exe2.forward()
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(),
                        out2[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)

    # with propogating shapes/types
    mysym3 = sym.optimize_for("myProp", arg_array)
    exe3 = mysym3.bind(ctx=mx.cpu(), args=args)
    out3 = exe3.forward()
    # check that result matches one executed by MXNet
    assert_almost_equal(out[0].asnumpy(),
                        out3[0].asnumpy(),
                        rtol=1e-3,
                        atol=1e-3)