def test_args(self): # Test that arguments to RandomFunction are honored rf2 = RandomFunction(np.random.RandomState.uniform, tensor.dvector) rf4 = RandomFunction(np.random.RandomState.uniform, tensor.dvector, inplace=True) rng_R = random_state_type() # use make_node to override some of the self.args post_r2, out2 = rf2(rng_R, (4, ), -2, 2) # NOT INPLACE post_r4, out4 = rf4(rng_R, (4, ), -4, 4) # INPLACE post_r2_4, out2_4 = rf2(rng_R, (4, ), -4.0, 2) # NOT INPLACE post_r2_4_4, out2_4_4 = rf2(rng_R, (4, ), -4.0, 4.0) # NOT INPLACE # configure out4 to be computed inplace # The update expression means that the random state rng_R will # be maintained by post_r4 f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r4, mutable=True, ) ], [out2, out4, out2_4, out2_4_4], accept_inplace=True, ) f2, f4, f2_4, f2_4_4 = f() f2b, f4b, f2_4b, f2_4_4b = f() # print f2 # print f4 # print f2_4 # print f2_4_4 # print f2b # print f4b # print f2_4b # print f2_4_4b # setting bounds is same as multiplying by 2 assert np.allclose(f2 * 2, f4), (f2, f4) # retrieving from non-inplace generator # is same as inplace one for first call assert np.allclose(f2_4_4, f4), (f2_4_4, f4) # f4 changes from call to call, that the update has worked assert not np.allclose(f4, f4b), (f4, f4b)
def test_no_inplace(self): # Test that when not running inplace, the RandomState is not updated rf = RandomFunction("uniform", tensor.dvector) rng_R = random_state_type() post_r, out = rf(rng_R, (3, ), 0.0, 1.0) f = compile.function([rng_R], [post_r, out]) rng = np.random.RandomState(utt.fetch_seed()) rng0, val0 = f(rng) rng_ = np.random.RandomState(utt.fetch_seed()) # rng should still be in a fresh state assert rng_R.type.values_eq(rng, rng_) # rng0 should be in an updated state assert not rng_R.type.values_eq(rng, rng0) f2 = compile.function( [compile.In(rng_R, value=rng, update=post_r, mutable=False)], [post_r, out]) rng2, val2 = f2() # rng should be in a fresh state assert rng_R.type.values_eq(rng, rng_) # rng2 should be in an updated state assert not rng_R.type.values_eq(rng, rng2) # The updated state should be the same for both functions assert rng_R.type.values_eq(rng2, rng0) rng3, val3 = f2() # rng2 should not have changed assert rng_R.type.values_eq(rng2, rng0) # rng3 should be an updated again version of rng2 assert not rng_R.type.values_eq(rng3, rng2) assert not rng_R.type.values_eq(rng3, rng)
def test_inplace_optimization(self): # Test that FAST_RUN includes the random_make_inplace optimization # inplace = False rf2 = RandomFunction(np.random.RandomState.uniform, tensor.dvector) rng_R = random_state_type() # If calling RandomFunction directly, all args have to be specified, # because shape will have to be moved to the end post_r2, out2 = rf2(rng_R, (4, ), 0.0, 1.0) f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r2, mutable=True, ) ], out2, mode="FAST_RUN", ) # DEBUG_MODE can't pass the id-based # test below # test that the RandomState object stays the same from function call to # function call, but that the values returned change from call to call. id0 = id(f[rng_R]) val0 = f() assert id0 == id(f[rng_R]) val1 = f() assert id0 == id(f[rng_R]) assert not np.allclose(val0, val1)
def randomfunction(random_state, size=(), low=0.0, high=0.0, ndim=None): ndim, size, bcast = raw_random._infer_ndim_bcast(ndim, size) if ndim_added < 0: bcast = bcast[:ndim_added] else: bcast = bcast + ((False,) * ndim_added) assert len(bcast) == ndim + ndim_added op = RandomFunction( "uniform", tensor.TensorType(dtype="float64", broadcastable=bcast), ndim_added=ndim_added, ) return op(random_state, size, low, high)
def test_basic_usage(self): rf = RandomFunction(np.random.RandomState.uniform, tensor.dvector) assert not rf.inplace assert getattr(rf, "destroy_map", {}) == {} rng_R = random_state_type() # If calling RandomFunction directly, all args have to be specified, # because shape will have to be moved to the end post_r, out = rf(rng_R, (4, ), 0.0, 1.0) assert out.type == tensor.dvector f = compile.function([rng_R], out) rng_state0 = np.random.RandomState(utt.fetch_seed()) f_0 = f(rng_state0) f_1 = f(rng_state0) assert np.all(f_0 == f_1)
def test_inplace_norun(self): rf = RandomFunction(np.random.RandomState.uniform, tensor.dvector, inplace=True) assert rf.inplace assert getattr(rf, "destroy_map", {}) != {}
def test_permutation_helper(self): # Test that raw_random.permutation_helper generates the same # results as numpy, # and that the 'ndim_added' keyword behaves correctly. # permutation_helper needs "ndim_added=1", because its output # is one dimension more than its "shape" argument (and there's # no way to determine that automatically). # Check the working case, over two calls to see if the random # state is correctly updated. rf = RandomFunction(permutation_helper, tensor.imatrix, 8, ndim_added=1) rng_R = random_state_type() post_r, out = rf(rng_R, (7, ), 8) f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [out], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() # numpy_rng.permutation outputs one vector at a time, # so we call it iteratively to generate all the samples. numpy_val0 = np.asarray([numpy_rng.permutation(8) for i in range(7)]) numpy_val1 = np.asarray([numpy_rng.permutation(8) for i in range(7)]) assert np.all(val0 == numpy_val0) assert np.all(val1 == numpy_val1) # This call lacks "ndim_added=1", so ndim_added defaults to 0. # A ValueError should be raised. rf0 = RandomFunction(permutation_helper, tensor.imatrix, 8) post_r0, out0 = rf0(rng_R, (7, ), 8) f0 = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r0, mutable=True, ) ], [out0], accept_inplace=True, ) with pytest.raises(ValueError): f0() # Here, ndim_added is 2 instead of 1. A ValueError should be raised. rf2 = RandomFunction(permutation_helper, tensor.imatrix, 8, ndim_added=2) post_r2, out2 = rf2(rng_R, (7, ), 8) f2 = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r2, mutable=True, ) ], [out2], accept_inplace=True, ) with pytest.raises(ValueError): f2()