def test_issue_6746(): assert manualintegrate(y**x, x) == \ Piecewise((x, Eq(log(y), 0)), (y**x/log(y), True)) assert manualintegrate(y**(n*x), x) == \ Piecewise( (x, Eq(n, 0)), (Piecewise( (n*x, Eq(log(y), 0)), (y**(n*x)/log(y), True))/n, True)) assert manualintegrate(exp(n*x), x) == \ Piecewise((x, Eq(n, 0)), (exp(n*x)/n, True)) with assuming(~Q.zero(log(y))): assert manualintegrate(y**x, x) == y**x / log(y) with assuming(Q.zero(log(y))): assert manualintegrate(y**x, x) == x with assuming(~Q.zero(n)): assert manualintegrate(y**(n*x), x) == \ Piecewise((n*x, Eq(log(y), 0)), (y**(n*x)/log(y), True))/n with assuming(~Q.zero(n) & ~Q.zero(log(y))): assert manualintegrate(y**(n*x), x) == \ y**(n*x)/(n*log(y)) with assuming(Q.negative(a)): assert manualintegrate(1 / (a + b*x**2), x) == \ Integral(1/(a + b*x**2), x)
def test_issue_6746(): assert manualintegrate(y**x, x) == \ Piecewise((x, Eq(log(y), 0)), (y**x/log(y), True)) assert manualintegrate(y**(n*x), x) == \ Piecewise( (x, Eq(n, 0)), (Piecewise( (n*x, Eq(log(y), 0)), (y**(n*x)/log(y), True))/n, True)) assert manualintegrate(exp(n*x), x) == \ Piecewise((x, Eq(n, 0)), (exp(n*x)/n, True)) with assuming(~Q.zero(log(y))): assert manualintegrate(y**x, x) == y**x/log(y) with assuming(Q.zero(log(y))): assert manualintegrate(y**x, x) == x with assuming(~Q.zero(n)): assert manualintegrate(y**(n*x), x) == \ Piecewise((n*x, Eq(log(y), 0)), (y**(n*x)/log(y), True))/n with assuming(~Q.zero(n) & ~Q.zero(log(y))): assert manualintegrate(y**(n*x), x) == \ y**(n*x)/(n*log(y)) with assuming(Q.negative(a)): assert manualintegrate(1 / (a + b*x**2), x) == \ Integral(1/(a + b*x**2), x)
def test_fftw_inverse(): c = FFTW(y) with assuming(Q.complex(y)): f = build(c, [y], [DFT(y)], modname='fftw2', filename='tmp/fftw2.f90') c = IFFTW(y) with assuming(Q.complex(y)): fi = build(c, [y], [DFT(y).T], modname='ifftw', filename='tmp/ifftw.f90') x = np.random.random_sample((8,)) + 1j * np.random.random_sample((8,)) expected = x f(x) fi(x) assert np.allclose(expected, x)
def test_recv_fortran(): with assuming(*map(Q.real_elements, (A, B, C))): a = r.fortran_call([], ['A', 'status', 'ierr'])[0] b = "call MPI_RECV( A, 15, MPI_DOUBLE_PRECISION, %d, %d, MPI_COMM_WORLD, status, ierr)"%(r.source, r.tag) print a print b assert streq(a, b)
def test_ElemProd_code(): from computations.matrices.fortran.core import generate ic = inplace_compile(c) with assuming(Q.real_elements(x), Q.real_elements(y)): s = generate(ic, [x,y], [HadamardProduct(x,y)]) with open('tmp/elem_test.f90','w') as f: f.write(s) assert "= X * Y" in s
def test_BlockMatrix_Determinant(): A, B, C, D = map(lambda s: MatrixSymbol(s, 3, 3), 'ABCD') X = BlockMatrix([[A, B], [C, D]]) from sympy import assuming, Q with assuming(Q.invertible(A)): assert det(X) == det(A) * det(D - C * A.I * B) assert isinstance(det(X), Expr)
def test_send_fortran_generate(): from computations.inplace import inplace_compile from computations.matrices.fortran.core import generate A = MatrixSymbol('A', 10, 10) s = Send(A, 1) iss = inplace_compile(s) with assuming(Q.real_elements(A)): code = generate(iss, [A], []) assert isinstance(code, str)
def test_BlockMatrix_Determinant(): A, B, C, D = map(lambda s: MatrixSymbol(s, 3, 3), 'ABCD') X = BlockMatrix([[A, B], [C, D]]) from sympy import assuming, Q with assuming(Q.invertible(A)): assert det(X) == det(A) * det(D - C*A.I*B) assert isinstance(det(X), Expr)
def test_recv_fortran_generate(): from computations.inplace import inplace_compile from computations.matrices.fortran.core import generate A = MatrixSymbol('A', 10, 10) r = Recv(A, 2) irr = inplace_compile(r) with assuming(Q.real_elements(A)): code = generate(irr, [], [A]) assert isinstance(code, str)
def test_fftw(): c = FFTW(y) with assuming(Q.complex_elements(y)): f = build(c, [y], [DFT(y)], modname='fftw', filename='tmp/fftw.f90') x = np.zeros(8, dtype='complex') expected = np.fft.fft(x) f(x) assert np.allclose(expected, x)
def test_ReadFromFile(): from computations.matrices.io import ReadFromFile X = MatrixSymbol('X', 2, 3) with assuming(Q.real_elements(X)): f = build(ReadFromFile('tmp/test_read.dat', X), [], [X], modname='readtest', filename='tmp/readtest.f90') result = f() assert result[0, 0] == 1.0
def test_commcost(): latency = 1. inv_bandwidth = .1 commcost = make_commcost(latency, inv_bandwidth) with assuming(*map(Q.real_elements, [A, B, x])): time = commcost(gemm, gemm2, 1, 2) assert isinstance(time, (float, Number)) assert time == 8*n*n*inv_bandwidth + latency assert commcost(gemm, gemm2, 1, 1) == 0
def test_execution(): with assuming(Q.real_elements(X), Q.real_elements(Y)): f = build(pgemm, [X, Y], [pgemm.duration], filename='tmp/profile.f90', modname='profile') assert callable(f) nX, nY = np.random.rand(500, 500), np.random.rand(500, 500) result = f(nX, nY) assert isinstance(result, float) assert result > 0
def test_Slice_build(): c = Slice(X[:2, :2]) with assuming(Q.real_elements(X)): f = build(c, [X], [X[:2, :2]], filename='tmp/slice.f90', modname='slice') nX = np.eye(3, dtype=np.float64) result = f(nX) expected = np.eye(2, dtype=np.float64) assert np.allclose(result, expected)
def test_es_toy(): K = MatrixSymbol('K',n,1) phi = MatrixSymbol('phi', n, 1) V = MatrixSymbol('V',n,1) c = AXPY(1.0, HP(K,phi), DFT(n).T*HP(V,DFT(n)*phi)) + ElemProd(K,phi) + IFFTW(HP(V, DFT(n) * phi)) + FFTW(phi) + ElemProd(V, DFT(n) * phi) # show(c) with assuming(Q.complex_elements(phi), Q.real_elements(K), Q.real_elements(V)): f = build(c, [K,V,phi], [HP(K,phi) + DFT(n).T * HP(V,DFT(n) * phi)], modname='es', filename='tmp/es.f90')
def test_Join_build(): c = Join(B) with assuming(Q.real_elements(X), Q.real_elements(Y)): f = build(c, [X, Y], [B], filename='tmp/join.f90', modname='join') nX = np.ones((2, 3), dtype=np.float64) nY = np.ones((2, 3), dtype=np.float64) result = f(nX, nY) expected = np.ones((2, 6), dtype=np.float64) assert np.allclose(result, expected)
def test_code_generation(): from computations.matrices.fortran.core import generate ic = inplace_compile(c) with assuming(Q.complex_elements(x)): s = generate(ic, [x], [DFT(n)*x]) with open('tmp/tmpfftw.f90','w') as f: f.write(s) assert 'use, intrinsic :: iso_c_binding' in s assert "include 'fftw3.f03'" in s assert isinstance(s, str)
def test_GEMM(): with assuming(Q.real_elements(A), Q.real_elements(X)): f = build(GEMM(1.0, A, X, 0.0, ZeroMatrix(A.rows, X.cols)), [A, X], [A*X], modname='gemmtest', filename='tmp/gemmtest.f90') nA = np.asarray([[1, 2], [3, 4]], dtype=np.float64, order='F') nX = np.asarray([[1, 1], [1, 1]], dtype=np.float64, order='F') expected = np.asarray([[3., 3.], [7., 7.]]) result = f(nA, nX) assert np.allclose(expected, result)
def test_BlockMatrix_Determinant(): A, B, C, D = [MatrixSymbol(s, 3, 3) for s in 'ABCD'] X = BlockMatrix([[A, B], [C, D]]) from sympy import assuming, Q with assuming(Q.invertible(A)): assert det(X) == det(A) * det(D - C * A.I * B) assert isinstance(det(X), Expr) assert det(BlockMatrix([A])) == det(A) assert det(BlockMatrix([ZeroMatrix(n, n)])) == 0
def test_linregress(): from computations.matrices.examples.linregress import c, assumptions, X, y cc = CompositeComputation(*map(ProfileMPI, c.toposort())) with assuming(*assumptions): f = build(cc, [X, y], [comp.duration for comp in cc.toposort()], filename='tmp/profile_linregress.f90', modname='profile_linregress') nX, ny = np.random.rand(500, 500), np.random.rand(500, 1) t1, t2, t3 = f(nX, ny) assert all(isinstance(t, float) for t in (t1, t2, t3))
def test_ReadWrite(): from computations.matrices.io import ReadFromFile, WriteToFile X = MatrixSymbol('X', 2, 3) c = ReadFromFile('tmp/test_read.dat', X) + WriteToFile('tmp/test_write2.dat', X) with assuming(Q.real_elements(X)): f = build(c, [], [], modname='readwritetest', filename='tmp/readwritetest.f90') f() with open('tmp/test_read.dat') as f: with open('tmp/test_write2.dat') as g: assert f.read() == g.read()
def test_compcost(): nA = np.asarray([[1, 2], [3, 4]], dtype=np.float64, order='F') nB = np.asarray([[1, 0], [0, 1]], dtype=np.float64, order='F') nx = np.asarray([[1], [1]], dtype=np.float64, order='F') with assuming(*map(Q.real_elements, [A, B, x])): compcost = make_compcost(gemm + gemm2, [A, B, x], [nA, nB, nx], filename='compcost.f90', modname='compcost') time = compcost(gemm, 1) assert isinstance(time, (float, Number)) assert 0 < time < .1
def test_WriteToFile(): from computations.matrices.io import WriteToFile filename = 'tmp/test_write.dat' with assuming(Q.real_elements(X)): f = build(WriteToFile(filename, X), [X], [], modname='writetest', filename='tmp/writetest.f90') data = np.asarray([[1., 2., 3.], [4., 5., 6.]]) result = f(data) with open(filename) as f: assert "1.0" in f.read()
def test_POSV(): c = POSV(A, y) with assuming(Q.real_elements(A), Q.real_elements(y)): f = build(c, [A, y], [A.I*y], modname='posv', filename='tmp/posv.f90') nA, ny = np.asarray([[2, 1], [1, 2]], dtype='float64').reshape((2, 2)), np.ones(2) mA = np.matrix(nA) my = np.matrix(ny).T expected = np.linalg.solve(mA, my) f(nA, ny) assert np.allclose(expected, ny)
def test_POTRS(): from sympy.matrices.expressions.factorizations import UofCholesky from computations.matrices.lapack import POTRS c = POTRS(UofCholesky(A), X) with assuming(Q.real_elements(A), Q.real_elements(X), Q.positive_definite(A)): f = build(c, [UofCholesky(A), X], [A.I*X], modname='potrs', filename='tmp/potrs.f90') nA = np.asarray([[1, 0], [0, 1]], dtype=np.float64, order='F') nX = np.asarray([[1, 2], [3, 4]], dtype=np.float64, order='F') expected = np.asarray([[1., 2.], [3., 4.]]) f(nA, nX); result = nX assert np.allclose(expected, result)
def is_compartmental(self): """ Returns checks that all fluxes are nonnegative at the time of implementation this functionality sympy did not support relations in predicates yet. So while the following works: with assuming(Q.positive(x) & Q.positive(y)): print(ask(Q.positive(2*x+y) it is not possible yet to get a meaningful answer to: with assuming(Q.is_true(x>0) & Q.is_true(y>0)): print(ask(Q.positive(2*x+y) We therefore cannot implement more elaborate assumptions like k_1-(a_12+a_32)>=0 but still can assume all the state_variables and the time_symbol to be nonnegative Therefore we can check the compartmental_property best after all paramater value have been substituted. At the moment the function throws an exception if this is not the case. """ #check if all free symbols have been removed allowed_symbs = set([sym for sym in self.state_vector]) if hasattr(self, "time_symbol"): allowed_symbs.add(self.time_symbol) if not (allowed_symbs.issuperset(self.free_symbols)): raise Exception( Template( "Sympy can not check the parameters without assumptions. Try to substitute all variables except the state variables and the time symbol. Use the subs methot of the class {c}" ).subs(c=self__class__)) def f(expr): res = ask(Q.nonnegative(expr)) if res is None: raise Exception( Template( """Sympy can not (yet) check the parameters even with correct assumptions,\ since relations (<,>) are not implemented yet. It gave up for the following expression: ${e}.""").substitute(e=expr)) return res # making a list of predicated stating that all state variables are nonnegative predList = [Q.nonnegative(sym) for sym in self.state_vector] if hasattr(self, "time_symbol"): predList += [Q.nonnegative(self.time_symbol)] with assuming(*predList): # under this assumption eveluate all fluxes all_fluxes_nonnegative = all(map(f, self.all_fluxes())) return all_fluxes_nonnegative
def dtype_of(expr, *assumptions): if hasattr(expr, 'fortran_type'): return expr.fortran_type() with assuming(*assumptions): if ask(Q.integer(expr) | Q.integer_elements(expr)) or expr.is_integer: result = 'integer' elif ask(Q.real(expr) | Q.real_elements(expr)) or expr.is_real: result = 'real(kind=8)' elif ask(Q.complex(expr) | Q.complex_elements(expr)) or expr.is_complex: result = 'complex(kind=8)' else: raise TypeError('Could not infer type of %s'%str(expr)) return result
def compile(inputs, outputs, *assumptions, **kwargs): """ A very simple greedy scheme.""" strategy = kwargs.get('strategy', greedy) c = Identity(*outputs) # Is this computation a leaf in our tree? Do its inputs match ours? isleaf = lambda comp: set(remove(constant_arg, comp.inputs)) == set(inputs) with assuming(*assumptions): with variables(*vars): stream = strategy(children, objective, isleaf, c) # all valid computations result = next(stream) # first valid computtion return result
def make_tompkins(c, agents, assumptions, commcost, inputs, ninputs, filenames, **kwargs): tokenizer = make_getname() ic = inplace_compile(c, tokenizer=tokenizer, Copy=COPY) send = partial(isend, tokenizer=tokenizer) recv = partial(irecv, tokenizer=tokenizer) with assuming(*assumptions): compcost = make_compcost(ic, inputs, ninputs) M = kwargs.pop('M', 20.0) dags, sched, m = schedule_tompkins(ic.dict_io(), agents, compcost, commcost, send=send, recv=recv, M=M) torders = orderings(sched) args = [] for ii, a in enumerate(dags): comps = set(dags[a].keys()) | set(sum(dags[a].values(), ())) t = computation_from_dict(dags[a]) reads = [wrap_tokenize(t, ReadFromFile(filenames[i], i), tokenizer) for i in filenames if i in [v.expr for v in t.inputs]] writes = [wrap_tokenize(t, WriteToFile(filenames[o], o), tokenizer) for o in filenames if o in [v.expr for v in t.outputs]] disk = CompositeComputation(*(reads + writes)) t2 = t + disk t2 = inplace_tokenize(t2) cmp = make_order_cmp(torders[a]) args.extend([t2, 'f%d'%ii, [cmp]]) # Debug from computations.dot import writepdf writepdf(t2, 'tmp/prog_mpi_t%d'%ii) tompcode = generate_mpi(*args) # Debug with open('tmp/sched.txt', 'w') as f: f.write('\n'.join(map(str, sched))) return tompcode, m
def test_linear_regression(): beta = (X.T*X).I * X.T*y c = (POSV(X.T*X, X.T*y) + SYRK(1.0, X.T, 0.0, ZeroMatrix(m, m)) + GEMM(1.0, X.T, y, 0.0, ZeroMatrix(n, 1))) with assuming(Q.real_elements(X), Q.real_elements(y)): f = build(c, [X, y], [beta], modname='linregress', filename='tmp/linregress.f90') nX = np.asarray([[1, 2], [3, 4], [5, 7]], dtype='float64', order='F') ny = np.asarray([[1], [1], [1]], dtype='float64', order='F') mX = np.matrix(nX) my = np.matrix(ny) expected = np.asarray(np.linalg.solve(mX.T*mX, mX.T*my)).squeeze() result = f(nX, ny) assert np.allclose(expected, result)
def make_heft(c, agents, assumptions, commcost, inputs, ninputs, filenames): tokenizer = make_getname() ic = inplace_compile(c, tokenizer=tokenizer, Copy=COPY) send = partial(isend, tokenizer=tokenizer) recv = partial(irecv, tokenizer=tokenizer) with assuming(*assumptions): compcost = make_compcost(ic, inputs, ninputs) orders, jobson = schedule_heft(ic.dict_io(), agents, compcost, commcost) neworders, jobson = insert_sendrecvs(orders, jobson, ic.dict_io(), send=send, recv=recv) args = [] for ii, a in enumerate(agents): h = CompositeComputation(*[e.job for e in neworders[a]]) reads = [wrap_tokenize(h, ReadFromFile(filenames[i], i), tokenizer) for i in filenames if i in [v.expr for v in h.inputs]] writes = [wrap_tokenize(h, WriteToFile(filenames[o], o), tokenizer) for o in filenames if o in [v.expr for v in h.outputs]] disk = CompositeComputation(*(reads + writes)) h2 = h + disk h2 = inplace_tokenize(h2) cmp = make_order_cmp([e.job for e in orders[a]]) args.extend([h2, 'f%d'%ii, [cmp]]) # Debug from computations.dot import writepdf writepdf(h2, 'tmp/prog_mpi_h%d'%ii) heftcode = generate_mpi(*args) # Debug with open('tmp/orders.txt', 'w') as f: f.write('\n'.join(map(str, orders.items()))) return heftcode, makespan(orders)
def make_kalman_comp(mu, Sigma, H, R, data, assumptions=assumptions): Z = H*Transpose(H*Sigma) + R A = Z.I * (-1.0*data + H*mu) B = Z.I * H with assuming(*assumptions): c = ( SYMM(1.0, H, Sigma, 0.0, ZeroMatrix(*H.shape)) + GEMM(1.0, H, mu, -1.0, data) + GEMM(1.0, H, Transpose(H*Sigma), 1.0, R) + POSV(Z, H) + POTRS(UofCholesky(Z), -1.0 * data + H*mu) + GEMM(1.0, H.T, A, 0.0, ZeroMatrix(*(H.T*A).shape)) + SYMM(1.0, Sigma, H.T*A, 1.0, mu) + GEMM(1.0, H.T, B, 0.0, ZeroMatrix(*(H.T*B).shape)) + SYMM(1.0, H.T*B, Sigma, 0.0, ZeroMatrix(*Sigma.shape)) + SYMM(-1.0, Sigma, H.T*B*Sigma, 1.0, Sigma)) # careful, overwrite return c
def test_satask(): # No relevant facts assert satask(Q.real(x), Q.real(x)) is True assert satask(Q.real(x), ~Q.real(x)) is False assert satask(Q.real(x)) is None assert satask(Q.real(x), Q.positive(x)) is True assert satask(Q.positive(x), Q.real(x)) is None assert satask(Q.real(x), ~Q.positive(x)) is None assert satask(Q.positive(x), ~Q.real(x)) is False raises(ValueError, lambda: satask(Q.real(x), Q.real(x) & ~Q.real(x))) with assuming(Q.positive(x)): assert satask(Q.real(x)) is True assert satask(~Q.positive(x)) is False raises(ValueError, lambda: satask(Q.real(x), ~Q.positive(x))) assert satask(Q.zero(x), Q.nonzero(x)) is False assert satask(Q.positive(x), Q.zero(x)) is False assert satask(Q.real(x), Q.zero(x)) is True assert satask(Q.zero(x), Q.zero(x*y)) is None assert satask(Q.zero(x*y), Q.zero(x))
def test_satask(): # No relevant facts assert satask(Q.real(x), Q.real(x)) is True assert satask(Q.real(x), ~Q.real(x)) is False assert satask(Q.real(x)) is None assert satask(Q.real(x), Q.positive(x)) is True assert satask(Q.positive(x), Q.real(x)) is None assert satask(Q.real(x), ~Q.positive(x)) is None assert satask(Q.positive(x), ~Q.real(x)) is False raises(ValueError, lambda: satask(Q.real(x), Q.real(x) & ~Q.real(x))) with assuming(Q.positive(x)): assert satask(Q.real(x)) is True assert satask(~Q.positive(x)) is False raises(ValueError, lambda: satask(Q.real(x), ~Q.positive(x))) assert satask(Q.zero(x), Q.nonzero(x)) is False assert satask(Q.positive(x), Q.zero(x)) is False assert satask(Q.real(x), Q.zero(x)) is True assert satask(Q.zero(x), Q.zero(x * y)) is None assert satask(Q.zero(x * y), Q.zero(x))
def test_iSend_fortran(): s = iSend(A, 2) with assuming(Q.real_elements(A)): result = s.fortran_call(['A'], ['request', 'ierr'])[0] expected = 'call MPI_iSend(A, %d, MPI_DOUBLE_PRECISION, 2, %d, MPI_COMM_WORLD, request, ierr)' % (A.rows*A.cols, s.tag) assert streq(result, expected)