├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── TODO.txt ├── benchmarks ├── 2d_convolution.py ├── __init__.py ├── allpairs_distances.py ├── arc_distance.py ├── collatz.py ├── compare_perf.py ├── diffuse.py ├── finite-difference.py ├── growcut.py ├── harris.py ├── julia.py ├── kmeans.py ├── matmult.py ├── matmult_tropical.py ├── morphology.py ├── nd_local_maxima.py ├── periodic_dist.py ├── pulseprop.py ├── rosenbrock.py ├── simple_conv.py ├── simple_regression.py ├── smoothing.py ├── sph_render.py ├── summation.py ├── template_sph_render.py ├── tensor_rotation.py ├── timer.py └── wald.py ├── examples ├── __init__.py ├── convolution.py ├── finite-difference.py ├── growcut.py ├── kmeans.py ├── matmult.py ├── rosenbrock.py ├── simple_avg.py ├── simple_regression.py ├── sum_loop.py └── tensor_rotation.py ├── parakeet ├── __init__.py ├── analysis │ ├── __init__.py │ ├── array_write_analysis.py │ ├── collect_vars.py │ ├── contains.py │ ├── escape_analysis.py │ ├── find_local_arrays.py │ ├── index_elim_analysis.py │ ├── inline_allowed.py │ ├── mutability_analysis.py │ ├── offset_analysis.py │ ├── syntax_visitor.py │ ├── use_analysis.py │ ├── usedef.py │ ├── value_range_analysis.py │ └── verify.py ├── builder │ ├── __init__.py │ ├── adverb_builder.py │ ├── arith_builder.py │ ├── array_builder.py │ ├── build_fn.py │ ├── builder.py │ ├── call_builder.py │ ├── core_builder.py │ └── loop_builder.py ├── c_backend │ ├── __init__.py │ ├── base_compiler.py │ ├── c_prims.py │ ├── compile_util.py │ ├── config.py │ ├── flags.py │ ├── fn_compiler.py │ ├── prepare_args.py │ ├── pymodule_compiler.py │ ├── reserved_names.py │ ├── run_function.py │ ├── shell_command.py │ ├── system_info.py │ └── type_mappings.py ├── config.py ├── cuda_backend │ ├── __init__.py │ ├── config.py │ ├── cuda_compiler.py │ ├── cuda_syntax.py │ ├── device_info.py │ └── run_function.py ├── frontend │ ├── __init__.py │ ├── ast_conversion.py │ ├── closure_specializations.py │ ├── decorators.py │ ├── diagnose.py │ ├── python_ref.py │ ├── run_function.py │ ├── type_conv_decls.py │ └── typed_repr.py ├── interp.py ├── lib │ ├── __init__.py │ ├── adverbs.py │ ├── array_constructors.py │ ├── array_properties.py │ ├── builtins.py │ ├── lib_helpers.py │ ├── linalg.py │ ├── math.py │ ├── numpy_misc.py │ ├── numpy_types.py │ ├── patchmap.py │ ├── prob.py │ ├── random.py │ └── reductions.py ├── llvm_backend │ ├── __init__.py │ ├── compiler.py │ ├── gv_helpers.py │ ├── llvm_config.py │ ├── llvm_context.py │ ├── llvm_convert.py │ ├── llvm_helpers.py │ ├── llvm_prims.py │ └── llvm_types.py ├── mappings.py ├── names.py ├── ndtypes │ ├── __init__.py │ ├── array_type.py │ ├── closure_type.py │ ├── core_types.py │ ├── dtypes.py │ ├── fn_type.py │ ├── ptr_type.py │ ├── scalar_types.py │ ├── slice_type.py │ ├── tuple_type.py │ └── type_conv.py ├── openmp_backend │ ├── __init__.py │ ├── config.py │ ├── multicore_compiler.py │ └── run_function.py ├── package_info.py ├── prims.py ├── shape_inference │ ├── __init__.py │ ├── shape.py │ ├── shape_codegen.py │ ├── shape_eval.py │ ├── shape_from_type.py │ └── shape_inference.py ├── syntax │ ├── __init__.py │ ├── actual_args.py │ ├── adverb_helpers.py │ ├── adverbs.py │ ├── array_expr.py │ ├── delay_until_typed.py │ ├── expr.py │ ├── formal_args.py │ ├── helpers.py │ ├── list_expr.py │ ├── low_level.py │ ├── seq_expr.py │ ├── source_info.py │ ├── stmt.py │ ├── tuple_expr.py │ ├── type_value.py │ ├── typed_fn.py │ ├── untyped_fn.py │ └── wrappers.py ├── system_info.py ├── testing_helpers.py ├── transforms │ ├── __init__.py │ ├── clone_function.py │ ├── clone_stmt.py │ ├── combine_nested_maps.py │ ├── copy_elimination.py │ ├── dead_code_elim.py │ ├── flattening.py │ ├── fusion.py │ ├── imap_elim.py │ ├── index_elimination.py │ ├── indexify_adverbs.py │ ├── inline.py │ ├── licm.py │ ├── loop_transform.py │ ├── loop_unrolling.py │ ├── lower_adverbs.py │ ├── lower_array_operators.py │ ├── lower_indexing.py │ ├── lower_slices.py │ ├── lower_structs.py │ ├── negative_index_elim.py │ ├── offset_propagation.py │ ├── parallelize_loops.py │ ├── parfor_to_nested_loops.py │ ├── permute_reductions.py │ ├── phase.py │ ├── pipeline.py │ ├── range_propagation.py │ ├── range_transform.py │ ├── recursive_apply.py │ ├── redundant_load_elim.py │ ├── scalar_replacement.py │ ├── shape_elim.py │ ├── simplify.py │ ├── simplify_array_operators.py │ ├── specialize_fn_args.py │ ├── subst.py │ ├── transform.py │ └── vectorize.py ├── type_inference │ ├── __init__.py │ ├── helpers.py │ ├── linearize_args.py │ ├── local_inference.py │ ├── rewrite_typed.py │ ├── type_inference.py │ └── var_map.py └── value_specialization │ ├── __init__.py │ ├── abstract_value.py │ ├── find_constant_values.py │ └── value_specialization.py ├── requirements.txt ├── setup.py └── test ├── __init__.py ├── adverbs ├── __init__.py ├── test_allpairs.py ├── test_imap.py ├── test_map.py ├── test_outer_prod.py ├── test_par_each.py ├── test_reduce.py └── test_scan.py ├── algorithms ├── __init__.py ├── test_2d_diff.py ├── test_arc_distance.py ├── test_black_scholes.py ├── test_conv.py ├── test_diffuse.py ├── test_dist.py ├── test_dot.py ├── test_find_border.py ├── test_floyd_warshall.py ├── test_growcut.py ├── test_harris_corner.py ├── test_histogram_intersection.py ├── test_hyst.py ├── test_is_prime.py ├── test_julia.py ├── test_kmeans.py ├── test_local_maxima.py ├── test_matmult_allpairs.py ├── test_matmult_comprehensions.py ├── test_matmult_loops.py ├── test_matmult_tropical.py ├── test_maxpool.py ├── test_nn.py ├── test_nn_simple.py ├── test_norm.py ├── test_partialDU.py ├── test_rad2deg.py ├── test_rotate.py ├── test_rule_30.py ├── test_simple_regression.py ├── test_sph_kernel.py ├── test_sph_render.py ├── test_sum_primes.py ├── test_tanh_rescale.py └── test_thresholds.py ├── arrays ├── __init__.py ├── test_arange.py ├── test_array_literal.py ├── test_assign_slice.py ├── test_broadcasting.py ├── test_empty.py ├── test_fancy_indexing.py ├── test_indexing.py ├── test_methods.py ├── test_negative_indexing.py ├── test_ones.py ├── test_ones_like.py ├── test_properties.py ├── test_range.py ├── test_ravel.py ├── test_setidx.py ├── test_slice_arith.py ├── test_slices.py ├── test_zeros.py └── test_zeros_like.py ├── builtins ├── __init__.py ├── test_max.py ├── test_min.py ├── test_range.py ├── test_sum.py └── test_types.py ├── compiler ├── __init__.py ├── test_call_overhead.py ├── test_codegen_add_scalars.py ├── test_codegen_add_vecs.py ├── test_codegen_identity.py ├── test_codegen_sum_loop.py ├── test_escape_analysis.py ├── test_licm.py ├── test_mutability_analysis.py ├── test_optimizations.py ├── test_shape_inference.py ├── test_subtypes.py ├── test_type_inference.py └── test_value_range_analysis.py ├── core_language ├── __init__.py ├── test_args.py ├── test_arith.py ├── test_cast.py ├── test_closure_args.py ├── test_div_bool.py ├── test_lambda.py ├── test_list_comp.py ├── test_loops.py ├── test_modulo.py ├── test_simple.py ├── test_square.py ├── test_tuples.py ├── test_type_values.py └── test_zip.py ├── neighborhood ├── __init__.py ├── test_morphology.py ├── test_patchmap.py └── test_windowed.py └── numpy_lib ├── __init__.py ├── test_dot.py ├── test_linspace.py ├── test_log1p.py ├── test_logaddexp2.py ├── test_prob.py ├── test_rint.py ├── test_sum.py ├── test_transcendental.py ├── test_ufunc_math_binary.py ├── test_ufunc_math_unary.py └── test_ufunc_trig.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .pydevproject 3 | .project 4 | runtime/*.o 5 | runtime/*.so 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | 5 | #virtualenv: 6 | # system_site_packages: true 7 | 8 | #before_install: 9 | # - sudo apt-get install build-essential python-dev python-setuptools 10 | # - sudo apt-get install -qq python-dev python-setuptools python-numpy python-scipy python-numpy-dev 11 | 12 | # command to install dependencies 13 | install: "pip install -r requirements.txt --use-mirrors" 14 | 15 | # # command to run tests 16 | script: nosetests test 17 | 18 | branches: 19 | only: 20 | - master 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | New BSD License 2 | 3 | Copyright (c) 2013 - Alex Rubinsteyn. 4 | All rights reserved. 5 | 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | a. Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | b. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | c. Neither the name of the Scikit-learn Developers nor the names of 16 | its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written 18 | permission. 19 | 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 31 | DAMAGE. 32 | 33 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.md 2 | include *.txt 3 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | Now: 2 | - fill in ParFor.read_only/write_only to avoid extra copying to/from the GPU 3 | - Indexing by boolean masks 4 | - LShift/RShift prims 5 | - Short-Circuit Or/And expressions 6 | - Multiple comparisons chained with short-circuit And 7 | 8 | Soon: 9 | - Coarse parallelism for groups of IndexReduce/IndexScan results 10 | - Fine grained tree-structured parallelism for IndexReduce/IndexScan inside CUDA kernels 11 | - Support 'output' parameter of ufuncs 12 | - PreallocArrays to move locally used allocation of arrays out functions into their calling scope 13 | - Garbage collection (or, at least, statically inferred deallocations) 14 | 15 | On pause: 16 | - Adverb semantics for conv 17 | - Code generation for conv 18 | 19 | Maybe never? 20 | - Adverb-level vectorization 21 | - Revive the LLVM backend but using the Python C API at the extension boundary, use as default for Windows 22 | 23 | Old: 24 | - Run tiling on perfectly nested code 25 | -------------------------------------------------------------------------------- /benchmarks/2d_convolution.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | import numpy as np 3 | from timer import compare_perf 4 | 5 | 6 | 7 | 8 | def clamp(i, offset, maxval): 9 | j = max(0, i + offset) 10 | return min(j, maxval) 11 | 12 | 13 | def reflect(pos, offset, bound): 14 | idx = pos+offset 15 | return min(2*(bound-1)-idx,max(idx,-idx)) 16 | 17 | 18 | def conv(x, weights, mode=clamp): 19 | sx = x.shape 20 | sw = weights.shape 21 | result = np.zeros_like(x) 22 | for i in xrange(sx[0]): 23 | for j in xrange(sx[1]): 24 | for ii in xrange(sw[0]): 25 | for jj in xrange(sw[1]): 26 | idx = mode(i,ii-sw[0]/2,sw[0]), mode(j,jj-sw[0]/2,sw[0]) 27 | result[i,j] += x[idx] * weights[ii,jj] 28 | return result 29 | 30 | 31 | xsize = (300,300) 32 | x = np.random.randn(*xsize) 33 | wsize = (5,5) 34 | w = np.random.randn(*wsize) 35 | 36 | compare_perf(conv, [x,w]) 37 | -------------------------------------------------------------------------------- /benchmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/benchmarks/__init__.py -------------------------------------------------------------------------------- /benchmarks/allpairs_distances.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def sqr_dists(X,Y): 4 | return np.array([[np.sum( (x-y) ** 2) for x in X] for y in Y]) 5 | 6 | def sqr_dists_loops(X,Y): 7 | m,n = X.shape[0], Y.shape[0] 8 | D = np.zeros((m,n), dtype=X.dtype) 9 | for i in xrange(m): 10 | for j in xrange(n): 11 | D[i,j] = np.sum( (X[i, :] -Y[j, :]) ** 2) 12 | return D 13 | 14 | ndims = 10 15 | nsamples = 10**4 16 | nclusters = 50 17 | X = np.random.randn(nsamples, ndims) 18 | Y = np.random.randn(nclusters, ndims) 19 | 20 | 21 | 22 | 23 | from timer import timer 24 | 25 | print 26 | print "Computing distances between %d and %d %s vectors of length %d" % \ 27 | (nsamples, nclusters, X.dtype, ndims) 28 | 29 | # 30 | # Parakeet 31 | # 32 | 33 | import parakeet 34 | 35 | parakeet_dists = parakeet.jit(sqr_dists) 36 | 37 | with timer('Parakeet (comprehensions) #1'): 38 | parakeet_dists(X,Y) 39 | 40 | with timer('Parakeet (comprehensions) #2'): 41 | parakeet_dists(X,Y) 42 | 43 | parakeet_dists_loops = parakeet.jit(sqr_dists_loops) 44 | 45 | with timer('Parakeet (loops) #1'): 46 | parakeet_dists_loops(X,Y) 47 | 48 | with timer('Parakeet (loops) #2'): 49 | parakeet_dists_loops(X,Y) 50 | 51 | 52 | 53 | # 54 | # Pure Python 55 | # 56 | from timer import timer 57 | 58 | with timer('Python (comprehensions)'): 59 | sqr_dists(X,Y) 60 | 61 | with timer('Python (loops)'): 62 | sqr_dists_loops(X,Y) 63 | 64 | 65 | 66 | # 67 | # Numba 68 | # 69 | 70 | import numba 71 | 72 | # 73 | # Numba's @autojit just like Parakeet's @jit 74 | # 75 | numba_dists = numba.autojit(sqr_dists) 76 | 77 | with timer('Numba (comprehensions) #1'): 78 | numba_dists(X,Y) 79 | 80 | with timer('Numba (comprehensions) #2'): 81 | numba_dists(X,Y) 82 | 83 | numba_dists_loops = numba.autojit(sqr_dists_loops) 84 | 85 | with timer('Numba (loops) #1'): 86 | numba_dists_loops(X,Y) 87 | 88 | with timer('Numba (loops) #2'): 89 | numba_dists_loops(X,Y) 90 | 91 | -------------------------------------------------------------------------------- /benchmarks/collatz.py: -------------------------------------------------------------------------------- 1 | # 2 | # Longest hailstone sequence from http://www.mit.edu/~mtikekar/posts/stream-fusion.html 3 | # 4 | import sys 5 | 6 | def collatzLen(a0): 7 | a = a0 8 | length = 0 9 | while a != 1: 10 | a = (a if a%2 == 0 else 3*a+1) / 2 11 | length += 1 12 | return length 13 | 14 | def maxLen(max_a0): 15 | max_length = 0 16 | longest = 0 17 | for a0 in xrange(1, max_a0 + 1): 18 | length = collatzLen(a0) 19 | if length > max_length: 20 | max_length = length 21 | longest = a0 22 | return max_length, longest 23 | 24 | from compare_perf import compare_perf 25 | 26 | compare_perf(maxLen, [1000000]) 27 | 28 | -------------------------------------------------------------------------------- /benchmarks/diffuse.py: -------------------------------------------------------------------------------- 1 | # 2 | # Code taken from Numba's documentation at http://numba.pydata.org/numba-doc/0.11/arrays.html 3 | # 4 | 5 | import numpy as np 6 | 7 | mu = 0.1 8 | Lx, Ly = 101, 101 9 | N = 1000 10 | import parakeet 11 | import parakeet.c_backend 12 | #parakeet.c_backend.config.print_module_source = True 13 | 14 | 15 | def diffuse_loops(iter_num): 16 | u = np.zeros((Lx, Ly), dtype=np.float64) 17 | temp_u = np.zeros_like(u) 18 | temp_u[Lx / 2, Ly / 2] = 1000.0 19 | 20 | for n in range(iter_num): 21 | for i in range(1, Lx - 1): 22 | for j in range(1, Ly - 1): 23 | u[i, j] = mu * (temp_u[i + 1, j] + temp_u[i - 1, j] + 24 | temp_u[i, j + 1] + temp_u[i, j - 1] - 25 | 4 * temp_u[i, j]) 26 | 27 | temp = u 28 | u = temp_u 29 | temp_u = temp 30 | 31 | return u 32 | 33 | def diffuse_array_expressions(iter_num): 34 | u = np.zeros((Lx, Ly), dtype=np.float64) 35 | temp_u = np.zeros_like(u) 36 | temp_u[Lx / 2, Ly / 2] = 1000.0 37 | 38 | for i in range(iter_num): 39 | u[1:-1, 1:-1] = mu * (temp_u[2:, 1:-1] + temp_u[:-2, 1:-1] + 40 | temp_u[1:-1, 2:] + temp_u[1:-1, :-2] - 41 | 4 * temp_u[1:-1, 1:-1]) 42 | 43 | temp = u 44 | u = temp_u 45 | temp_u = temp 46 | return u 47 | 48 | 49 | from compare_perf import compare_perf 50 | 51 | compare_perf(diffuse_loops, [N], numba=True) 52 | compare_perf( diffuse_array_expressions, [N], numba =True) 53 | -------------------------------------------------------------------------------- /benchmarks/finite-difference.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def fdtd(input_grid, steps): 4 | grid = input_grid.copy() 5 | old_grid = np.zeros_like(input_grid) 6 | previous_grid = np.zeros_like(input_grid) 7 | 8 | l_x = grid.shape[0] 9 | l_y = grid.shape[1] 10 | 11 | for i in range(steps): 12 | previous_grid[:, :] = old_grid 13 | old_grid[:, :] = grid 14 | for x in range(l_x): 15 | for y in range(l_y): 16 | grid[x,y] = 0.0 17 | if x + 1 < l_x: 18 | grid[x,y] += old_grid[x+1,y] 19 | if 0 < x-1 and x - 1 < l_x: 20 | grid[x,y] += old_grid[x-1,y] 21 | if y+1 < l_y: 22 | grid[x,y] += old_grid[x,y+1] 23 | if 0 < y-1 and y-1 < l_y: 24 | grid[x,y] += old_grid[x,y-1] 25 | grid[x,y] /= 2.0 26 | grid[x,y] -= previous_grid[x,y] 27 | return grid 28 | 29 | N = 1000 30 | steps = 20 31 | input_grid = np.random.randn(N,N).astype('float64') 32 | 33 | import parakeet 34 | parakeet.config.print_generated_code = True 35 | 36 | from compare_perf import compare_perf 37 | compare_perf(fdtd, [input_grid, steps], backends = ('c', 'openmp', 'cuda')) 38 | 39 | 40 | -------------------------------------------------------------------------------- /benchmarks/harris.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | 5 | def harris(I): 6 | m,n = I.shape 7 | dx = (I[1:, :] - I[:m-1, :])[:, 1:] 8 | dy = (I[:, 1:] - I[:, :n-1])[1:, :] 9 | 10 | # 11 | # At each point we build a matrix 12 | # of derivative products 13 | # M = 14 | # | A = dx^2 C = dx * dy | 15 | # | C = dy * dx B = dy * dy | 16 | # 17 | # and the score at that point is: 18 | # det(M) - k*trace(M)^2 19 | # 20 | A = dx * dx 21 | B = dy * dy 22 | C = dx * dy 23 | tr = A + B 24 | det = A * B - C * C 25 | k = np.float32(0.05) 26 | return det - k * tr * tr 27 | 28 | from compare_perf import compare_perf 29 | m,n = 2400, 2400 30 | dtype = 'float32' 31 | I = (np.random.randn(m,n) ** 2).astype(dtype) 32 | 33 | compare_perf(harris, [I], propagate_exceptions=True) 34 | -------------------------------------------------------------------------------- /benchmarks/julia.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import testing_helpers 3 | 4 | def kernel(zr, zi, cr, ci, lim, cutoff): 5 | ''' Computes the number of iterations `n` such that 6 | |z_n| > `lim`, where `z_n = z_{n-1}**2 + c`. 7 | ''' 8 | count = np.uint32(0) 9 | while ((zr*zr + zi*zi) < (lim*lim)) and count < cutoff: 10 | zr, zi = zr * zr - zi * zi + cr, 2 * zr * zi + ci 11 | count += np.uint32(1) 12 | return count 13 | 14 | def julia_loops(cr, ci, N, bound=1.5, lim=1000., cutoff=1e6): 15 | ''' Pure Python calculation of the Julia set for a given `c`. No NumPy 16 | array operations are used. 17 | ''' 18 | julia = np.empty((N, N), dtype=np.uint32) 19 | grid_x = np.linspace(-bound, bound, N) 20 | for i, x in enumerate(grid_x): 21 | for j, y in enumerate(grid_x): 22 | julia[i,j] = kernel(x, y, cr, ci, lim, cutoff=cutoff) 23 | return julia 24 | 25 | def julia(cr, ci, N, bound=1.5, lim=1000., cutoff=1e6): 26 | grid_x = np.linspace(-bound, bound, N) 27 | return np.array([[kernel(x,y,cr,ci,lim,cutoff=cutoff) 28 | for x in grid_x] 29 | for y in grid_x]) 30 | 31 | from compare_perf import compare_perf 32 | cr=0.285 33 | ci=0.01 34 | N=1200 35 | bound = 1.5 36 | lim = 1000 37 | cutoff = 1e6 38 | 39 | extra = {} 40 | try: 41 | from numba import autojit 42 | extra['numba'] = autojit(julia_loops) 43 | except: 44 | print "Failed to import Numba" 45 | 46 | compare_perf(julia, [cr, ci, N, bound, lim, cutoff], numba = False, extra = extra) 47 | 48 | -------------------------------------------------------------------------------- /benchmarks/kmeans.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | import numpy as np 3 | 4 | 5 | def dist(x,y): 6 | return ((x-y)**2).sum() 7 | 8 | def kmeans_comprehensions(X, k, niters = 10): 9 | C = X[:k, :] 10 | for _ in xrange(niters): 11 | A = np.array([np.argmin([dist(x,c) for c in C]) for x in X]) 12 | C = np.array([np.mean(X[A == i, :], axis = 0) for i in xrange(k)]) 13 | return C 14 | 15 | def kmeans_loops(X, k, niters = 10): 16 | C = X[:k, :] 17 | n,ndims = X.shape 18 | A = np.zeros(n, dtype=int) 19 | for _ in xrange(niters): 20 | # assign data points to nearest centroid 21 | for i in xrange(n): 22 | x = X[i,:] 23 | min_dist = dist(x, C[0, :]) 24 | min_idx = 0 25 | for cidx in xrange(1,k): 26 | centroid = C[cidx,:] 27 | curr_dist = 0.0 28 | for xidx in xrange(ndims): 29 | curr_dist += (x[xidx] - centroid[xidx])**2 30 | if curr_dist < min_dist: 31 | min_dist = curr_dist 32 | min_idx = cidx 33 | A[i] = min_idx 34 | # recompute the clusters by averaging data points 35 | # assigned to them 36 | for cidx in xrange(k): 37 | # reset centroids 38 | for dim_idx in xrange(ndims): 39 | C[cidx, dim_idx] = 0 40 | # add each data point only to its assigned centroid 41 | cluster_count = 0 42 | for i in xrange(n): 43 | if A[i] == cidx: 44 | C[cidx, :] += X[i, :] 45 | cluster_count += 1 46 | C[cidx, :] /= cluster_count 47 | return C 48 | 49 | n, d = 10**4, 50 50 | X = np.random.randn(n,d) 51 | k = 25 52 | 53 | from compare_perf import compare_perf 54 | 55 | compare_perf(kmeans_comprehensions, [X, k, 5],cpython=False) 56 | 57 | compare_perf(kmeans_loops, [X, k, 5], cpython=True) 58 | -------------------------------------------------------------------------------- /benchmarks/matmult.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | import numpy as np 3 | def matmult_high_level(X,Y): 4 | return np.array([[np.dot(x,y) for y in Y.T] for x in X]) 5 | 6 | 7 | # 8 | #n, d = 2500, 20 9 | #m = 2500 10 | 11 | n,d,m = 1200,1200,1200 12 | dtype = 'float32' 13 | X = np.random.randn(m,d).astype(dtype) 14 | Y = np.random.randn(d,n).astype(dtype) 15 | 16 | from compare_perf import compare_perf 17 | 18 | extra = {'BLAS (np.dot)' : np.dot} 19 | try: 20 | import pycuda 21 | import pycuda.gpuarray 22 | import pycuda.autoinit 23 | 24 | import scikits.cuda.linalg 25 | import scikits.cuda.cublas 26 | cublas_context = scikits.cuda.cublas.cublasCreate() 27 | def gpu_dot(X,Y): 28 | X_gpu = pycuda.gpuarray.to_gpu(X) 29 | Y_gpu = pycuda.gpuarray.to_gpu(Y) 30 | Z_gpu = scikits.cuda.linalg.dot(X_gpu, Y_gpu, 'N', 'N', handle = cublas_context) 31 | return Z_gpu.get() 32 | extra['cuBLAS'] = gpu_dot 33 | except: 34 | print "Failed to import PyCUDA + scikits.cuda" 35 | 36 | try: 37 | import numba 38 | 39 | @numba.autojit 40 | def matmult_loops(X,Y,Z): 41 | m, d = X.shape 42 | n = Y.shape[1] 43 | for i in xrange(m): 44 | for j in xrange(n): 45 | total = X[i,0] * Y[0,j] 46 | for k in xrange(1,d): 47 | total += X[i,k] * Y[k,j] 48 | Z[i,j] = total 49 | 50 | def call_numba(X,Y): 51 | Z = np.zeros((X.shape[0],Y.shape[1])).astype(dtype) 52 | matmult_loops(X,Y,Z) 53 | return Z 54 | 55 | extra['numba'] = call_numba 56 | 57 | except: 58 | print "Failed to import Numba" 59 | pass 60 | 61 | compare_perf(matmult_high_level, [X,Y], 62 | cpython=True, 63 | # numba can't run the nested comprehensions so we use 64 | # a special loopy version instead 65 | numba=False, 66 | extra = extra, 67 | suppress_output = False, 68 | propagate_exceptions = False) 69 | 70 | -------------------------------------------------------------------------------- /benchmarks/matmult_tropical.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | import numpy as np 3 | 4 | 5 | def dot(x,y): 6 | return np.min(x+y) 7 | 8 | def matmult_high_level(X,Y): 9 | return np.array([[dot(x,y) for y in Y.T] for x in X]) 10 | 11 | def matmult_loops(X,Y,Z): 12 | m, d = X.shape 13 | n = Y.shape[1] 14 | for i in xrange(m): 15 | for j in xrange(n): 16 | total = X[i,0] + Y[0,j] 17 | for k in xrange(1,d): 18 | total = min(total, X[i,k] + Y[k,j]) 19 | Z[i,j] = total 20 | return Z 21 | 22 | n, d = 500, 500 23 | m = 500 24 | X = np.random.randn(m,d) 25 | Y = np.random.randn(d,n) 26 | Z = np.zeros((m,n)) 27 | from compare_perf import compare_perf 28 | 29 | compare_perf(matmult_high_level, [X,Y], cpython=True, numba=False) 30 | compare_perf(matmult_loops, [X, Y, Z], cpython=False) 31 | 32 | -------------------------------------------------------------------------------- /benchmarks/nd_local_maxima.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | 4 | def wrap(pos, offset, bound): 5 | return ( pos + offset ) % bound 6 | 7 | def clamp(pos, offset, bound): 8 | return min(bound-1,max(0,pos+offset)) 9 | 10 | def reflect(pos, offset, bound): 11 | idx = pos+offset 12 | return min(2*(bound-1)-idx,max(idx,-idx)) 13 | 14 | 15 | def local_maxima(data, wsize, mode=wrap): 16 | result = np.ones(shape=data.shape,dtype=bool) 17 | for pos in np.ndindex(data.shape): 18 | myval = data[pos] 19 | for offset in np.ndindex(wsize): 20 | neighbor_idx = tuple(mode(p, o-w/2, w) for (p, o, w) in zip(pos, offset, wsize)) 21 | result[pos] &= (data[neighbor_idx] <= myval) 22 | return result 23 | 24 | 25 | @parakeet.jit 26 | def parakeet_local_maxima(data, wsize, mode=wrap): 27 | def is_max(pos): 28 | def is_smaller_neighbor(offset): 29 | neighbor_idx = tuple(mode(p, o-w/2, w) for (p, o, w) in zip(pos, offset, wsize)) 30 | return data[neighbor_idx] <= data[pos] 31 | return np.all(parakeet.imap(is_smaller_neighbor, wsize)) 32 | return parakeet.imap(is_max, data.shape) 33 | 34 | 35 | # not sure how to get numba to auto-jit size generic code 36 | # get error: "FAILED with KeyError 'sized_pointer(npy_intp, 4)'" 37 | #import numba 38 | #numba_local_maxima = numba.autojit(python_local_maxima) 39 | 40 | from compare_perf import compare_perf 41 | 42 | shape = (30,30,20,12) 43 | x = np.random.randn(*shape) 44 | compare_perf(local_maxima, [x, shape]) 45 | -------------------------------------------------------------------------------- /benchmarks/rosenbrock.py: -------------------------------------------------------------------------------- 1 | 2 | # Rosenbrock function derivative 3 | # 4 | # Copied from https://github.com/numfocus/python-benchmarks/blob/master/rosen_der/rosen_der_python.py 5 | # Original authors: Travis Oliphant (NumPy version) & Serge Guelton (loops version) 6 | # 7 | 8 | import numpy as np 9 | from parakeet import jit 10 | 11 | def rosen_der_np(x): 12 | der = np.empty_like(x) 13 | der[1:-1] = (+ 200 * (x[1:-1] - x[:-2] ** 2) 14 | - 400 * (x[2:] - x[1:-1] ** 2) * x[1:-1] 15 | - 2 * (1 - x[1:-1])) 16 | der[0] = -400 * x[0] * (x[1] - x[0] ** 2) - 2 * (1 - x[0]) 17 | der[-1] = 200 * (x[-1] - x[-2] ** 2) 18 | return der 19 | 20 | def rosen_der_loops(x): 21 | n = x.shape[0] 22 | der = np.empty_like(x) 23 | 24 | for i in range(1, n - 1): 25 | der[i] = (+ 200 * (x[i] - x[i - 1] ** 2) 26 | - 400 * (x[i + 1] 27 | - x[i] ** 2) * x[i] 28 | - 2 * (1 - x[i])) 29 | der[0] = -400 * x[0] * (x[1] - x[0] ** 2) - 2 * (1 - x[0]) 30 | der[-1] = 200 * (x[-1] - x[-2] ** 2) 31 | return der 32 | 33 | if __name__ == '__main__': 34 | N = 10**7 35 | x = np.arange(N) / float(N) 36 | jit(rosen_der_np)(x) 37 | from compare_perf import compare_perf 38 | # numba still crashes on negative indexing 39 | compare_perf(rosen_der_np, [x.copy()], numba=False) 40 | compare_perf(rosen_der_loops, [x.copy()], numba=False) 41 | -------------------------------------------------------------------------------- /benchmarks/simple_conv.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from compare_perf import compare_perf 3 | 4 | # Simple convolution of 3x3 patches from a given array x 5 | # by a 3x3 array of filter weights 6 | 7 | def conv_3x3_trim(x, weights): 8 | return np.array([[(x[i-1:i+2, j-1:j+2]*weights).sum() 9 | for j in xrange(1, x.shape[1] -2)] 10 | for i in xrange(1, x.shape[0] -2)]) 11 | 12 | x = np.random.randn(1500,1500).astype('float32') 13 | w = np.random.randn(3,3).astype('float32') 14 | #compare_perf(conv_3x3_trim, [x,w]) 15 | 16 | w = np.random.randn(3,3).astype('float32') 17 | # Simple convolution of 5x5 patches from a given array x 18 | # by a 5x5 array of filter weights 19 | 20 | def conv_3x3_trim_loops(image, weights): 21 | result = np.zeros_like(image) 22 | for i in xrange(1,x.shape[0]-1): 23 | for j in xrange(1,x.shape[1]-1): 24 | for ii in xrange(3): 25 | for jj in xrange(3): 26 | result[i,j] += image[i-ii+1, j-jj+1] * weights[ii, jj] 27 | return result 28 | 29 | compare_perf(conv_3x3_trim_loops, [x,w]) 30 | 31 | import parakeet 32 | def conv_3x3_imap(image, weights): 33 | def compute((i,j)): 34 | total = np.float32(0.0) 35 | for ii in xrange(3): 36 | for jj in xrange(3): 37 | total += image[i+ii-1, j + jj - 1] * weights[ii, jj] 38 | return total 39 | w,h = image.shape 40 | return parakeet.imap(compute, (w-2,h-2)) 41 | compare_perf(conv_3x3_imap, [x,w], backends=('openmp', 'cuda',)) 42 | -------------------------------------------------------------------------------- /benchmarks/simple_regression.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit, config, c_backend 2 | 3 | 4 | 5 | def covariance(x,y): 6 | return ((x-x.mean()) * (y-y.mean())).mean() 7 | 8 | def fit_simple_regression(x,y): 9 | slope = covariance(x,y) / covariance(x,x) 10 | offset = y.mean() - slope * x.mean() 11 | return slope, offset 12 | 13 | import numpy as np 14 | 15 | N = 2*10**7 16 | x = np.random.randn(N).astype('float64') 17 | slope = 903.29 18 | offset = 102.1 19 | y = slope * x + offset 20 | 21 | 22 | 23 | from compare_perf import compare_perf 24 | compare_perf(fit_simple_regression, (x,y), numba=True) 25 | -------------------------------------------------------------------------------- /benchmarks/smoothing.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def smooth(x, alpha): 5 | s = x.copy() 6 | for i in xrange(1, len(x)): 7 | s[i] = alpha * x[i] + (1-alpha)*s[i-1] 8 | return s 9 | 10 | n = 10**6 11 | alpha = 0.01 12 | X = np.random.randn(n).astype('float32') 13 | 14 | from compare_perf import compare_perf 15 | compare_perf(smooth, [X, alpha]) 16 | 17 | -------------------------------------------------------------------------------- /benchmarks/summation.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | def summation(pos, weights, points): 4 | n_points = len(points) 5 | n_weights = len(weights) 6 | sum_array = np.zeros(n_points) 7 | sum_array3d = np.zeros((n_points,3)) 8 | def compute(i): 9 | pxi = points[i, 0] 10 | pyi = points[i, 1] 11 | pzi = points[i, 2] 12 | total = 0.0 13 | for j in xrange(n_weights): 14 | weight_j = weights[j] 15 | xj = pos[j,0] 16 | yj = pos[j,1] 17 | zj = pos[j,2] 18 | dx = pxi - pos[j, 0] 19 | dy = pyi - pos[j, 1] 20 | dz = pzi - pos[j, 2] 21 | dr = 1.0/np.sqrt(dx*dx + dy*dy + dz*dz) 22 | total += weight_j * dr 23 | sum_array3d[i,0] += weight_j * dx 24 | sum_array3d[i,1] += weight_j * dy 25 | sum_array3d[i,2] += weight_j * dz 26 | return total 27 | sum_array = np.array([compute(i) for i in xrange(n_points)]) 28 | return sum_array, sum_array3d 29 | 30 | n_points = 200 31 | n_weights = 400 32 | pos = np.random.randn(n_weights, 3) 33 | weights = np.random.randn(n_weights) 34 | points = np.random.randn(n_points, 3) 35 | 36 | from compare_perf import compare_perf 37 | 38 | compare_perf(summation, [pos, weights, points]) 39 | -------------------------------------------------------------------------------- /benchmarks/tensor_rotation.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | # 4 | # Tensor rotation 5 | # from Peter Mortensen's stackoverflow question 6 | # @ http://stackoverflow.com/questions/4962606/fast-tensor-rotation-with-numpy/18301915 7 | # 8 | 9 | n = 9 10 | def rotT_loops(T, g): 11 | Tprime = np.zeros((n,n,n,n)) 12 | for i in range(n): 13 | for j in range(n): 14 | for k in range(n): 15 | for l in range(n): 16 | for ii in range(n): 17 | for jj in range(n): 18 | for kk in range(n): 19 | for ll in range(n): 20 | gg = g[ii,i]*g[jj,j]*g[kk,k]*g[ll,l] 21 | Tprime[i,j,k,l] = Tprime[i,j,k,l] + gg*T[ii,jj,kk,ll] 22 | return Tprime 23 | 24 | def rotT_numpy(T, g): 25 | """ 26 | Accepted response on stack overflow by phillip 27 | """ 28 | gg = np.outer(g, g) 29 | gggg = np.outer(gg, gg).reshape(4 * g.shape) 30 | axes = ((0, 2, 4, 6), (0, 1, 2, 3)) 31 | return np.tensordot(gggg, T, axes) 32 | 33 | T = np.random.randn(n,n,n,n) 34 | g = np.random.randn(n,n) 35 | 36 | from compare_perf import compare_perf 37 | compare_perf(rotT_loops, [T, g], extra = {'numpy_tensordot': rotT_numpy}, numba= False, backends=('c', 'openmp'), cpython=True) 38 | 39 | 40 | def rotT_par(T, g): 41 | def compute_elt(i,j,k,l): 42 | total = 0.0 43 | for ii in range(n): 44 | for jj in range(n): 45 | for kk in range(n): 46 | for ll in range(n): 47 | gg = g[ii,i]*g[jj,j]*g[kk,k]*g[ll,l] 48 | total += gg*T[ii,jj,kk,ll] 49 | return total 50 | return np.array([[[[compute_elt(i,j,k,l) 51 | for k in xrange(n)] 52 | for l in xrange(n)] 53 | for j in xrange(n)] 54 | for i in xrange(n)]) 55 | compare_perf(rotT_par, [T, g], extra = {'numpy_tensordot': rotT_numpy}, numba= False, backends=('c', 'openmp'), cpython = True) 56 | -------------------------------------------------------------------------------- /benchmarks/timer.py: -------------------------------------------------------------------------------- 1 | 2 | import cStringIO 3 | import os 4 | import sys 5 | import time 6 | import tempfile 7 | 8 | class timer(object): 9 | def __init__(self, name = None, newline = True, 10 | suppress_stdout = True, 11 | suppress_stderr = True, 12 | propagate_exceptions = False): 13 | self.name = name 14 | self.start_t = time.time() 15 | self.newline = newline 16 | self.suppress_stdout = suppress_stdout 17 | self.suppress_stderr = suppress_stderr 18 | self.propagate_exceptions = propagate_exceptions 19 | def __enter__(self): 20 | if self.suppress_stdout: 21 | stdout_newfile = tempfile.NamedTemporaryFile() 22 | self.prev_stdout_fd = os.dup(sys.stdout.fileno()) 23 | os.dup2(stdout_newfile.fileno(), sys.stdout.fileno()) 24 | self.prev_stdout = sys.stdout 25 | 26 | if self.suppress_stderr: 27 | stderr_newfile = tempfile.NamedTemporaryFile() 28 | self.prev_stderr_fd = os.dup(sys.stderr.fileno()) 29 | os.dup2(stderr_newfile.fileno(), sys.stderr.fileno()) 30 | self.prev_stderr = sys.stderr 31 | 32 | self.start_t = time.time() 33 | 34 | 35 | def elapsed(self): 36 | return time.time() - self.start_t 37 | 38 | def __exit__(self, exc_type, exc_value, traceback): 39 | t = self.elapsed() 40 | if self.suppress_stdout: 41 | os.dup2(self.prev_stdout_fd, self.prev_stdout.fileno()) 42 | if self.suppress_stderr: 43 | os.dup2(self.prev_stderr_fd, self.prev_stderr.fileno()) 44 | if self.newline: 45 | print 46 | s = "Elapsed time: " if self.name is None else "%s : " % self.name 47 | if exc_type is None: 48 | s += "%0.4f" % t 49 | else: 50 | name = str(exc_type) if exc_type.__name__ is None else exc_type.__name__ 51 | s += "FAILED with %s '%s'" % (name, exc_value) 52 | print s 53 | # don't raise exceptions 54 | if self.propagate_exceptions: 55 | return False 56 | else: 57 | return exc_type is not KeyboardInterrupt 58 | 59 | 60 | -------------------------------------------------------------------------------- /benchmarks/wald.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit, config 2 | import time 3 | import numpy as np 4 | def wald(v, a, rands, u_rands, sigma, accum): 5 | mu = a / v 6 | lam = a**2 / sigma**2 7 | y = rands[:, accum]**2 8 | x = mu + (mu**2. * y) / (2.*lam) - mu / (2.*lam) * np.sqrt(4.*mu*lam*y + mu**2. * y**2.) 9 | z = u_rands[:, accum] 10 | return x 11 | 12 | 13 | def rep(f, n = 1000, d = 10000): 14 | rands = np.random.randn(d, 1) 15 | urands = np.random.rand(d, 1) 16 | for i in xrange(n): 17 | f(1,2,rands,urands,1,0) 18 | 19 | n = 1000 20 | 21 | t = time.time() 22 | rep(wald, n) 23 | py_t = time.time() - t 24 | 25 | 26 | waldjit = jit(wald) 27 | #warmup 28 | rep(waldjit, 1) 29 | t = time.time() 30 | rep(waldjit, n) 31 | par_t = time.time() - t 32 | 33 | config.value_specialization = False 34 | rep(waldjit, 1) 35 | t = time.time() 36 | rep(waldjit, n) 37 | par_t_no_specialization = time.time() - t 38 | 39 | print "Python time per call:", 1000 * (py_t / n), "ms" 40 | print "Parakeet time w/ value specialization:", 1000 * (par_t / n), "ms" 41 | print "Parakeet time w/out value specialization", 1000 * (par_t_no_specialization / n), "ms" 42 | 43 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/convolution.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit 3 | # Simple convolution of 3x3 patches from a given array x 4 | # by a 3x3 array of filter weights 5 | 6 | @jit 7 | def conv_3x3_trim(x, weights): 8 | def compute_pixel(i,j): 9 | total = 0 10 | for ii in xrange(3): 11 | for jj in xrange(3): 12 | total += weights[ii,jj] * x[i-ii+1, j-jj+1] 13 | return total 14 | 15 | return np.array([[compute_pixel(i,j) 16 | for j in xrange(1, x.shape[1] -2)] 17 | for i in xrange(1, x.shape[0] -2)]) 18 | 19 | 20 | x = np.random.randn(50,50) 21 | w = np.random.randn(3,3) 22 | 23 | print "Input", x 24 | print "Convolved output", conv_3x3_trim(x,w) 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/finite-difference.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit 3 | 4 | @jit 5 | def fdtd(input_grid, steps): 6 | grid = input_grid.copy() 7 | old_grid = np.zeros_like(input_grid) 8 | previous_grid = np.zeros_like(input_grid) 9 | 10 | l_x = grid.shape[0] 11 | l_y = grid.shape[1] 12 | 13 | for i in range(steps): 14 | previous_grid[:, :] = old_grid 15 | old_grid[:, :] = grid 16 | for x in range(l_x): 17 | for y in range(l_y): 18 | grid[x,y] = 0.0 19 | if 0 < x+1 and x + 1 < l_x: 20 | grid[x,y] += old_grid[x+1,y] 21 | if 0 < x-1 and x- 1 < l_x: 22 | grid[x,y] += old_grid[x-1,y] 23 | if 0 < y+1 and y+1< l_y: 24 | grid[x,y] += old_grid[x,y+1] 25 | if 0 < y-1 and y-1< l_y: 26 | grid[x,y] += old_grid[x,y-1] 27 | 28 | grid[x,y] /= 2.0 29 | grid[x,y] -= previous_grid[x,y] 30 | 31 | return grid 32 | 33 | N = 5 34 | steps = 10 35 | input_grid = np.random.randn(N,N).astype('float32') 36 | 37 | fdtd(input_grid, steps) 38 | -------------------------------------------------------------------------------- /examples/growcut.py: -------------------------------------------------------------------------------- 1 | 2 | # Original authors: Nathan Faggian, Stefan van der Walt, Aron Ahmadia, Olivier Grisel 3 | # https://github.com/stefanv/growcut_py 4 | # ...simplified and made more compact for Parakeet 5 | 6 | import numpy as np 7 | import parakeet 8 | 9 | @parakeet.jit 10 | def growcut(image, state, window_radius): 11 | height = image.shape[0] 12 | width = image.shape[1] 13 | def attack_cell(i,j): 14 | winning_colony = state[i, j, 0] 15 | defense_strength = state[i, j, 1] 16 | for jj in xrange(max(0, j - window_radius), 17 | min(width, j+window_radius+1)): 18 | for ii in xrange(max(0, i - window_radius), 19 | min(height, i + window_radius + 1)): 20 | if ii != i or jj != j: 21 | ssd = np.sum( (image[i,j,:] - image[ii, jj, :]) ** 2) 22 | gval = 1.0 - np.sqrt(ssd) / np.sqrt(3.0) 23 | attack_strength = gval * state[ii, jj, 1] 24 | 25 | if attack_strength > defense_strength: 26 | defense_strength = attack_strength 27 | winning_colony = state[ii, jj, 0] 28 | return np.array([winning_colony, defense_strength]) 29 | return np.array([[attack_cell(i, j) 30 | for i in xrange(height)] 31 | for j in xrange(width)]) 32 | 33 | 34 | N = 50 35 | dtype = np.double 36 | image = np.zeros((N, N, 3), dtype=dtype) 37 | state = np.zeros((N, N, 2), dtype=dtype) 38 | 39 | # colony 1 is strength 1 at position 0,0 40 | # colony 0 is strength 0 at all other positions 41 | state[0, 0, 0] = 1 42 | state[0, 0, 1] = 1 43 | 44 | window_radius = 10 45 | 46 | state_next = growcut(image, state, window_radius) 47 | 48 | -------------------------------------------------------------------------------- /examples/kmeans.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit 2 | import numpy as np 3 | 4 | 5 | def dist(x,y): 6 | return ((x-y)**2).sum() 7 | 8 | @jit 9 | def kmeans(X, k, niters = 10): 10 | C = X[:k, :] 11 | for _ in xrange(niters): 12 | A = np.array([np.argmin([dist(x,c) for c in C]) for x in X]) 13 | C = np.array([np.mean(X[A == i, :], axis = 0) for i in xrange(k)]) 14 | return C 15 | 16 | 17 | n, d = 10**3, 100 18 | X = np.random.randn(n,d) 19 | k = 5 20 | 21 | C = kmeans(X, k, niters=20) 22 | print "Clusters:", C 23 | -------------------------------------------------------------------------------- /examples/matmult.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | import numpy as np 3 | 4 | @parakeet.jit 5 | def matmult(X,Y): 6 | return np.array([[np.dot(x,y) for y in Y.T] for x in X]) 7 | 8 | 9 | n, d = 120, 120 10 | m = 120 11 | dtype = 'float64' 12 | X = np.random.randn(m,d).astype(dtype) 13 | Y = np.random.randn(d,n).astype(dtype) 14 | Z = matmult(X,Y) 15 | -------------------------------------------------------------------------------- /examples/rosenbrock.py: -------------------------------------------------------------------------------- 1 | 2 | # Rosenbrock function derivative 3 | # 4 | # Copied from https://github.com/numfocus/python-benchmarks/blob/master/rosen_der/rosen_der_python.py 5 | # Original authors: Travis Oliphant (NumPy version) & Serge Guelton (loops version) 6 | # 7 | 8 | import numpy as np 9 | from parakeet import jit 10 | 11 | @jit 12 | def rosenbrock_derivative(x): 13 | der = np.empty_like(x) 14 | der[1:-1] = (+ 200 * (x[1:-1] - x[:-2] ** 2) 15 | - 400 * (x[2:] - x[1:-1] ** 2) * x[1:-1] 16 | - 2 * (1 - x[1:-1])) 17 | der[0] = -400 * x[0] * (x[1] - x[0] ** 2) - 2 * (1 - x[0]) 18 | der[-1] = 200 * (x[-1] - x[-2] ** 2) 19 | return der 20 | 21 | N = 12 22 | x = np.arange(N) / float(N) 23 | print "Input: ", x 24 | print "Deriv(Rosenbrock):", rosenbrock_derivative(x) 25 | 26 | -------------------------------------------------------------------------------- /examples/simple_avg.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit 2 | 3 | @jit 4 | def avg(x,y,z): 5 | """ 6 | Return the average of three scalars or arrays 7 | (gets optimized into single traversal) 8 | """ 9 | return (x + y + z) / 3.0 10 | 11 | import numpy as np 12 | 13 | N = 20 14 | x = np.random.randn(N) 15 | y = np.random.randn(N) 16 | z = np.random.randn(N) 17 | 18 | assert np.allclose(avg(x,y,z), (x+y+z)/3.0) 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/simple_regression.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit 2 | 3 | def covariance(x,y): 4 | return ((x-x.mean()) * (y-y.mean())).mean() 5 | 6 | @jit 7 | def fit_simple_regression(x,y): 8 | slope = covariance(x,y) / covariance(x,x) 9 | offset = y.mean() - slope * x.mean() 10 | return slope, offset 11 | 12 | import numpy as np 13 | 14 | N = 10**4 15 | x = np.random.randn(N).astype('float64') 16 | slope = 903.29 17 | offset = 102.1 18 | y = slope * x + offset 19 | 20 | slope_estimate, offset_estimate = fit_simple_regression(x,y) 21 | 22 | print "Expected slope =", slope, "offset =", offset 23 | print "Parakeet slope =", slope_estimate, "offset =", offset_estimate 24 | -------------------------------------------------------------------------------- /examples/sum_loop.py: -------------------------------------------------------------------------------- 1 | 2 | from parakeet import jit 3 | 4 | @jit 5 | def sum_loop(xs): 6 | total = 0 7 | for x in xs: 8 | total += x 9 | return total 10 | 11 | xs = [1,2,3,4,5] 12 | print "Python result", sum(xs) 13 | print "Parakeet result", sum_loop(xs) 14 | -------------------------------------------------------------------------------- /examples/tensor_rotation.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | # 4 | # Tensor rotation 5 | # from Peter Mortensen's stackoverflow question 6 | # @ http://stackoverflow.com/questions/4962606/fast-tensor-rotation-with-numpy/18301915 7 | # 8 | 9 | 10 | from parakeet import jit 11 | 12 | @jit 13 | def rotT_loops(T, g): 14 | def compute_elt(i,j,k,l): 15 | total = 0 16 | for ii in range(3): 17 | for jj in range(3): 18 | for kk in range(3): 19 | for ll in range(3): 20 | gg = g[ii,i]*g[jj,j]*g[kk,k]*g[ll,l] 21 | total += gg*T[ii,jj,kk,ll] 22 | return total 23 | return np.array([[[[compute_elt(i,j,k,l) 24 | for i in xrange(3)] 25 | for j in xrange(3)] 26 | for k in xrange(3)] 27 | for l in xrange(3)]) 28 | 29 | T = np.random.randn(3,3,3,3) 30 | g = np.random.randn(3,3) 31 | 32 | #parakeet.config.print_specialized_function = True 33 | #parakeet.config.print_indexified_function = True 34 | #parakeet.config.print_loopy_function = True 35 | rotT_loops(T,g) 36 | -------------------------------------------------------------------------------- /parakeet/__init__.py: -------------------------------------------------------------------------------- 1 | import config 2 | 3 | import package_info 4 | __author__ = package_info.__author__ 5 | __email__ = package_info.__email__ 6 | __desc__ = package_info.__desc__ 7 | __license__ = package_info.__license__ 8 | __version__ = package_info.__version__ 9 | __website__ = package_info.__website__ 10 | 11 | from system_info import openmp_available 12 | from ndtypes import * 13 | 14 | from analysis import SyntaxVisitor, verify 15 | 16 | from builder import Builder, build_fn, mk_identity_fn, mk_cast_fn 17 | 18 | from transforms import clone_function, Transform 19 | 20 | 21 | 22 | from lib import * 23 | from prims import * 24 | 25 | from frontend import jit, macro, run_python_fn, run_untyped_fn, run_typed_fn 26 | from frontend import typed_repr, specialize, find_broken_transform 27 | 28 | 29 | -------------------------------------------------------------------------------- /parakeet/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | from collect_vars import (collect_binding_names, 2 | collect_bindings, 3 | collect_var_names, 4 | collect_var_names_from_exprs, 5 | collect_var_names_list) 6 | from contains import (contains_adverbs, contains_calls, contains_functions, 7 | contains_loops, contains_slices, contains_structs, 8 | contains_array_operators) 9 | 10 | from escape_analysis import may_alias, may_escape, escape_analysis 11 | 12 | from find_local_arrays import FindLocalArrays 13 | from index_elim_analysis import IndexElimAnalysis 14 | from inline_allowed import can_inline 15 | from mutability_analysis import find_mutable_types, TypeBasedMutabilityAnalysis 16 | from offset_analysis import OffsetAnalysis 17 | from syntax_visitor import SyntaxVisitor 18 | from use_analysis import find_live_vars, use_count 19 | from usedef import StmtPath, UseDefAnalysis 20 | from value_range_analysis import ValueRangeAnalyis 21 | from verify import verify 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /parakeet/analysis/array_write_analysis.py: -------------------------------------------------------------------------------- 1 | 2 | from collect_vars import collect_var_names, collect_var_names_from_exprs 3 | from escape_analysis import escape_analysis 4 | from syntax_visitor import SyntaxVisitor 5 | 6 | 7 | class ArrayWriteAnalysis(SyntaxVisitor): 8 | def __init__(self, fn, fresh_alloc_args = set([])): 9 | self.fn = fn 10 | self.fresh_alloc_args = fresh_alloc_args 11 | 12 | def visit_fn(self, fn): 13 | escape_info = escape_analysis(fn, self.fresh_alloc_args) 14 | self.may_alias = escape_info.may_alias 15 | SyntaxVisitor.visit_fn(self, fn) 16 | self.writes = set([]) 17 | 18 | def visit_Assign(self, stmt): 19 | if stmt.lhs.__class__ is Tuple: 20 | for elt in stmt.lhs.elts: 21 | self.visit_Assign(elt) 22 | elif stmt.lhs.__class__ is Index: 23 | for name in collect_var_names(stmt.lhs.value): 24 | self.writes.append(name) 25 | for alias_name in self.may_alias[name]: 26 | self.writes.append(alias_name) 27 | 28 | 29 | def visit_Index(self): 30 | pass 31 | 32 | -------------------------------------------------------------------------------- /parakeet/analysis/collect_vars.py: -------------------------------------------------------------------------------- 1 | from .. syntax import Var, Tuple 2 | from syntax_visitor import SyntaxVisitor 3 | 4 | class SetCollector(SyntaxVisitor): 5 | def __init__(self): 6 | SyntaxVisitor.__init__(self) 7 | self.var_names = set([]) 8 | 9 | def visit_Var(self, expr): 10 | self.var_names.add(expr.name) 11 | 12 | def collect_var_names(expr): 13 | collector = SetCollector() 14 | collector.visit_expr(expr) 15 | return collector.var_names 16 | 17 | def collect_var_names_from_exprs(exprs): 18 | collector = SetCollector() 19 | collector.visit_expr_list(exprs) 20 | return collector.var_names 21 | 22 | class ListCollector(SyntaxVisitor): 23 | def __init__(self): 24 | SyntaxVisitor.__init__(self) 25 | self.var_names = [] 26 | 27 | def visit_Var(self, expr): 28 | self.var_names.append(expr.name) 29 | 30 | def collect_var_names_list(expr): 31 | collector = ListCollector() 32 | collector.visit_expr(expr) 33 | return collector.var_names 34 | 35 | 36 | 37 | def collect_binding_names(lhs): 38 | lhs_class = lhs.__class__ 39 | if lhs_class is Var: 40 | return [lhs.name] 41 | elif lhs.__class__ is Tuple: 42 | combined = [] 43 | for elt in lhs.elts: 44 | combined.extend(collect_binding_names(elt)) 45 | return combined 46 | else: 47 | return [] 48 | 49 | class CollectBindings(SyntaxVisitor): 50 | def __init__(self): 51 | SyntaxVisitor.__init__(self) 52 | self.bindings = {} 53 | 54 | def bind(self, lhs, rhs): 55 | if lhs.__class__ is Var: 56 | self.bindings[lhs.name] = rhs 57 | elif lhs.__class__ is Tuple: 58 | for elt in lhs.elts: 59 | self.bind(elt, rhs) 60 | 61 | def visit_Assign(self, stmt): 62 | self.bind(stmt.lhs, stmt.rhs) 63 | 64 | def collect_bindings(fn): 65 | return CollectBindings().visit_fn(fn) 66 | -------------------------------------------------------------------------------- /parakeet/analysis/inline_allowed.py: -------------------------------------------------------------------------------- 1 | 2 | from ..syntax import Assign, ExprStmt, If, While, ForLoop, Comment, Return, ParFor 3 | 4 | def all_branches_return(stmt): 5 | if isinstance(stmt, Return): 6 | return True 7 | elif isinstance(stmt, If): 8 | return len(stmt.true) > 0 and \ 9 | all_branches_return(stmt.true[-1]) and \ 10 | len(stmt.false) > 0 and \ 11 | all_branches_return(stmt.false[-1]) 12 | 13 | def can_inline_block(stmts, outer = False): 14 | for stmt in stmts: 15 | stmt_class = stmt.__class__ 16 | if stmt_class in (Assign, ExprStmt, ParFor): 17 | pass 18 | elif stmt_class is If: 19 | # if every branch leading from here ends up 20 | # returning a value, then it's OK to replace those 21 | # with variable assignments 22 | # ...but only once the Inliner knows how to deal with 23 | # control flow... 24 | #if outer and all_branches_return(stmt): 25 | # return True 26 | if not can_inline_block(stmt.true, outer = False): 27 | return False 28 | if not can_inline_block(stmt.false, outer=False): 29 | return False 30 | 31 | elif stmt_class in (While, ForLoop): 32 | if not can_inline_block(stmt.body): 33 | return False 34 | elif stmt_class is Comment: 35 | continue 36 | 37 | else: 38 | assert stmt_class is Return, "Unexpected statement: %s" % stmt 39 | if not outer: 40 | return False 41 | return True 42 | 43 | def can_inline(fundef): 44 | return can_inline_block(fundef.body, outer = True) -------------------------------------------------------------------------------- /parakeet/analysis/use_analysis.py: -------------------------------------------------------------------------------- 1 | 2 | from .. syntax import Var, Tuple 3 | from syntax_visitor import SyntaxVisitor 4 | 5 | class FindLiveVars(SyntaxVisitor): 6 | def __init__(self): 7 | SyntaxVisitor.__init__(self) 8 | self.live_vars = set([]) 9 | 10 | def visit_Var(self, expr): 11 | self.live_vars.add(expr.name) 12 | 13 | def visit_lhs(self, expr): 14 | expr_class = expr.__class__ 15 | if expr_class is Var: 16 | pass 17 | elif expr_class is Tuple: 18 | for elt in expr.elts: 19 | self.visit_lhs(elt) 20 | else: 21 | self.visit_expr(expr) 22 | 23 | def visit_fn(self, fn): 24 | self.live_vars.clear() 25 | for name in fn.arg_names: 26 | self.live_vars.add(name) 27 | self.visit_block(fn.body) 28 | return self.live_vars 29 | 30 | def find_live_vars(fn): 31 | return FindLiveVars().visit_fn(fn) 32 | 33 | class VarUseCount(SyntaxVisitor): 34 | 35 | def __init__(self): 36 | 37 | SyntaxVisitor.__init__(self) 38 | self.counts = {} 39 | 40 | def visit_Var(self, expr): 41 | old_count = self.counts.get(expr.name, 0) 42 | self.counts[expr.name] = old_count + 1 43 | 44 | def visit_ForLoop(self, stmt): 45 | self.visit_Var(stmt.var) 46 | SyntaxVisitor.visit_ForLoop(self, stmt) 47 | 48 | def visit_lhs(self, expr): 49 | expr_class = expr.__class__ 50 | if expr_class is Var: 51 | pass 52 | elif expr_class is Tuple: 53 | for elt in expr.elts: 54 | self.visit_lhs(elt) 55 | else: 56 | self.visit_expr(expr) 57 | 58 | def visit_fn(self, fn): 59 | self.counts.clear() 60 | for name in fn.arg_names: 61 | self.counts[name] = 1 62 | self.visit_block(fn.body) 63 | return self.counts 64 | 65 | def use_count(fn): 66 | return VarUseCount().visit_fn(fn) -------------------------------------------------------------------------------- /parakeet/builder/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from builder import Builder 4 | from build_fn import build_fn, mk_identity_fn, mk_cast_fn, mk_prim_fn 5 | 6 | __all__ = ['Builder', 'build_fn'] -------------------------------------------------------------------------------- /parakeet/c_backend/__init__.py: -------------------------------------------------------------------------------- 1 | from fn_compiler import FnCompiler 2 | from pymodule_compiler import PyModuleCompiler 3 | from run_function import run 4 | -------------------------------------------------------------------------------- /parakeet/c_backend/c_prims.py: -------------------------------------------------------------------------------- 1 | from .. import prims 2 | from ..ndtypes import FloatT, Float32, Float64 3 | 4 | 5 | # names used in math library 6 | _float_fn_names = { 7 | prims.tan : 'tan', 8 | prims.tanh : 'tanh', 9 | prims.arctan : 'atan', 10 | prims.arctanh : 'atanh', 11 | prims.arctan2 : 'atan2', 12 | 13 | prims.cos : 'cos', 14 | prims.cosh : 'cosh', 15 | prims.arccos : 'acos', 16 | prims.arccosh : 'acosh', 17 | 18 | prims.sin : 'sin', 19 | prims.sinh : 'sinh', 20 | prims.arcsin : 'asin', 21 | prims.arcsinh : 'asinh', 22 | 23 | prims.log : 'log', 24 | prims.log2 : 'log2', 25 | prims.log10 : 'log10', 26 | prims.log1p : 'log1p', 27 | 28 | 29 | prims.exp : 'exp', 30 | prims.exp2 : 'exp2', 31 | prims.power : 'pow', 32 | prims.expm1 : 'expm1', 33 | prims.sqrt : 'sqrt', 34 | 35 | prims.abs : 'fabs', 36 | 37 | prims.ceil : 'ceil', 38 | prims.floor : 'floor', 39 | prims.round : 'round', 40 | 41 | } 42 | 43 | def float_prim(p, t): 44 | assert p in _float_fn_names 45 | assert isinstance(t, FloatT) 46 | name = _float_fn_names[p] 47 | if t == Float32: 48 | return name + "f" 49 | else: 50 | return name 51 | -------------------------------------------------------------------------------- /parakeet/c_backend/config.py: -------------------------------------------------------------------------------- 1 | ########################## 2 | # Performance Options # 3 | ########################## 4 | fast_math = True 5 | sse2 = True 6 | opt_level = '-O2' 7 | # overload the default compiler path 8 | compiler_path = None 9 | 10 | ########################## 11 | # Insert Debugging Code # 12 | ########################## 13 | debug = False 14 | check_pyobj_types = False 15 | 16 | ######################### 17 | # Verbose Printing # 18 | ######################### 19 | print_input_ir = False 20 | 21 | print_line_numbers = False 22 | 23 | print_function_source = False 24 | 25 | print_commands = False 26 | print_command_elapsed_time = False 27 | 28 | 29 | # Generate a .c file or a .cpp? 30 | pure_c = True 31 | 32 | # Throw away .c and .o files 33 | delete_temp_files = True 34 | 35 | # Directory to use for caching generated modules. 36 | # Set to None to disable caching. 37 | from appdirs import user_cache_dir 38 | cache_dir = user_cache_dir('parakeet') 39 | 40 | # if compiling C or OpenMP we can skip some of the craziness and 41 | # have distutils figure out the system config and compiler for us 42 | use_distutils = True 43 | 44 | # show all the warnings? w 45 | suppress_compiler_output = False 46 | 47 | # when compiling with NVCC, other headers get implicitly included 48 | # and cause warnings since Python redefines _POSIX_C_SOURCE 49 | # we can undefine it before including Python.h to get rid of those warnings 50 | undef_posix_c_source = True -------------------------------------------------------------------------------- /parakeet/c_backend/prepare_args.py: -------------------------------------------------------------------------------- 1 | from itertools import izip 2 | import numpy as np 3 | from ..ndtypes import (type_conv, ScalarT, ArrayT, FnT, ClosureT, SliceT, NoneT, TupleT, TypeValueT) 4 | from ..syntax import TypedFn, UntypedFn 5 | 6 | 7 | def prepare_closure_args(untyped_fn): 8 | closure_args = untyped_fn.python_nonlocals() 9 | closure_arg_types = [type_conv.typeof(v) for v in closure_args] 10 | return prepare_args(closure_args, closure_arg_types) 11 | 12 | 13 | def prepare_arg(arg, t): 14 | if isinstance(t, ScalarT): 15 | return t.dtype.type(arg) 16 | elif isinstance(t, ArrayT): 17 | return np.asarray(arg) 18 | elif isinstance(t, TupleT): 19 | arg = tuple(arg) 20 | assert len(arg) == len(t.elt_types) 21 | return prepare_args(arg, t.elt_types) 22 | elif isinstance(t, (NoneT, SliceT)): 23 | return arg 24 | elif isinstance(t, TypeValueT): 25 | return () 26 | elif isinstance(t, (FnT, ClosureT)): 27 | if isinstance(arg, TypedFn): 28 | return () 29 | elif isinstance(arg, UntypedFn): 30 | return prepare_closure_args(arg) 31 | else: 32 | from ..frontend import ast_conversion 33 | untyped = ast_conversion.translate_function_value(arg) 34 | return prepare_closure_args(untyped) 35 | assert False, "Can't call compiled C code with argument %s (Python type = %s, Parakeet type = %s)" % \ 36 | (arg, type(arg), t) 37 | 38 | def prepare_args(args, arg_types): 39 | return tuple(prepare_arg(arg, t) for arg, t in izip(args, arg_types)) 40 | 41 | 42 | -------------------------------------------------------------------------------- /parakeet/c_backend/reserved_names.py: -------------------------------------------------------------------------------- 1 | keywords = set([ 2 | "auto", 3 | "break", 4 | "case", 5 | "char", 6 | "const", 7 | "continue", 8 | "default", 9 | "do", 10 | "double", 11 | "else", 12 | "enum", 13 | "extern", 14 | "float", 15 | "for", 16 | "goto", 17 | "if", 18 | "int", 19 | "long", 20 | "register", 21 | "return" 22 | "short" 23 | "signed" 24 | "sizeof" 25 | "static" 26 | "struct", 27 | "switch" 28 | "typedef", 29 | "union", 30 | "unsigned", 31 | "void", 32 | "volatile", 33 | "while"]) 34 | 35 | macro_names = set(["assert"]) 36 | util_names = set(["printf", "malloc", "free", ]) 37 | 38 | import math 39 | 40 | base_math_names = [name for name in dir(math) if not name.startswith("__")] 41 | 42 | float32_math_names = [name+'f' for name in base_math_names] 43 | long_math_names = [name+"l" for name in base_math_names] 44 | extra_math_names = [ 45 | "atof", "cbrt", "cbrtf", "cbrtl", 46 | "div", 47 | "exp2", "exp2f", "exp2l", 48 | "j0", "j1", "jn", 49 | "log2", "log2f", "log2l", 50 | "logb", "logbf", "logbl", 51 | "lrintf", "lrintl", 52 | "lround", "lroundf", "lroundl", 53 | "remainder", "remainderf", "remainderl", 54 | "remquo", "remquof", "remquol", 55 | "rint", "rintf", "rintl", 56 | "round", "roundf", "roundl", 57 | "scalb", "scalbln", "scalblnf", "scalblnl", "scalbn", "scalbnf", "scalbnl", 58 | "signgam", 59 | "tgamma", "tgammaf", "tgammal" 60 | "y0", "y1", "yn", 61 | ] 62 | math_names = set(base_math_names+float32_math_names+long_math_names+extra_math_names) 63 | all_reserved_names = keywords.union(macro_names).union(util_names).union(math_names) 64 | 65 | def is_reserved(name): 66 | return name in all_reserved_names or name.startswith("Py") -------------------------------------------------------------------------------- /parakeet/c_backend/run_function.py: -------------------------------------------------------------------------------- 1 | from prepare_args import prepare_args 2 | from ..transforms.pipeline import lower_to_loops 3 | from ..value_specialization import specialize 4 | from ..config import value_specialization 5 | from pymodule_compiler import PyModuleCompiler 6 | 7 | 8 | 9 | _cache = {} 10 | def run(fn, args): 11 | args = prepare_args(args, fn.input_types) 12 | 13 | fn = lower_to_loops(fn) 14 | 15 | if value_specialization: 16 | fn = specialize(fn, args) 17 | 18 | key = fn.cache_key 19 | if key in _cache: 20 | return _cache[key](*args) 21 | compiled_fn = PyModuleCompiler().compile_entry(fn) 22 | c_fn = compiled_fn.c_fn 23 | _cache[key] = c_fn 24 | return c_fn(*args) 25 | -------------------------------------------------------------------------------- /parakeet/c_backend/shell_command.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import time 4 | 5 | import config 6 | 7 | class CommandFailed(Exception): 8 | def __init__(self, cmd, env, label): 9 | self.cmd = cmd 10 | self.env = env 11 | self.label = label 12 | 13 | 14 | def __str__(self): 15 | return "CommandFailed(%s)" % self.cmd 16 | 17 | def __repr__(self): 18 | return "CommandFailed(cmd=%s, env=%s, label=%s)" % (" ".join(self.cmd), self.env, self.label) 19 | 20 | def run_cmd(cmd, env = None, label = ""): 21 | if config.print_commands: 22 | print " ".join(cmd) 23 | if config.print_command_elapsed_time: 24 | t = time.time() 25 | 26 | # first compile silently 27 | # if you encounter an error, then recompile with output printing 28 | try: 29 | if config.suppress_compiler_output: 30 | with open(os.devnull, "w") as fnull: 31 | subprocess.check_call(cmd, stdout = fnull, stderr = fnull, env = env) 32 | else: 33 | subprocess.check_call(cmd, env = env) 34 | except: 35 | raise CommandFailed(cmd, env, label) 36 | 37 | if config.print_command_elapsed_time: 38 | if label: 39 | print "%s, elapsed time: %0.4f" % (label, time.time() - t) 40 | else: 41 | print "Elapsed time:", time.time() - t 42 | -------------------------------------------------------------------------------- /parakeet/c_backend/system_info.py: -------------------------------------------------------------------------------- 1 | import distutils 2 | 3 | import numpy.distutils as npdist 4 | import numpy.distutils.system_info as np_sysinfo 5 | 6 | from ..system_info import windows, mac_os, openmp_available 7 | import config 8 | 9 | config_vars = distutils.sysconfig.get_config_vars() 10 | 11 | def get_compiler(_cache = {}): 12 | if config.compiler_path: 13 | return config.compiler_path 14 | if config.pure_c in _cache: 15 | return _cache[config.pure_c] 16 | for compiler in [('gcc' if config.pure_c else 'g++'), 17 | 'icc']: 18 | path = distutils.spawn.find_executable(compiler) 19 | if path: 20 | _cache[config.pure_c] = path 21 | return path 22 | assert False, "No compiler found!" 23 | 24 | 25 | def get_source_extension(): 26 | return ".c" if config.pure_c else ".cpp" 27 | 28 | object_extension = ".o" 29 | shared_extension = np_sysinfo.get_shared_lib_extension(True) 30 | 31 | 32 | 33 | 34 | python_include_dirs = [distutils.sysconfig.get_python_inc()] 35 | numpy_include_dirs = npdist.misc_util.get_numpy_include_dirs() 36 | include_dirs = numpy_include_dirs + python_include_dirs 37 | 38 | python_lib_dir = distutils.sysconfig.get_python_lib() + "/../../" 39 | python_version = distutils.sysconfig.get_python_version() 40 | 41 | -------------------------------------------------------------------------------- /parakeet/c_backend/type_mappings.py: -------------------------------------------------------------------------------- 1 | 2 | from ..ndtypes import (UInt8, UInt16, UInt32, UInt64, 3 | Int8, Int16, Int32, Int64, Float32, Float64, NoneType, 4 | Bool, ArrayT, ClosureT, TupleT, SliceT, NoneT, PtrT) 5 | 6 | _dtype_mappings = { 7 | Bool : "NPY_BOOL", 8 | Int8 : "NPY_INT8", 9 | Int16 : "NPY_INT16", 10 | Int32 : "NPY_INT32", 11 | Int64 : "NPY_INT64", 12 | UInt8 : "NPY_UINT8", 13 | UInt16 : "NPY_UINT16", 14 | UInt32 : "NPY_UINT32", 15 | UInt64 : "NPY_UINT64", 16 | Float32 : "NPY_FLOAT32", 17 | Float64 : "NPY_FLOAT64" 18 | } 19 | def to_dtype(t): 20 | if t in _dtype_mappings: 21 | return _dtype_mappings[t] 22 | assert False, "Unsupported element type %s" % t 23 | 24 | _ctype_mappings = { 25 | Int8: "int8_t", 26 | UInt8: "uint8_t", 27 | UInt16: "uint16_t", 28 | UInt32: "uint32_t", 29 | UInt64: "uint64_t", 30 | Int16: "int16_t", 31 | Int32: "int32_t", 32 | Int64: "int64_t", 33 | Float32: "float", 34 | Float64: "double", 35 | NoneType: "int", 36 | Bool: "int8_t", 37 | } 38 | 39 | def to_ctype(t): 40 | if t in _ctype_mappings: 41 | return _ctype_mappings[t] 42 | elif isinstance(t, PtrT): 43 | return "%s*" % to_ctype(t.elt_type) 44 | elif isinstance(t, (ArrayT, ClosureT, TupleT, SliceT, NoneT)): 45 | return "PyObject*" 46 | else: 47 | assert False, "Unsupported type %s" % t 48 | -------------------------------------------------------------------------------- /parakeet/cuda_backend/__init__.py: -------------------------------------------------------------------------------- 1 | import device_info 2 | from run_function import run 3 | -------------------------------------------------------------------------------- /parakeet/cuda_backend/config.py: -------------------------------------------------------------------------------- 1 | threads_per_block_dim = 16 2 | blocks_per_sm = 128 3 | compute_capability = (1,3) 4 | arch = "sm_%d%d" % compute_capability -------------------------------------------------------------------------------- /parakeet/cuda_backend/cuda_syntax.py: -------------------------------------------------------------------------------- 1 | from ..ndtypes import Int32 2 | from ..syntax import SourceExpr, SourceStmt 3 | 4 | class dim3(object): 5 | def __init__(self, x, y, z): 6 | self.x = x 7 | self.y = y 8 | self.z = z 9 | 10 | def __iter__(self): 11 | yield self.x 12 | yield self.y 13 | yield self.z 14 | 15 | def __getitem__(self, idx): 16 | if idx == 0: 17 | return self.x 18 | elif idx == 1: 19 | return self.y 20 | else: 21 | assert idx == 2, "Unexpected index %s to %s" % (idx, self) 22 | return self.z 23 | 24 | def __str__(self): 25 | return "dim3(x = %s, y = %s, z = %s)" % (self.x, self.y, self.z) 26 | 27 | # pasted literally into the C source 28 | blockIdx_x = SourceExpr("blockIdx.x", type=Int32) 29 | blockIdx_y = SourceExpr("blockIdx.y", type=Int32) 30 | blockIdx_z = SourceExpr("blockIdx.z", type=Int32) 31 | blockIdx = dim3(blockIdx_x, blockIdx_y, blockIdx_z) 32 | 33 | threadIdx_x = SourceExpr("threadIdx.x", type=Int32) 34 | threadIdx_y = SourceExpr("threadIdx.y", type=Int32) 35 | threadIdx_z = SourceExpr("threadIdx.z", type=Int32) 36 | threadIdx = dim3(threadIdx_x, threadIdx_y, threadIdx_z) 37 | 38 | blockDim_x = SourceExpr("blockDim.x", type = Int32) 39 | blockDim_y = SourceExpr("blockDim.y", type = Int32) 40 | blockDim_z = SourceExpr("blockDim.z", type = Int32) 41 | blockDim = dim3(blockDim_x, blockDim_y, blockDim_z) 42 | 43 | gridDim_x = SourceExpr("gridDim.x", type = Int32) 44 | gridDim_y = SourceExpr("gridDim.y", type = Int32) 45 | gridDim_z = SourceExpr("gridDim.z", type = Int32) 46 | gridDim = dim3(gridDim_x, gridDim_y, gridDim_z) 47 | 48 | warpSize = SourceExpr("wrapSize", type=Int32) 49 | __syncthreads = SourceStmt("__syncthreads;") 50 | 51 | -------------------------------------------------------------------------------- /parakeet/cuda_backend/device_info.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import config 4 | def get_cuda_devices(compute_capability = config.compute_capability): 5 | try: 6 | import pycuda.autoinit 7 | import pycuda.driver 8 | except: 9 | return [] 10 | devices = [pycuda.driver.Device(i) for i in xrange(pycuda.driver.Device.count())] 11 | return [d for d in devices if d.compute_capability() >= compute_capability] 12 | 13 | def device_id(cuda_device): 14 | import pycuda.driver 15 | return cuda_device.get_attribute(pycuda.driver.device_attribute.PCI_DEVICE_ID) 16 | 17 | def display_attached(cuda_device): 18 | import pycuda.driver 19 | return cuda_device.get_attribute(pycuda.driver.device_attribute.KERNEL_EXEC_TIMEOUT) == 1 20 | 21 | def num_multiprocessors(cuda_device): 22 | import pycuda.driver 23 | return cuda_device.get_attribute(pycuda.driver.device_attribute.MULTIPROCESSOR_COUNT) 24 | 25 | 26 | def best_cuda_device(compute_capability = config.compute_capability): 27 | devices = get_cuda_devices(compute_capability) 28 | if len(devices) == 0: 29 | return None 30 | 31 | best_device = devices[0] 32 | for d in devices[1:]: 33 | if display_attached(best_device) and not display_attached(d): 34 | best_device = d 35 | elif num_multiprocessors(d) > num_multiprocessors(best_device): 36 | best_device = d 37 | elif d.total_memory() > best_device.total_memory(): 38 | best_device = d 39 | return best_device 40 | 41 | def has_gpu(): 42 | return best_cuda_device() is not None 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /parakeet/cuda_backend/run_function.py: -------------------------------------------------------------------------------- 1 | from ..c_backend.prepare_args import prepare_args 2 | from ..config import value_specialization 3 | from ..transforms.pipeline import (lower_to_adverbs, ) 4 | from ..value_specialization import specialize 5 | 6 | 7 | from cuda_compiler import CudaCompiler 8 | 9 | def run(fn, args): 10 | args = prepare_args(args, fn.input_types) 11 | 12 | fn = lower_to_adverbs.apply(fn) 13 | 14 | if value_specialization: 15 | fn = specialize(fn, python_values = args) 16 | compiled_fn = CudaCompiler().compile_entry(fn) 17 | assert len(args) == len(fn.input_types) 18 | result = compiled_fn.c_fn(*args) 19 | return result 20 | -------------------------------------------------------------------------------- /parakeet/frontend/__init__.py: -------------------------------------------------------------------------------- 1 | from ast_conversion import translate_function_value, translate_function_ast 2 | from closure_specializations import print_specializations 3 | from decorators import jit, macro, staged_macro, typed_macro, axis_macro 4 | from diagnose import find_broken_transform 5 | from run_function import run_untyped_fn, run_typed_fn, run_python_fn, specialize 6 | import type_conv_decls as _decls 7 | from typed_repr import typed_repr 8 | -------------------------------------------------------------------------------- /parakeet/frontend/closure_specializations.py: -------------------------------------------------------------------------------- 1 | 2 | from ..config import print_specialized_function_names 3 | from ..ndtypes.closure_type import _closure_type_cache 4 | 5 | def clear_specializations(): 6 | for clos_t in _closure_type_cache.itervalues(): 7 | clos_t.specializations.clear() 8 | 9 | 10 | def print_specializations(): 11 | 12 | if print_specialized_function_names: 13 | print 14 | print "FUNCTION SPECIALIZATIONS" 15 | count = 0 16 | for ((untyped,closure_types), clos_t) in sorted(_closure_type_cache.items()): 17 | specializations = clos_t.specializations.items() 18 | if len(specializations) > 0: 19 | name = untyped.name if hasattr(untyped, 'name') else str(untyped) 20 | print "Closure %s %s" % (name, closure_types) 21 | for (arg_types, typed_fn) in sorted(specializations): 22 | print " -- %s ==> %s" % (arg_types, typed_fn.name) 23 | count += 1 24 | print 25 | print "Total: %d function specializations" % count 26 | 27 | 28 | import atexit 29 | atexit.register(print_specializations) -------------------------------------------------------------------------------- /parakeet/frontend/python_ref.py: -------------------------------------------------------------------------------- 1 | import abc 2 | 3 | class Ref(object): 4 | __meta__ = abc.ABCMeta 5 | 6 | @abc.abstractmethod 7 | def deref(self): 8 | pass 9 | 10 | class GlobalValueRef(Ref): 11 | def __init__(self, value): 12 | self.value = value 13 | 14 | def deref(self): 15 | return self.value 16 | 17 | def __str__(self): 18 | return "GlobalValueRef(%s)" % (self.value,) 19 | 20 | def __repr__(self): 21 | return str(self) 22 | 23 | def __eq__(self, other): 24 | return isinstance(other, GlobalValueRef) and self.value is other.value 25 | 26 | class GlobalNameRef(Ref): 27 | def __init__(self, globals_dict, name): 28 | self.globals_dict = globals_dict 29 | self.name = name 30 | 31 | def __str__(self): 32 | return "GlobalNameRef(%s)" % self.name 33 | 34 | def __repr__(self): 35 | return str(self) 36 | 37 | def deref(self): 38 | return self.globals_dict[self.name] 39 | 40 | def __eq__(self, other): 41 | return isinstance(other, GlobalNameRef) and \ 42 | self.globals_dict is other.globals_dict and \ 43 | self.name == other.name 44 | 45 | class ClosureCellRef(Ref): 46 | def __init__(self, cell, name): 47 | self.cell = cell 48 | self.name = name 49 | 50 | def deref(self): 51 | return self.cell.cell_contents 52 | 53 | def __str__(self): 54 | return "ClosureCellRef(%s)" % self.name 55 | 56 | def __repr__(self): 57 | return str(self) 58 | 59 | def __eq__(self, other): 60 | if isinstance(other, ClosureCellRef): 61 | try: 62 | return self.cell == other.cell 63 | except: 64 | return self.cell is other.cell 65 | return False 66 | -------------------------------------------------------------------------------- /parakeet/frontend/typed_repr.py: -------------------------------------------------------------------------------- 1 | from run_function import specialize 2 | 3 | def typed_repr(python_fn, args, optimize = True): 4 | typed_fn, _ = specialize(python_fn, args) 5 | if optimize: 6 | from ..transforms import pipeline 7 | return pipeline.high_level_optimizations.apply(typed_fn) 8 | else: 9 | return typed_fn 10 | 11 | 12 | -------------------------------------------------------------------------------- /parakeet/lib/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from adverbs import * 3 | from array_properties import * 4 | from array_constructors import * 5 | from builtins import * 6 | from math import * 7 | from numpy_misc import * 8 | from reductions import * 9 | from numpy_types import * 10 | from patchmap import * 11 | 12 | import prob 13 | import linalg 14 | from linalg import dot 15 | import random 16 | -------------------------------------------------------------------------------- /parakeet/lib/array_properties.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from .. import ndtypes 4 | from .. ndtypes import ArrayT, Int64, elt_type, empty_tuple_t, TupleT, TypeValueT 5 | from .. frontend import macro, jit, typed_macro 6 | from .. syntax import (Attribute, Tuple, Ravel, Shape, Reshape, TypeValue, Transpose, Const) 7 | from .. syntax.helpers import const_int, zero_i64 8 | 9 | 10 | @macro 11 | def transpose(x): 12 | return Transpose(x) 13 | 14 | @macro 15 | def ravel(x): 16 | return Ravel(x) 17 | 18 | @macro 19 | def reshape(x): 20 | return Reshape(x) 21 | 22 | @typed_macro 23 | def get_elt_type(x): 24 | elt_t = ndtypes.elt_type(x.type) 25 | return TypeValue(elt_t, type = TypeValueT(elt_t)) 26 | 27 | @typed_macro 28 | def itemsize(xt): 29 | return const_int(elt_type(xt.type).nbytes) 30 | 31 | @typed_macro 32 | def rank(xt): 33 | return const_int(xt.type.rank) 34 | 35 | @typed_macro 36 | def size(xt, axis = None): 37 | if axis is None: 38 | axis = zero_i64 39 | assert isinstance(axis, Const), "Axis argument to 'size' must be a constant, given %s" % axis 40 | assert axis.value == 0, "Calling 'size' along axes other than 0 not yet supported, given %s" % axis 41 | if isinstance(xt.type, ArrayT): 42 | return Attribute(xt, 'size', type = Int64) 43 | elif isinstance(xt.type, TupleT): 44 | return const_int(len(xt.type.elt_types)) 45 | else: 46 | return const_int(1) 47 | 48 | 49 | @macro 50 | def shape(x): 51 | return Shape(x) 52 | 53 | -------------------------------------------------------------------------------- /parakeet/lib/builtins.py: -------------------------------------------------------------------------------- 1 | from .. import prims 2 | 3 | from .. frontend import jit, typed_macro 4 | from .. ndtypes import make_tuple_type, TupleT, ArrayT 5 | from ..syntax import Tuple, Array 6 | 7 | @jit 8 | def builtin_or(x, y): 9 | return x or y 10 | 11 | @jit 12 | def builtin_and(x, y): 13 | return x and y 14 | 15 | @typed_macro 16 | def builtin_tuple(xt): 17 | if isinstance(xt.type, TupleT): 18 | return xt 19 | else: 20 | assert isinstance(xt.type, ArrayT), "Can't create type from %s" % (xt.type,) 21 | assert isinstance(xt, Array), "Can only create tuple from array of const length" 22 | elt_types = [e.type for e in xt.elts] 23 | tuple_t = make_tuple_type(elt_types) 24 | return Tuple(xt.elts, type = tuple_t) 25 | 26 | -------------------------------------------------------------------------------- /parakeet/lib/math.py: -------------------------------------------------------------------------------- 1 | from ..frontend import jit 2 | 3 | import numpy as np 4 | 5 | 6 | 7 | @jit 8 | def conjugate(x): 9 | """ 10 | For now we don't have complex numbers so this is just the identity function 11 | """ 12 | return x 13 | 14 | 15 | @jit 16 | def real(x): 17 | """ 18 | For now we don't have complex types, so real is just the identity function 19 | """ 20 | return x 21 | 22 | def _scalar_sign(x): 23 | if x > 0: 24 | return 1 25 | elif x < 0: 26 | return -1 27 | else: 28 | return 0 29 | 30 | @jit 31 | def sign(x): 32 | return map(_scalar_sign, x) 33 | 34 | @jit 35 | def reciprocal(x): 36 | return 1 / x 37 | 38 | @jit 39 | def rad2deg(rad): 40 | return rad * 180 / 3.141592653589793 41 | 42 | @jit 43 | def deg2rad(deg): 44 | return deg * 3.141592653589793 / 180 45 | 46 | @jit 47 | def hypot(x,y): 48 | return np.sqrt(x**2 + y**2) 49 | 50 | @jit 51 | def square(x): 52 | return x * x 53 | 54 | def _logaddexp_scalar(x, y): 55 | """ 56 | Copied from BioPython (http://biopython.org/) 57 | """ 58 | if x < y: 59 | bigger = x 60 | smaller = y 61 | else: 62 | bigger = x 63 | smaller = y 64 | 65 | diff = smaller - bigger 66 | if diff < -100: 67 | return bigger 68 | 69 | return bigger + np.log1p(np.exp(diff)) 70 | 71 | 72 | @jit 73 | def logaddexp(x, y): 74 | return map(_logaddexp_scalar, x, y) 75 | 76 | @jit 77 | def log2_1p(x): 78 | return (1.0 / np.log(2)) * np.log1p(x) 79 | 80 | 81 | @jit 82 | def logaddexp2(x, y): 83 | diff = x - y 84 | return np.where(diff > 0, x + log2_1p(2 ** -diff) , y + log2_1p(2 ** diff)) 85 | 86 | 87 | @jit 88 | def true_divide(x, y): 89 | """ 90 | Not exactly true divide, since I guess it's sometimes supposed to stay an int 91 | """ 92 | return (x + 0.0) / (y + 0.0) 93 | 94 | @jit 95 | def floor_divide(x, y): 96 | return np.floor(x / y) 97 | -------------------------------------------------------------------------------- /parakeet/lib/numpy_misc.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import prims 3 | from ..frontend import jit, macro, typed_macro 4 | from ..ndtypes import ScalarT, ArrayT, make_array_type 5 | from ..syntax import Select, DelayUntilTyped, PrimCall, Call, OuterMap 6 | 7 | 8 | 9 | 10 | @macro 11 | def _select(cond, trueval, falseval): 12 | return Select(cond, trueval, falseval) 13 | 14 | #@macro 15 | def where(cond, trueval, falseval): 16 | #return Select(cond, trueval, falseval ) 17 | return map(_select, cond, trueval, falseval) 18 | 19 | 20 | @jit 21 | def diff(x): 22 | """ 23 | TODO: 24 | - axis selection 25 | - preserve size by filling with zeros 26 | - allow n'th differences by recursion 27 | """ 28 | return x[1:] - x[:-1] 29 | 30 | 31 | @jit 32 | def fill(x, v): 33 | for i in range(len(x)): 34 | x[i] = v 35 | 36 | -------------------------------------------------------------------------------- /parakeet/lib/numpy_types.py: -------------------------------------------------------------------------------- 1 | 2 | from .. ndtypes import (Int8, Int16, Int32, Int64, 3 | UInt8, UInt16, UInt32, UInt64, 4 | Float32, Float64, Bool) 5 | 6 | from .. frontend import macro, jit 7 | from .. syntax import Cast 8 | 9 | @macro 10 | def int8(x): 11 | return Cast(x, type = Int8) 12 | 13 | @macro 14 | def int16(x): 15 | return Cast(x, type = Int16) 16 | 17 | @macro 18 | def int32(x): 19 | return Cast(x, type = Int32) 20 | 21 | @macro 22 | def int64(x): 23 | return Cast(x, type = Int64) 24 | 25 | 26 | @macro 27 | def uint8(x): 28 | return Cast(x, type = UInt8) 29 | 30 | @macro 31 | def uint16(x): 32 | return Cast(x, type = UInt16) 33 | 34 | @macro 35 | def uint32(x): 36 | return Cast(x, type = UInt32) 37 | 38 | @macro 39 | def uint64(x): 40 | return Cast(x, type = UInt64) 41 | 42 | uint = uint64 43 | 44 | @macro 45 | def float32(x): 46 | return Cast(x, type = Float32) 47 | 48 | @macro 49 | def float64(x): 50 | return Cast(x, type = Float64) 51 | 52 | @macro 53 | def bool(x): 54 | return Cast(x, type = Bool) 55 | -------------------------------------------------------------------------------- /parakeet/lib/patchmap.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from .. frontend import jit 3 | from adverbs import imap 4 | 5 | @jit 6 | def pmap1(f, x, w = 3): 7 | n = x.shape[0] 8 | def local_apply(i): 9 | lower = __builtins__.max(i-w/2, 0) 10 | upper = __builtins__.min(i+w/2+1, n) 11 | elts = x[lower:upper] 12 | return f(elts) 13 | return imap(local_apply, n) 14 | 15 | @jit 16 | def pmap2(f, x, width = (3,3)): 17 | """ 18 | Patch-map where the function can accept both interior windows 19 | and smaller border windows 20 | """ 21 | width_x, width_y = width 22 | n_rows, n_cols = x.shape 23 | hx = width_x / 2 24 | hy = width_y / 2 25 | 26 | def local_apply((i,j)): 27 | lx = __builtins__.max(i-hx, 0) 28 | ux = __builtins__.min(i+hx+1, n_rows) 29 | ly = __builtins__.max(j-hy, 0) 30 | uy = __builtins__.min(j+hy+1, n_cols) 31 | return f(x[lx:ux, ly:uy]) 32 | 33 | return imap(local_apply, x.shape) 34 | 35 | @jit 36 | def pmap2_trim(f, x, width = (3,3), step = (1,1)): 37 | """ 38 | Patch-map over interior windows, ignoring the border 39 | """ 40 | width_x, width_y = width 41 | step_x, step_y = step 42 | n_rows, n_cols = x.shape 43 | hx = width_x / 2 44 | hy = width_y / 2 45 | return [[f(x[i-hx:i+hx+1, j-hy:j+hy+1]) 46 | for j in np.arange(hx, n_cols-hx, step_x)] 47 | for i in np.arange(hy, n_rows-hy, step_y)] 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /parakeet/lib/random.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from ..frontend.decorators import jit 4 | 5 | @jit 6 | def shuffle(x): 7 | n = len(x) 8 | r = np.random.randint(0, n, n) 9 | for i in xrange(n): 10 | j = np.fmod(r[i], i) 11 | old_xj = x[j] 12 | x[j] = x[i] 13 | x[i] = old_xj 14 | 15 | @jit 16 | def permutation(x): 17 | y = np.zeros_like(x) 18 | return shuffle(y) 19 | 20 | -------------------------------------------------------------------------------- /parakeet/llvm_backend/__init__.py: -------------------------------------------------------------------------------- 1 | from compiler import compile_fn 2 | from gv_helpers import ctypes_to_generic_value, generic_value_to_python, python_to_generic_value 3 | from llvm_context import global_context 4 | 5 | import llvm_context -------------------------------------------------------------------------------- /parakeet/llvm_backend/gv_helpers.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | from llvm.ee import GenericValue 4 | 5 | from .. ndtypes import FloatT, SignedT, IntT, NoneT, PtrT 6 | from .. ndtypes import type_conv 7 | import llvm_types 8 | 9 | def python_to_generic_value(x, t): 10 | if isinstance(t, FloatT): 11 | llvm_t = llvm_types.llvm_value_type(t) 12 | return GenericValue.real(llvm_t, x) 13 | elif isinstance(t, SignedT): 14 | llvm_t = llvm_types.llvm_value_type(t) 15 | return GenericValue.int_signed(llvm_t, x) 16 | elif isinstance(t, IntT): 17 | llvm_t = llvm_types.llvm_value_type(t) 18 | return GenericValue.int(llvm_t, x) 19 | elif isinstance(t, PtrT): 20 | return GenericValue.pointer(x) 21 | else: 22 | ctypes_obj = type_conv.from_python(x) 23 | return GenericValue.pointer(ctypes.addressof(ctypes_obj)) 24 | 25 | def ctypes_to_generic_value(cval, t): 26 | if isinstance(t, FloatT): 27 | llvm_t = llvm_types.llvm_value_type(t) 28 | return GenericValue.real(llvm_t, cval.value) 29 | elif isinstance(t, SignedT): 30 | llvm_t = llvm_types.llvm_value_type(t) 31 | return GenericValue.int_signed(llvm_t, cval.value) 32 | elif isinstance(t, IntT): 33 | llvm_t = llvm_types.llvm_value_type(t) 34 | return GenericValue.int(llvm_t, cval.value) 35 | elif isinstance(t, NoneT): 36 | return GenericValue.int(llvm_types.int64_t, 0) 37 | elif isinstance(t, PtrT): 38 | return GenericValue.pointer(ctypes.addressof(cval.contents)) 39 | else: 40 | return GenericValue.pointer(ctypes.addressof(cval)) 41 | 42 | def generic_value_to_python(gv, t): 43 | if isinstance(t, SignedT): 44 | return t.dtype.type(gv.as_int_signed() ) 45 | elif isinstance(t, IntT): 46 | return t.dtype.type( gv.as_int() ) 47 | elif isinstance(t, FloatT): 48 | llvm_t = llvm_types.ctypes_scalar_to_lltype(t.ctypes_repr) 49 | return t.dtype.type(gv.as_real(llvm_t)) 50 | elif isinstance(t, NoneT): 51 | return None 52 | else: 53 | addr = gv.as_pointer() 54 | struct = t.ctypes_repr.from_address(addr) 55 | return t.to_python(struct) -------------------------------------------------------------------------------- /parakeet/llvm_backend/llvm_config.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | ###################################### 4 | # OPTIMIZER OPTIONS # 5 | ###################################### 6 | 7 | # run LLVM optimization passes 8 | llvm_optimize = True 9 | 10 | # number of times to run optimizations 11 | llvm_num_passes = 4 12 | 13 | # run verifier over generated LLVM code? 14 | llvm_verify = True 15 | 16 | 17 | ###################################### 18 | # PRINTING OPTIONS # 19 | ###################################### 20 | 21 | # print generated assembly of compiled functions 22 | print_x86 = False 23 | 24 | # show LLVM bytecode before optimization passes 25 | print_unoptimized_llvm = False 26 | 27 | # show LLVM bytecode after optimizations 28 | # print_optimized_llvm = False 29 | 30 | -------------------------------------------------------------------------------- /parakeet/llvm_backend/llvm_helpers.py: -------------------------------------------------------------------------------- 1 | import llvm.core as llcore 2 | 3 | from .. ndtypes import ScalarT, FloatT, Int32, Int64 4 | from llvm_types import llvm_value_type 5 | 6 | def const(python_scalar, parakeet_type): 7 | assert isinstance(parakeet_type, ScalarT) 8 | llvm_type = llvm_value_type(parakeet_type) 9 | if isinstance(parakeet_type, FloatT): 10 | return llcore.Constant.real(llvm_type, float(python_scalar)) 11 | else: 12 | return llcore.Constant.int(llvm_type, int(python_scalar)) 13 | 14 | def int32(x): 15 | """Make LLVM constants of type int32""" 16 | return const(x, Int32) 17 | 18 | def int64(x): 19 | return const(x, Int64) 20 | 21 | def zero(llvm_t): 22 | """ 23 | Make a zero constant of either int or real type. 24 | Doesn't (yet) work for vector constants! 25 | """ 26 | if isinstance(llvm_t, llcore.IntegerType): 27 | return llcore.Constant.int(llvm_t, 0) 28 | else: 29 | return llcore.Constant.real(llvm_t, 0.0) 30 | 31 | def one(llvm_t): 32 | """ 33 | Make a constant 1 of either int or real type. 34 | Doesn't (yet) work for vector constants! 35 | """ 36 | if isinstance(llvm_t, llcore.IntegerType): 37 | return llcore.Constant.int(llvm_t, 1) 38 | else: 39 | return llcore.Constant.real(llvm_t, 1.0) 40 | 41 | -------------------------------------------------------------------------------- /parakeet/names.py: -------------------------------------------------------------------------------- 1 | class NameNotFound(Exception): 2 | def __init__(self, name): 3 | self.name = name 4 | 5 | 6 | def __str__(self): 7 | return self.name 8 | 9 | versions = {} 10 | original_names = {} 11 | 12 | def get(name): 13 | version = versions.get(name) 14 | if version is None: 15 | raise NameNotFound(name) 16 | else: 17 | return "%s.%d" % (name, version) 18 | 19 | def fresh(name): 20 | version = versions.get(name, 0) + 1 21 | versions[name] = version 22 | if version == 1: 23 | ssa_name = name 24 | else: 25 | ssa_name = "%s.%d" % (name, version) 26 | original_names[ssa_name] = name 27 | # assert ssa_name != 'array_elt.3' 28 | return ssa_name 29 | 30 | lcase_chars = [chr(i + 97) for i in xrange(26)] 31 | def fresh_list(count): 32 | prefixes = lcase_chars[:count] 33 | while len(prefixes) < count: 34 | count -= 26 35 | prefixes += lcase_chars[:count] 36 | return map(fresh, prefixes) 37 | 38 | 39 | def original(unique_name): 40 | original_name = original_names.get(unique_name) 41 | 42 | if original_name is None: 43 | versions[unique_name] = 1 44 | original_names[unique_name] = unique_name 45 | return unique_name 46 | else: 47 | return original_name 48 | 49 | def refresh(unique_name): 50 | """Given an existing unique name, create another versioned name with the same root""" 51 | try: 52 | return fresh(original(unique_name)) 53 | except NameNotFound: 54 | # it wasn't really an SSA name but keep going anyway 55 | return fresh(unique_name) 56 | 57 | def add_prefix(prefix, name): 58 | base = original(name) 59 | return fresh(prefix + base) -------------------------------------------------------------------------------- /parakeet/ndtypes/__init__.py: -------------------------------------------------------------------------------- 1 | from array_type import (ArrayT, make_array_type, 2 | elt_type, elt_types, rank, 3 | get_rank, lower_rank, 4 | lower_rank, lower_ranks, increase_rank) 5 | 6 | from closure_type import make_closure_type, ClosureT 7 | 8 | from core_types import (Type, AnyT, Any, UnknownT, Unknown, 9 | TypeFailure, IncompatibleTypes, FieldNotFound, 10 | NoneT, NoneType, 11 | ConcreteT, ImmutableT, StructT, 12 | TypeValueT, combine_type_list) 13 | 14 | from fn_type import make_fn_type, FnT 15 | 16 | from ptr_type import PtrT, ptr_type 17 | 18 | from scalar_types import (ScalarT, 19 | IntT, FloatT, BoolT, SignedT, UnsignedT, 20 | Int8, Int16, Int24, Int32, Int64, 21 | UInt8, UInt16, UInt32, UInt64, 22 | Bool, Float32, Float64, 23 | is_scalar_subtype, is_scalar, all_scalars, 24 | from_dtype, from_char_code) 25 | 26 | from slice_type import SliceT, make_slice_type 27 | 28 | from tuple_type import TupleT, make_tuple_type, empty_tuple_t, repeat_tuple 29 | 30 | import dtypes 31 | import type_conv 32 | from type_conv import typeof 33 | 34 | -------------------------------------------------------------------------------- /parakeet/ndtypes/dtypes.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | # partial mapping, since ctypes doesn't support 5 | # complex numbers 6 | bool8 = np.dtype('bool8') 7 | 8 | int8 = np.dtype('int8') 9 | uint8 = np.dtype('uint8') 10 | 11 | int16 = np.dtype('int16') 12 | uint16 = np.dtype('uint16') 13 | 14 | int32 = np.dtype('int32') 15 | uint32 = np.dtype('uint32') 16 | 17 | int64 = np.dtype('int64') 18 | uint64 = np.dtype('uint64') 19 | 20 | 21 | float32 = np.dtype('float32') 22 | float64 = np.dtype('float64') 23 | complex64 = np.dtype('complex64') 24 | complex128 = np.dtype('complex128') 25 | 26 | def is_float(dtype): 27 | return dtype.type in np.sctypes['float'] 28 | 29 | def is_signed(dtype): 30 | return dtype.type in np.sctypes['int'] 31 | 32 | def is_unsigned(dtype): 33 | return dtype.type in np.sctypes['uint'] 34 | 35 | def is_complex(dtype): 36 | return dtype.type in np.sctypes['complex'] 37 | 38 | def is_bool(dtype): 39 | return dtype == np.bool8 40 | 41 | def is_int(dtype): 42 | return is_bool(dtype) or is_signed(dtype) or is_unsigned(dtype) 43 | 44 | 45 | import ctypes 46 | _to_ctypes = { 47 | bool8 : ctypes.c_bool, 48 | 49 | int8 : ctypes.c_int8, 50 | uint8 : ctypes.c_uint8, 51 | 52 | int16 : ctypes.c_int16, 53 | uint16 : ctypes.c_uint16, 54 | 55 | int32 : ctypes.c_int32, 56 | uint32 : ctypes.c_uint32, 57 | 58 | int64 : ctypes.c_int64, 59 | uint64 : ctypes.c_uint64, 60 | 61 | float32 : ctypes.c_float, 62 | float64 : ctypes.c_double, 63 | } 64 | 65 | def to_ctypes(dtype): 66 | """ 67 | Give the ctypes representation for each numpy scalar type. 68 | Beware that complex numbers have no assumed representation 69 | and thus aren't valid arguments to this function. 70 | """ 71 | if dtype in _to_ctypes: 72 | return _to_ctypes[dtype] 73 | else: 74 | raise RuntimeError("No conversion from %s to ctypes" % dtype) 75 | 76 | -------------------------------------------------------------------------------- /parakeet/ndtypes/fn_type.py: -------------------------------------------------------------------------------- 1 | from core_types import IncompatibleTypes, ImmutableT 2 | 3 | class FnT(ImmutableT): 4 | """Type of a typed function""" 5 | def __init__(self, input_types, return_type): 6 | self.input_types = tuple(input_types) 7 | self.return_type = return_type 8 | self._hash = hash(self.input_types + (return_type,)) 9 | 10 | def __str__(self): 11 | input_str = ", ".join(str(t) for t in self.input_types) 12 | return "(%s)->%s" % (input_str, self.return_type) 13 | 14 | def __repr__(self): 15 | return str(self) 16 | 17 | def __eq__(self, other): 18 | return other.__class__ is FnT and \ 19 | self.return_type == other.return_type and \ 20 | len(self.input_types) == len(other.input_types) and \ 21 | all(t1 == t2 for (t1, t2) in 22 | zip(self.input_types, other.input_types)) 23 | 24 | def combine(self, other): 25 | if self == other: 26 | return self 27 | else: 28 | raise IncompatibleTypes(self, other) 29 | 30 | def __hash__(self): 31 | return self._hash 32 | 33 | _fn_type_cache = {} 34 | def make_fn_type(input_types, return_type): 35 | input_types = tuple(input_types) 36 | key = input_types, return_type 37 | if key in _fn_type_cache: 38 | return _fn_type_cache[key] 39 | else: 40 | t = FnT(input_types, return_type) 41 | _fn_type_cache[key] = t 42 | return t -------------------------------------------------------------------------------- /parakeet/ndtypes/ptr_type.py: -------------------------------------------------------------------------------- 1 | from core_types import ConcreteT 2 | from scalar_types import IntT 3 | 4 | ########################################### 5 | # 6 | # Pointers! 7 | # 8 | ########################################### 9 | 10 | class PtrT(ConcreteT): 11 | """ 12 | I'm not giving pointer a concrete to_python/from_python conversion or any 13 | usable fields, so it's up to our ctypes_repr and llvm_backend to appropriately 14 | interpret objects of this type. 15 | """ 16 | def __init__(self, elt_type): 17 | self.elt_type = elt_type 18 | self._hash = hash(elt_type) 19 | 20 | rank = 1 21 | def index_type(self, idx): 22 | assert isinstance(idx, IntT), \ 23 | "Index into pointer must be of type int, got %s" % (idx) 24 | return self.elt_type 25 | 26 | def children(self): 27 | return self.elt_type 28 | 29 | def __str__(self): 30 | return "ptr(%s)" % self.elt_type 31 | 32 | def __eq__(self, other): 33 | return other.__class__ is PtrT and self.elt_type == other.elt_type 34 | 35 | def __hash__(self): 36 | return self._hash 37 | 38 | def __repr__(self): 39 | return str(self) 40 | 41 | @property 42 | def ctypes_repr(self): 43 | return self._ctypes_repr 44 | 45 | _ptr_types = {} 46 | def ptr_type(t): 47 | if t in _ptr_types: 48 | return _ptr_types[t] 49 | else: 50 | ptr_t = PtrT(t) 51 | _ptr_types[t] = ptr_t 52 | return ptr_t 53 | -------------------------------------------------------------------------------- /parakeet/ndtypes/slice_type.py: -------------------------------------------------------------------------------- 1 | import type_conv 2 | 3 | from core_types import StructT, ImmutableT, IncompatibleTypes 4 | 5 | class SliceT(StructT, ImmutableT): 6 | def __init__(self, start_type, stop_type, step_type): 7 | self.start_type = start_type 8 | self.stop_type = stop_type 9 | self.step_type = step_type 10 | self._fields_ = [('start',start_type), ('stop', stop_type), ('step', step_type)] 11 | self._hash = hash((self.start_type, self.stop_type, self.step_type)) 12 | 13 | def children(self): 14 | yield self.start_type 15 | yield self.stop_type 16 | yield self.step_type 17 | 18 | def __eq__(self, other): 19 | return self is other or \ 20 | (other.__class__ is SliceT and 21 | self.start_type == other.start_type and 22 | self.stop_type == other.stop_type and 23 | self.step_type == other.step_type) 24 | 25 | def __hash__(self): 26 | return self._hash 27 | 28 | def combine(self, other): 29 | if self == other: return self 30 | else:raise IncompatibleTypes(self, other) 31 | 32 | def __str__(self): 33 | return "SliceT(%s, %s, %s)" % (self.start_type, 34 | self.stop_type, 35 | self.step_type) 36 | 37 | def __repr__(self): 38 | return str(self) 39 | 40 | _slice_type_cache = {} 41 | def make_slice_type(start_t, stop_t, step_t): 42 | key = (start_t, stop_t, step_t) 43 | if key in _slice_type_cache: 44 | return _slice_type_cache[key] 45 | else: 46 | t = SliceT(start_t, stop_t, step_t) 47 | _slice_type_cache[key] = t 48 | return t 49 | 50 | def typeof_slice(s): 51 | start_type = type_conv.typeof(s.start) 52 | stop_type = type_conv.typeof(s.stop) 53 | step_type = type_conv.typeof(s.step) 54 | return make_slice_type(start_type, stop_type, step_type) 55 | 56 | type_conv.register(slice, SliceT, typeof_slice) 57 | -------------------------------------------------------------------------------- /parakeet/openmp_backend/__init__.py: -------------------------------------------------------------------------------- 1 | from multicore_compiler import MulticoreCompiler 2 | from run_function import run -------------------------------------------------------------------------------- /parakeet/openmp_backend/config.py: -------------------------------------------------------------------------------- 1 | collapse_nested_loops = True 2 | schedule = 'static' 3 | -------------------------------------------------------------------------------- /parakeet/openmp_backend/run_function.py: -------------------------------------------------------------------------------- 1 | from .. import config 2 | 3 | from ..c_backend.prepare_args import prepare_args 4 | from ..transforms.pipeline import lower_to_adverbs 5 | from ..value_specialization import specialize 6 | 7 | 8 | from multicore_compiler import MulticoreCompiler 9 | 10 | _cache = {} 11 | def run(fn, args): 12 | args = prepare_args(args, fn.input_types) 13 | fn = lower_to_adverbs.apply(fn) 14 | if config.value_specialization: 15 | fn = specialize(fn, python_values = args) 16 | key = fn.cache_key 17 | if key in _cache: 18 | return _cache[key](*args) 19 | else: 20 | compiled_fn = MulticoreCompiler().compile_entry(fn) 21 | c_fn = compiled_fn.c_fn 22 | _cache[key] = c_fn 23 | return c_fn(*args) 24 | -------------------------------------------------------------------------------- /parakeet/package_info.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Alex Rubinsteyn' 2 | __email__ = 'alex -dot- rubinsteyn -at- gmail -dot- com' 3 | __desc__ = 'Runtime compiler for numerical Python' 4 | __license__ = 'BSD3' 5 | __version__ = '0.24' 6 | __website__ = 'http://www.parakeetpython.com' 7 | 8 | -------------------------------------------------------------------------------- /parakeet/shape_inference/__init__.py: -------------------------------------------------------------------------------- 1 | import shape 2 | from shape import * 3 | 4 | from shape_from_type import shapes_from_types 5 | from shape_inference import (shape_env, call_shape_expr, bind, bind_pairs, 6 | subst, subst_list, symbolic_call) 7 | -------------------------------------------------------------------------------- /parakeet/syntax/__init__.py: -------------------------------------------------------------------------------- 1 | from adverbs import * 2 | 3 | from adverb_helpers import * 4 | 5 | from actual_args import ActualArgs 6 | 7 | from array_expr import (AllocArray, Array, ArrayExpr, ArrayView, 8 | Compress, 9 | ConstArray, ConstArrayLike, 10 | DiagonalArray, 11 | Range, Ravel, Reshape, 12 | Shape, Slice, Strides, 13 | Transpose, 14 | Where) 15 | 16 | 17 | from delay_until_typed import DelayUntilTyped 18 | 19 | from expr import Attribute, Call, Cast, Const, Closure, ClosureElt, Expr 20 | from expr import PrimCall, Select, Var 21 | 22 | from formal_args import FormalArgs, MissingArgsError, TooManyArgsError 23 | 24 | import helpers 25 | from helpers import * 26 | 27 | from low_level import Alloc, Struct, Free, SourceExpr, SourceStmt 28 | 29 | from seq_expr import Index, Enumerate, Len, Zip 30 | 31 | from stmt import (Stmt, Assign, Comment, ExprStmt, ForLoop, If, Return, While, ParFor, 32 | PrintString, block_to_str) 33 | 34 | from source_info import SourceInfo 35 | from tuple_expr import Tuple, TupleProj 36 | 37 | from typed_fn import TypedFn 38 | from type_value import TypeValue 39 | 40 | from untyped_fn import UntypedFn 41 | 42 | from wrappers import build_untyped_prim_fn, build_untyped_expr_fn, build_untyped_cast_fn 43 | 44 | -------------------------------------------------------------------------------- /parakeet/syntax/delay_until_typed.py: -------------------------------------------------------------------------------- 1 | 2 | from expr import Expr 3 | 4 | 5 | class DelayUntilTyped(Expr): 6 | """ 7 | Once the list of values has been annotated with locally inferred types, 8 | pass them to the given function to construct a final expression 9 | """ 10 | def __init__(self, values, keywords, fn, source_info = None): 11 | """ 12 | No need for a 'type' argument since the user-supplied function 13 | will generate a typed expression to replace this one 14 | """ 15 | if isinstance(values, list): values = tuple(values) 16 | elif not isinstance(values, tuple): values = (self.values,) 17 | self.values = values 18 | 19 | if keywords is None: keywords = {} 20 | self.keywords = keywords 21 | 22 | self.fn = fn 23 | self.source_info = source_info 24 | self.type = None 25 | 26 | def children(self): 27 | return tuple(self.values) + tuple(self.keywords.values()) -------------------------------------------------------------------------------- /parakeet/syntax/list_expr.py: -------------------------------------------------------------------------------- 1 | from seq_expr import SeqExpr 2 | 3 | class List(SeqExpr): 4 | def __init__(self, elts, type = None, source_info = None): 5 | self.elts = tuple(elts) 6 | self.type = type 7 | self.source_info = source_info 8 | 9 | def children(self): 10 | return self.elts 11 | -------------------------------------------------------------------------------- /parakeet/syntax/seq_expr.py: -------------------------------------------------------------------------------- 1 | from expr import Expr 2 | 3 | class SeqExpr(Expr): 4 | def __init__(self, value, type = None, source_info = None): 5 | self.value = value 6 | self.type = type 7 | self.source_info = source_info 8 | 9 | def children(self): 10 | yield self.value 11 | 12 | class Enumerate(SeqExpr): 13 | pass 14 | 15 | class Zip(SeqExpr): 16 | def __init__(self, values, type = None, source_info = None): 17 | self.values = tuple(values) 18 | self.type = type 19 | self.source_info = source_info 20 | 21 | def children(self): 22 | return self.values 23 | 24 | class Len(SeqExpr): 25 | pass 26 | 27 | class Index(SeqExpr): 28 | """ 29 | TODO: 30 | - make all user-defined indexing check_negative=True by default 31 | - implement backend logic for lowering check_negative 32 | """ 33 | def __init__(self, value, index, check_negative = None, type = None, source_info = None): 34 | self.value = value 35 | self.index = index 36 | self.check_negative = check_negative 37 | self.type = type 38 | self.source_info = source_info 39 | 40 | def __eq__(self, other): 41 | return other.__class__ is Index and \ 42 | other.value == self.value and \ 43 | other.index == self.index 44 | 45 | def __hash__(self): 46 | return hash((self.value, self.index)) 47 | 48 | def children(self): 49 | yield self.value 50 | yield self.index 51 | 52 | def __str__(self): 53 | return "%s[%s]" % (self.value, self.index) 54 | 55 | -------------------------------------------------------------------------------- /parakeet/syntax/source_info.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | 3 | SourceInfo = namedtuple('SourceInfo', ('filename', 'line', 'col', 'function')) 4 | -------------------------------------------------------------------------------- /parakeet/syntax/tuple_expr.py: -------------------------------------------------------------------------------- 1 | from ..ndtypes import make_tuple_type 2 | 3 | from expr import Const 4 | from seq_expr import SeqExpr 5 | 6 | class Tuple(SeqExpr): 7 | def __init__(self, elts, type = None, source_info = None): 8 | self.elts = tuple(elts) 9 | self.type = type 10 | self.source_info = source_info 11 | 12 | if self.type is None and all(e.type is not None for e in self.elts): 13 | self.type = make_tuple_type(tuple(e.type for e in self.elts)) 14 | 15 | def __iter__(self): 16 | return iter(self.elts) 17 | 18 | def __len__(self): 19 | return len(self.elts) 20 | 21 | def __getitem__(self, idx): 22 | return self.elts[idx] 23 | 24 | def __str__(self): 25 | if len(self.elts) > 0: 26 | return ", ".join([str(e) for e in self.elts]) 27 | else: 28 | return "()" 29 | 30 | def children(self): 31 | return self.elts 32 | 33 | def __hash__(self): 34 | return hash(tuple(self.elts)) 35 | 36 | 37 | class TupleProj(SeqExpr): 38 | def __init__(self, tuple, index, type = None, source_info = None): 39 | self.tuple = tuple 40 | self.index = index 41 | self.type = type 42 | self.source_info = source_info 43 | 44 | if self.type is None: 45 | if self.tuple.type is not None and self.index.__class__ is Const: 46 | self.type = self.tuple.type.elt_types[self.index.value] 47 | 48 | def __str__(self): 49 | return "TupleProj(%s, %d)" % (self.tuple, self.index) 50 | 51 | def children(self): 52 | return (self.tuple,) 53 | 54 | def __hash__(self): 55 | return hash((self.tuple, self.index)) -------------------------------------------------------------------------------- /parakeet/syntax/type_value.py: -------------------------------------------------------------------------------- 1 | from .. ndtypes import TypeValueT 2 | from expr import Expr 3 | 4 | 5 | class TypeValue(Expr): 6 | """ 7 | Value materialization of a type 8 | """ 9 | def __init__(self, type_value, type = None, source_info = None): 10 | self.type_value = type_value 11 | 12 | if type is None: type = TypeValueT(self.type_value) 13 | assert isinstance(type, TypeValueT) 14 | assert type.type is not None 15 | 16 | self.type = type 17 | 18 | -------------------------------------------------------------------------------- /parakeet/syntax/untyped_fn.py: -------------------------------------------------------------------------------- 1 | 2 | from ..ndtypes import make_closure_type 3 | from expr import Expr 4 | from formal_args import FormalArgs 5 | from stmt import block_to_str 6 | 7 | 8 | class UntypedFn(Expr): 9 | """ 10 | Function definition. 11 | A top-level function can have references to python values from its enclosing 12 | scope, which are stored in the 'python_refs' field. 13 | 14 | A nested function, on the other hand, might refer to some variables from its 15 | enclosing Parakeet scope, whose original names are stored in 16 | 'parakeet_nonlocals' 17 | """ 18 | 19 | registry = {} 20 | 21 | def __init__(self, name, args, body, 22 | python_refs = None, 23 | parakeet_nonlocals = None, 24 | doc_string = None, 25 | source_info = None): 26 | assert isinstance(name, str), "Expected string for fn name, got %s" % name 27 | self.name = name 28 | 29 | assert isinstance(args, FormalArgs), \ 30 | "Expected arguments to fn to be FormalArgs object, got %s" % self.args 31 | self.args = args 32 | 33 | assert isinstance(body, list), \ 34 | "Expected body of fn to be list of statements, got " + str(body) 35 | self.body = body 36 | 37 | self.python_refs = python_refs 38 | self.parakeet_nonlocals = parakeet_nonlocals 39 | 40 | self.type = make_closure_type(self, ()) 41 | 42 | self.source_info = source_info 43 | self.registry[self.name] = self 44 | 45 | 46 | 47 | def __repr__(self): 48 | return "def %s(%s):%s" % (self.name, self.args, block_to_str(self.body)) 49 | 50 | def __str__(self): 51 | return repr(self) 52 | 53 | def __hash__(self): 54 | return hash(self.name) 55 | 56 | def python_nonlocals(self): 57 | if self.python_refs: 58 | return [ref.deref() for ref in self.python_refs] 59 | else: 60 | return [] 61 | 62 | def children(self): 63 | return () 64 | -------------------------------------------------------------------------------- /parakeet/syntax/wrappers.py: -------------------------------------------------------------------------------- 1 | from .. import names, prims 2 | from ..ndtypes import ScalarT, Type, type_conv 3 | from .. syntax import FormalArgs, Var, UntypedFn, Return, PrimCall, Expr, Cast 4 | 5 | 6 | _untyped_fn_cache = {} 7 | def simple_untyped_fn(name, 8 | expr, 9 | n_inputs = 1, 10 | fixed_args = [], 11 | keyword_args = {}, 12 | unpack = False): 13 | key = name, expr, n_inputs, tuple(fixed_args), tuple(keyword_args.items()), unpack 14 | if key in _untyped_fn_cache: 15 | return _untyped_fn_cache[key] 16 | 17 | fn_name = names.fresh(name) 18 | args_obj = FormalArgs() 19 | 20 | arg_vars = [] 21 | for name in names.fresh_list(n_inputs): 22 | args_obj.add_positional(name) 23 | arg_vars.append(Var(name)) 24 | 25 | if unpack: 26 | combined_args = tuple(fixed_args) + tuple(arg_vars) 27 | else: 28 | combined_args = tuple(fixed_args) + (tuple(arg_vars),) 29 | result = expr(*combined_args, **keyword_args) 30 | body = [Return(result)] 31 | fundef = UntypedFn(fn_name, args_obj, body, []) 32 | _untyped_fn_cache[key] = fundef 33 | return fundef 34 | 35 | def build_untyped_prim_fn(p): 36 | """Given a primitive, return an untyped function which calls that prim""" 37 | assert isinstance(p, prims.Prim), "Expected Prim but got %s" % p 38 | return simple_untyped_fn(p.name, PrimCall, p.nin, [p]) 39 | 40 | 41 | def build_untyped_expr_fn(expr, n_args = 1): 42 | """Given an expression, return a function which applies that expression to arguments""" 43 | return simple_untyped_fn(expr.__name__ + "_fn", expr, n_args) 44 | 45 | _untyped_cast_wrappers = {} 46 | def build_untyped_cast_fn(t): 47 | if not isinstance(t, Type): 48 | t = type_conv.equiv_type(t) 49 | assert isinstance(t, ScalarT), "Expected scalar type but got %s" % t 50 | return simple_untyped_fn("cast_" + str(t), Cast, 1, keyword_args = {'type': t}) 51 | -------------------------------------------------------------------------------- /parakeet/system_info.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import platform 4 | 5 | 6 | mac_os = platform.system() == 'Darwin' 7 | windows = platform.system() == 'Windows' 8 | 9 | def check_openmp_available(): 10 | cmd = """echo "int main() {}" | clang -fopenmp -x c++ -""" 11 | with open(os.devnull, 'w') as devnull: 12 | p = subprocess.Popen(cmd, shell=True, stderr = devnull, stdout = devnull) 13 | p.wait() 14 | code = p.returncode 15 | return code == 0 16 | 17 | openmp_available = check_openmp_available() -------------------------------------------------------------------------------- /parakeet/transforms/__init__.py: -------------------------------------------------------------------------------- 1 | from clone_stmt import CloneStmt 2 | from clone_function import CloneFunction 3 | from dead_code_elim import DCE 4 | from inline import Inliner 5 | from phase import Phase 6 | from simplify import Simplify 7 | from subst import subst_expr, subst_expr_list, subst_expr_tuple, subst_stmt_list 8 | from transform import Transform -------------------------------------------------------------------------------- /parakeet/transforms/imap_elim.py: -------------------------------------------------------------------------------- 1 | from transform import Transform 2 | 3 | class IndexMapElimination(Transform): 4 | """ 5 | a = IndexMap(f, bounds) 6 | ... a[i] ... 7 | 8 | -becomes- 9 | 10 | ... f(i) ... 11 | """ 12 | def transform_IndexMap(self, expr): 13 | return expr -------------------------------------------------------------------------------- /parakeet/transforms/parfor_to_nested_loops.py: -------------------------------------------------------------------------------- 1 | from transform import Transform 2 | 3 | class ParForToNestedLoops(Transform): 4 | def transform_ParFor(self, stmt): 5 | fn = self.transform_expr(stmt.fn) 6 | self.nested_loops(stmt.bounds, fn) 7 | 8 | -------------------------------------------------------------------------------- /parakeet/transforms/permute_reductions.py: -------------------------------------------------------------------------------- 1 | from ..builder import build_fn 2 | from ..ndtypes import ArrayT, lower_rank 3 | from ..prims import Prim 4 | from ..syntax import Return, Map 5 | from ..syntax.helpers import is_identity_fn, unwrap_constant 6 | from transform import Transform 7 | 8 | def get_nested_map(fn): 9 | if len(fn.body) != 1: 10 | return None 11 | stmt = fn.body[0] 12 | if stmt.__class__ is not Return: 13 | return None 14 | if stmt.value.__class__ is not Map: 15 | return None 16 | return stmt.value 17 | 18 | 19 | class PermuteReductions(Transform): 20 | """ 21 | When we have a reduction of array values, such as: 22 | Reduce(combine = Map(f), X, axis = 0) 23 | it can be more efficient to interchange the Map and Reduce: 24 | Map(combine = f, X, axis = 1) 25 | """ 26 | 27 | 28 | def transform_Reduce(self, expr): 29 | return expr 30 | 31 | def transform_Scan(self, expr): 32 | if len(expr.args) > 1: 33 | return expr 34 | 35 | axis = unwrap_constant(expr.axis) 36 | if axis is None or not isinstance(axis, (int,long)) or axis > 1 or axis < 0: 37 | return expr 38 | 39 | if not isinstance(expr.type, ArrayT) or expr.type.rank != 2: 40 | return expr 41 | 42 | fn = self.get_fn(expr.fn) 43 | fn_closure_args = self.closure_elts(expr.fn) 44 | if len(fn_closure_args) > 0: 45 | return expr 46 | 47 | combine = self.get_fn(expr.combine) 48 | combine_closure_args = self.closure_elts(expr.closure) 49 | if len(combine_closure_args) > 0: 50 | return expr 51 | 52 | if is_identity_fn(fn): 53 | nested_map = get_nested_map(combine) 54 | 55 | if not isinstance(nested_map.fn, Prim): 56 | return expr 57 | 58 | arg_t = expr.args[0].type 59 | elt_t = lower_rank(arg_t, 1) 60 | new_nested_fn = None 61 | return Map(fn = new_nested_fn, 62 | args = expr.args, 63 | axis = 1 - axis, 64 | type = expr.type) 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /parakeet/transforms/range_propagation.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from .. import prims 4 | from ..syntax import Const 5 | from ..analysis.value_range_analysis import Interval 6 | from range_transform import RangeTransform 7 | 8 | class RangePropagation(RangeTransform): 9 | 10 | def visit_Var(self, expr): 11 | if expr.name in self.ranges: 12 | range_val = self.ranges[expr.name] 13 | if isinstance(range_val, Interval) and range_val.lower == range_val.upper: 14 | return Const(range_val.lower, type = expr.type) 15 | return expr 16 | 17 | def visit_PrimCall(self, expr): 18 | p = expr.prim 19 | result = None 20 | if isinstance(p, prims.Cmp): 21 | argx, argy = expr.args 22 | x, y = self.get(argx), self.get(argy) 23 | if x is not None and y is not None: 24 | if p == prims.equal: 25 | result = self.cmp_eq(x,y) 26 | elif p == prims.less: 27 | result = self.cmp_lt(x,y) 28 | elif p == prims.less_equal: 29 | result = self.cmp_lte(x, y) 30 | elif p == prims.greater: 31 | result = self.cmp_lt(y, x) 32 | elif p == prims.greater_equal: 33 | result = self.cmp_lte(y, x) 34 | 35 | 36 | if result is None: 37 | return expr 38 | else: 39 | return result 40 | 41 | -------------------------------------------------------------------------------- /parakeet/transforms/range_transform.py: -------------------------------------------------------------------------------- 1 | from ..analysis.value_range_analysis import (ValueRangeAnalyis, Interval, NoneValue) 2 | from ..syntax.helpers import true, false 3 | from transform import Transform 4 | 5 | class RangeTransform(Transform, ValueRangeAnalyis): 6 | """ 7 | Base class for transforms which use value ranges gathered from analysis 8 | """ 9 | 10 | def pre_apply(self, old_fn): 11 | ValueRangeAnalyis.__init__(self) 12 | self.visit_fn(old_fn) 13 | 14 | def cmp_eq(self, x, y): 15 | if not isinstance(x, Interval) or not isinstance(y, Interval): 16 | return None 17 | if x.lower == y.lower and x.upper == y.upper: 18 | return true 19 | if x.upper < y.lower or y.upper < x.lower: 20 | return false 21 | return None 22 | 23 | def cmp_lt(self, x, y): 24 | if not isinstance(x, Interval) or not isinstance(y, Interval): 25 | return None 26 | if x.upper < y.lower: 27 | return true 28 | elif x.lower > y.upper: 29 | return false 30 | else: 31 | return None 32 | 33 | def cmp_lte(self, x, y): 34 | if not isinstance(x, Interval) or not isinstance(y, Interval): 35 | return None 36 | if x.upper < y.lower: 37 | return true 38 | elif x.lower > y.upper: 39 | return false 40 | else: 41 | return None 42 | -------------------------------------------------------------------------------- /parakeet/transforms/redundant_load_elim.py: -------------------------------------------------------------------------------- 1 | from .. syntax import Assign, Index, Var 2 | 3 | from loop_transform import LoopTransform 4 | 5 | class RedundantLoadElimination(LoopTransform): 6 | def transform_block(self, stmts): 7 | stmts = LoopTransform.transform_block(self, stmts) 8 | if self.is_simple_block(stmts, allow_branches = False): 9 | reads, writes = self.collect_memory_accesses(stmts) 10 | safe_arrays = set([]) 11 | for name in reads: 12 | # if any alias of this array gets written to, consider it unsafe 13 | aliases = self.may_alias.get(name, set([])) 14 | aliases.add(name) 15 | unsafe = any(alias in writes for alias in aliases) 16 | if not unsafe: 17 | safe_arrays.add(name) 18 | available_expressions = {} 19 | new_stmts = [] 20 | for stmt in stmts: 21 | if stmt.__class__ is Assign: 22 | if stmt.rhs.__class__ is Index and \ 23 | stmt.rhs.value.__class__ is Var and \ 24 | stmt.rhs.value.name in safe_arrays: 25 | key = (stmt.rhs.value.name, stmt.rhs.index) 26 | if key in available_expressions: 27 | stmt.rhs = available_expressions[key] 28 | elif stmt.lhs.__class__ is Var: 29 | available_expressions[key] = stmt.lhs 30 | else: 31 | temp = self.fresh_var(stmt.rhs.type, "load") 32 | new_stmts.append(Assign(temp, stmt.rhs)) 33 | stmt.rhs = temp 34 | available_expressions[key] = temp 35 | new_stmts.append(stmt) 36 | return new_stmts 37 | else: 38 | return stmts 39 | 40 | -------------------------------------------------------------------------------- /parakeet/transforms/subst.py: -------------------------------------------------------------------------------- 1 | from .. syntax import Expr, Var 2 | from clone_function import CloneFunction 3 | from transform import Transform 4 | 5 | class RewriteVars(Transform): 6 | def __init__(self, rename_dict): 7 | Transform.__init__(self, require_types = False) 8 | self.rename_dict = rename_dict 9 | 10 | def transform_merge(self, old_merge): 11 | new_merge = {} 12 | for (k,(l,r)) in old_merge.iteritems(): 13 | new_name = self.rename_dict.get(k,k) 14 | if type(new_name) != str: 15 | assert new_name.__class__ is Var, \ 16 | "Unexpected substitution %s for %s" % (new_name, k) 17 | new_name = new_name.name 18 | new_left = self.transform_expr(l) 19 | new_right = self.transform_expr(r) 20 | new_merge[new_name] = new_left, new_right 21 | return new_merge 22 | 23 | def transform_Var(self, expr): 24 | new_value = self.rename_dict.get(expr.name, expr.name) 25 | if new_value.__class__ is str: 26 | if new_value != expr.name: 27 | expr.name = new_value 28 | return expr 29 | else: 30 | assert isinstance(expr, Expr) 31 | assert new_value.type is not None, \ 32 | "Type of replacement value %s can't be None" % new_value 33 | return new_value 34 | 35 | def subst_expr(expr, rename_dict): 36 | fresh_expr = CloneFunction().transform_expr(expr) 37 | return RewriteVars(rename_dict).transform_expr(fresh_expr) 38 | 39 | def subst_expr_list(nodes, rename_dict): 40 | return [subst_expr(node, rename_dict) for node in nodes] 41 | 42 | def subst_expr_tuple(elts, rename_dict): 43 | return tuple(subst_expr_list(elts, rename_dict)) 44 | 45 | def subst_stmt_list(stmts, rename_dict): 46 | fresh_stmts = CloneFunction().transform_block(stmts) 47 | return RewriteVars(rename_dict).transform_block(fresh_stmts) 48 | -------------------------------------------------------------------------------- /parakeet/transforms/vectorize.py: -------------------------------------------------------------------------------- 1 | from ..ndtypes import Int32, Int64, Float32, Float64 2 | 3 | from loop_transform import LoopTransform 4 | 5 | class Vectorize(LoopTransform): 6 | 7 | def pre_apply(self, _): 8 | # skip the may-alias analysis from LoopTransform 9 | pass 10 | 11 | vector_elt_types = (Int32, Int64, Float32, Float64) 12 | def vectorize_loop(self, stmt): 13 | 14 | candidate_names = set([]) 15 | before_values = {} 16 | after_values = {} 17 | for (k, (before, after)) in stmt.merge.iteritems(): 18 | t = before.type 19 | if t in self.vector_elt_types: 20 | candidate_names.add(k) 21 | before_values[k] = before 22 | after_values[k] = after 23 | 24 | 25 | def transform_ForLoop(self, stmt): 26 | # for now we only vectorize if 27 | # something is being accumulated, 28 | # otherwise you need more sophisticated 29 | # cost-base heuristic to avoid lots of 30 | # redundant SIMD packing and unpacking 31 | if self.is_simple_block(stmt.body) and len(stmt.merge) > 1: 32 | return self.vectorize_loop(stmt) 33 | else: 34 | return stmt 35 | -------------------------------------------------------------------------------- /parakeet/type_inference/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from linearize_args import linearize_actual_args, linearize_arg_types 3 | from rewrite_typed import rewrite_typed 4 | from type_inference import (specialize, invoke_result_type, infer_return_type) 5 | -------------------------------------------------------------------------------- /parakeet/type_inference/var_map.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import names 3 | 4 | class VarMap: 5 | def __init__(self): 6 | self._vars = {} 7 | 8 | def rename(self, old_name): 9 | new_name = names.refresh(old_name) 10 | self._vars[old_name] = new_name 11 | return new_name 12 | 13 | def lookup(self, old_name): 14 | if old_name in self._vars: 15 | return self._vars[old_name] 16 | else: 17 | return self.rename(old_name) 18 | 19 | def __str__(self): 20 | return "VarMap(%s)" % self._vars 21 | -------------------------------------------------------------------------------- /parakeet/value_specialization/__init__.py: -------------------------------------------------------------------------------- 1 | from value_specialization import specialize -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | dsltools 2 | numpy 3 | appdirs 4 | nose 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup, find_packages 4 | import os 5 | 6 | import parakeet.package_info 7 | 8 | readme_filename = os.path.join(os.path.dirname(__file__), 'README.md') 9 | with open(readme_filename, 'r') as f: 10 | readme = f.read() 11 | 12 | try: 13 | import pypandoc 14 | readme = pypandoc.convert(readme, to='rst', format='md') 15 | except: 16 | print "Conversion of long_description from markdown to reStructuredText failed, skipping..." 17 | 18 | setup( 19 | name="parakeet", 20 | description="Runtime compiler for numerical Python.", 21 | long_description=readme, 22 | classifiers=['Development Status :: 3 - Alpha', 23 | 'Topic :: Software Development :: Libraries', 24 | 'License :: OSI Approved :: BSD License', 25 | 'Intended Audience :: Developers', 26 | 'Programming Language :: Python :: 2.7', 27 | ], 28 | author="Alex Rubinsteyn", 29 | author_email="alexr@cs.nyu.edu", 30 | license="BSD", 31 | version=parakeet.package_info.__version__, 32 | url=parakeet.package_info.__website__, 33 | download_url = 'https://github.com/iskandr/parakeet/releases', 34 | packages=find_packages() + ['parakeet.test', 'parakeet.benchmarks', 'parakeet.examples'], 35 | package_dir={ 36 | 'parakeet.benchmarks' : './benchmarks', 37 | 'parakeet.test' : './test', 38 | 'parakeet.examples' : './examples', 39 | }, 40 | install_requires=[ 41 | 'numpy>=1.7', 42 | 'dsltools', 43 | 'appdirs', 44 | # LLVM is optional as long as you use the C backend 45 | # 'llvmpy', 46 | ]) 47 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/__init__.py -------------------------------------------------------------------------------- /test/adverbs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/adverbs/__init__.py -------------------------------------------------------------------------------- /test/adverbs/test_allpairs.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet.testing_helpers import expect, run_local_tests, eq, expect_allpairs 4 | 5 | int_mat = np.reshape(np.arange(9), (3,3)) 6 | float_mat = np.sqrt(int_mat) 7 | bool_mat = int_mat % 2 8 | matrices = [int_mat, float_mat, bool_mat] 9 | vecs = [m[0] for m in matrices] 10 | 11 | def dot(x,y): 12 | return sum(x*y) 13 | 14 | def test_dot(): 15 | expect_allpairs(dot, np.dot, vecs) 16 | 17 | def adverb_matmult(X,Y): 18 | return parakeet.allpairs(dot, X, Y) 19 | 20 | 21 | def test_adverb_matmult(): 22 | expect_allpairs(adverb_matmult, lambda x, y: np.dot(x, y.T), matrices) 23 | 24 | def allpairs_elt_diff(x,y): 25 | return parakeet.allpairs(lambda xi,yi: xi - yi, x, y) 26 | 27 | def test_allpairs_elt_diff(): 28 | def python_impl(x,y): 29 | nx = len(x) 30 | ny = len(y) 31 | result = np.zeros(shape = (nx,ny), dtype=(x[0]-y[0]).dtype) 32 | for i in xrange(nx): 33 | for j in xrange(ny): 34 | result[i,j] = x[i] - y[j] 35 | return result 36 | expect_allpairs(allpairs_elt_diff, python_impl, vecs) 37 | 38 | 39 | if __name__ == '__main__': 40 | run_local_tests() 41 | -------------------------------------------------------------------------------- /test/adverbs/test_imap.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet import jit 4 | from parakeet.testing_helpers import expect, run_local_tests, eq 5 | 6 | 7 | @jit 8 | def fill_with_const(a, k): 9 | def return_const(idx): 10 | return k 11 | return parakeet.imap(return_const, a.shape) 12 | 13 | def test_fill_with_const(): 14 | shape=(1,2,1,1) 15 | a = np.empty(shape=shape, dtype='float32') 16 | k = 3.137 17 | expected = np.ones(shape = shape, dtype='float32') * k 18 | expect(fill_with_const, [a, k], expected) 19 | 20 | 21 | def test_identity(): 22 | x = np.ones((1,1,2,1)) 23 | def get_idx(idx): 24 | return x[idx] 25 | y = parakeet.imap(get_idx, x.shape) 26 | assert eq(x,y) 27 | 28 | if __name__ == '__main__': 29 | run_local_tests() 30 | -------------------------------------------------------------------------------- /test/adverbs/test_outer_prod.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import time 3 | 4 | from parakeet import allpairs, multiply 5 | from parakeet.testing_helpers import expect, expect_allpairs, run_local_tests 6 | 7 | bool_vec = np.array([True, False, ]) 8 | int_vec = np.array([1,2,]) 9 | float_vec = np.array([10.0, 20.0, ]) 10 | 11 | vectors = [bool_vec, int_vec, float_vec] 12 | 13 | def loop_outer_prod(x,y,z): 14 | nx = x.shape[0] 15 | ny = y.shape[0] 16 | for i in xrange(0, nx): 17 | for j in xrange(0, ny): 18 | z[i,j] = x[i] * y[j] 19 | return z 20 | 21 | def test_loop_outer_prod(): 22 | for v1 in vectors: 23 | for v2 in vectors: 24 | res = np.outer(v1, v2) 25 | v3 = np.zeros_like(res) 26 | expect(loop_outer_prod, [v1, v2, v3], res) 27 | 28 | def adverb_outer_prod(x,y): 29 | return allpairs(multiply, x, y) 30 | 31 | def test_adverb_outer_prod(): 32 | expect_allpairs(adverb_outer_prod, np.multiply.outer, vectors) 33 | 34 | if __name__ == '__main__': 35 | run_local_tests() 36 | -------------------------------------------------------------------------------- /test/adverbs/test_par_each.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import each, testing_helpers 3 | 4 | def add1(xi): 5 | return xi + 1 6 | 7 | def add11d(x): 8 | return each(add1, x) 9 | 10 | int_vec = np.arange(128, dtype=np.float).reshape(16,8) 11 | 12 | def test_add1(): 13 | result = each(add11d, int_vec) 14 | expected = int_vec + 1 15 | assert testing_helpers.eq(result, expected), \ 16 | "Expected %s, got %s" % (expected, result) 17 | 18 | if __name__ == '__main__': 19 | testing_helpers.run_local_tests() 20 | -------------------------------------------------------------------------------- /test/adverbs/test_reduce.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet import testing_helpers 4 | 5 | int_vec = 300 + np.arange(300, dtype=int) 6 | float_vec = int_vec.astype(float) 7 | bool_vec = float_vec < np.mean(float_vec) 8 | 9 | a = np.arange(500, dtype=float).reshape(50,10) 10 | b = np.arange(100,600).reshape(50,10) 11 | 12 | def my_sum(xs): 13 | return parakeet.reduce(parakeet.add, xs, init=0) 14 | 15 | def test_int_sum(): 16 | testing_helpers.expect(my_sum, [int_vec], np.sum(int_vec)) 17 | 18 | def test_float_sum(): 19 | testing_helpers.expect(my_sum, [float_vec], np.sum(float_vec)) 20 | 21 | def test_bool_sum(): 22 | testing_helpers.expect(my_sum, [bool_vec], np.sum(bool_vec)) 23 | 24 | def sqr_dist(y, x): 25 | return sum((x-y)*(x-y)) 26 | 27 | def test_sqr_dist(): 28 | z = a[0] 29 | def run_sqr_dist(c): 30 | return sqr_dist(z, c) 31 | par_rslt = parakeet.each(run_sqr_dist, a) 32 | py_rslt = np.array(map(run_sqr_dist, a)) 33 | assert testing_helpers.eq(par_rslt, py_rslt), \ 34 | "Expected %s but got %s" % (py_rslt, par_rslt) 35 | 36 | def reduce_2d(Ys): 37 | init = parakeet.zeros_like(Ys[0]) 38 | return parakeet.reduce(parakeet.add, Ys, init = init, axis = 0) 39 | 40 | def test_2d_reduce(): 41 | par_rslt = reduce_2d(a) 42 | np_rslt = np.sum(a, 0) 43 | assert testing_helpers.eq(par_rslt, np_rslt), \ 44 | "Expected %s but got %s" % (np_rslt, par_rslt) 45 | 46 | def avg_along_axis_0(Xs): 47 | assign = np.array([0,0,1,0,1,0,1,0,1,1]) 48 | Ys = Xs[assign == 1] 49 | 50 | def zero(x): 51 | return 0.0 52 | zeros = parakeet.each(zero, Xs[0]) 53 | s = reduce(parakeet.add, Ys, init=zeros) 54 | def d(s): 55 | return s / Ys.shape[0] 56 | return parakeet.each(d, s) 57 | 58 | if __name__ == '__main__': 59 | testing_helpers.run_local_tests() 60 | -------------------------------------------------------------------------------- /test/adverbs/test_scan.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet import scan, add 4 | from parakeet.testing_helpers import run_local_tests, expect, expect_each 5 | 6 | int_1d = np.arange(5) 7 | float_1d = np.arange(5, dtype='float') 8 | int_2d = np.array([int_1d, int_1d, int_1d]) 9 | float_2d = np.array([float_1d, float_1d, float_1d]) 10 | 11 | def running_sum(x): 12 | return scan(add, x, init = 0) 13 | 14 | def test_scan_add_1d(): 15 | expect_each(running_sum, np.cumsum, [int_1d, float_1d]) 16 | 17 | def loop_row_sums(x): 18 | n_rows = x.shape[0] 19 | y = np.zeros_like(x) 20 | y[0, :] = x[0, :] 21 | for i in xrange(1,n_rows): 22 | y[i, :] = y[i-1, :] + x[i, :] 23 | return y 24 | """ 25 | def test_scan_add_2d(): 26 | expect_each(running_sum, loop_row_sums, [int_2d, float_2d]) 27 | """ 28 | if __name__ == '__main__': 29 | run_local_tests() 30 | -------------------------------------------------------------------------------- /test/algorithms/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/algorithms/__init__.py -------------------------------------------------------------------------------- /test/algorithms/test_2d_diff.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from parakeet.testing_helpers import expect_each, run_local_tests 4 | 5 | size = (5,5) 6 | float_mat = np.random.uniform(0,1,size=size) 7 | int_mat = np.random.random_integers(0,255,size=size) 8 | 9 | matrices = [float_mat, int_mat] 10 | 11 | def diff_x(I): 12 | m = I.shape[0] 13 | return (I[1:, :] - I[:m-1, :])[:, 1:] 14 | 15 | def test_diff_x(): 16 | expect_each(diff_x, diff_x, matrices) 17 | 18 | def diff_y(I): 19 | n = I.shape[1] 20 | return (I[:, 1:] - I[:, :n-1])[1:, :] 21 | 22 | def test_diff_y(): 23 | expect_each(diff_x, diff_x, matrices) 24 | 25 | if __name__ == "__main__": 26 | run_local_tests() 27 | -------------------------------------------------------------------------------- /test/algorithms/test_black_scholes.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit 2 | from parakeet.testing_helpers import eq, run_local_tests, expect 3 | 4 | from numpy import exp, log, sqrt 5 | 6 | 7 | def CND(x): 8 | a1 = 0.31938153 9 | a2 = -0.356563782 10 | a3 = 1.781477937 11 | a4 = -1.821255978 12 | a5 = 1.330274429 13 | L = abs(x) 14 | K = 1.0 / (1.0 + 0.2316419 * L) 15 | w = 1.0 - 1.0/sqrt(2*3.141592653589793)* exp(-1*L*L/2.) * (a1*K + 16 | a2*K*K + a3*K*K*K + a4*K*K*K*K + a5*K*K*K*K*K) 17 | if x<0: 18 | w = 1.0-w 19 | return w 20 | 21 | def black_scholes(CallFlag,S,X,T,r,v): 22 | d1 = ((r+v*v/2.)*T+log(S/X))/(v*sqrt(T)) 23 | d2 = d1-v*sqrt(T) 24 | z = exp(-1.0*r*T) * X 25 | if CallFlag: 26 | return S*CND(d1) - z*CND(d2) 27 | else: 28 | return z*CND(-1.0*d2) - S*CND(-1.0*d1) 29 | 30 | black_scholes_parakeet = jit(black_scholes) 31 | 32 | def test_black_scholes(): 33 | x1 = (False, 10.0, 10.0, 2.0, 2.0, 2.0) 34 | x2 = (True, 10.0, 10.0, 2.0, 2.0, 2.0) 35 | xs = [x1, x2] 36 | for x in xs: 37 | expect(black_scholes, x, black_scholes(*x)) 38 | 39 | if __name__ == '__main__': 40 | run_local_tests() 41 | -------------------------------------------------------------------------------- /test/algorithms/test_conv.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | # Simple convolution of 3x3 patches from a given array x 5 | # by a 3x3 array of filter weights 6 | 7 | def conv_3x3_trim(x, weights): 8 | return np.array([[(x[i-1:i+2, j-1:j+2]*weights).sum() 9 | for j in xrange(1, x.shape[1] -1)] 10 | for i in xrange(1, x.shape[0] -1)]) 11 | 12 | x = np.random.randn(4,4) 13 | w = np.random.randn(3,3) 14 | """ 15 | def test_conv_float32(): 16 | x_f32 = x.astype('float32') 17 | w_f32 = w.astype('float32') 18 | expect(conv_3x3_trim, [x_f32, w_f32], conv_3x3_trim(x_f32,w_f32)) 19 | 20 | def test_conv_int16(): 21 | x_i16 = x.astype('int16') 22 | w_i16 = w.astype('int16') 23 | expect(conv_3x3_trim, [x_i16, w_i16], conv_3x3_trim(x_i16,w_i16)) 24 | 25 | def test_conv_bool(): 26 | xb = x > 0 27 | wb = w > 0 28 | expect(conv_3x3_trim, [xb, wb], conv_3x3_trim(xb,wb)) 29 | """ 30 | def conv_3x3_trim_loops(image, weights): 31 | result = np.zeros_like(image[1:-1, 1:-1]) 32 | m,n = image.shape 33 | for i in xrange(1,m-1): 34 | for j in xrange(1,n-1): 35 | for ii in xrange(3): 36 | for jj in xrange(3): 37 | result[i-1,j-1] += image[i-ii+1, j-jj+1] * weights[ii, jj] 38 | return result 39 | 40 | def test_conv_loops_float32(): 41 | x_f32 = x.astype('float32') 42 | w_f32 = w.astype('float32') 43 | 44 | expect(conv_3x3_trim_loops, [x_f32, w_f32], conv_3x3_trim_loops(x_f32,w_f32)) 45 | 46 | def test_conv_loops_int16(): 47 | x_i16 = x.astype('int16') 48 | w_i16 = w.astype('int16') 49 | expect(conv_3x3_trim_loops, [x_i16, w_i16], conv_3x3_trim_loops(x_i16,w_i16)) 50 | 51 | def test_conv_loops_bool(): 52 | xb = x > 0 53 | wb = w > 0 54 | expect(conv_3x3_trim_loops, [xb, wb], conv_3x3_trim_loops(xb,wb)) 55 | 56 | if __name__ == "__main__": 57 | run_local_tests() 58 | -------------------------------------------------------------------------------- /test/algorithms/test_diffuse.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import testing_helpers 3 | 4 | 5 | 6 | 7 | mu = 0.1 8 | Lx, Ly = 7, 7 9 | 10 | def diffuse_loops(iter_num): 11 | u = np.zeros((Lx, Ly), dtype=np.float64) 12 | temp_u = np.zeros_like(u) 13 | temp_u[Lx / 2, Ly / 2] = 1000.0 14 | for _ in range(iter_num): 15 | for i in range(1, Lx - 1): 16 | for j in range(1, Ly - 1): 17 | u[i, j] = mu * (temp_u[i + 1, j] + temp_u[i - 1, j] + 18 | temp_u[i, j + 1] + temp_u[i, j - 1] - 19 | 4 * temp_u[i, j]) 20 | temp = u 21 | u = temp_u 22 | temp_u = temp 23 | return u 24 | 25 | def test_diffuse_loops(): 26 | testing_helpers.expect(diffuse_loops, [3], diffuse_loops(3)) 27 | 28 | 29 | def diffuse_array_expressions(iter_num): 30 | u = np.zeros((Lx, Ly), dtype=np.float64) 31 | temp_u = np.zeros_like(u) 32 | temp_u[Lx / 2, Ly / 2] = 1000.0 33 | 34 | for _ in range(iter_num): 35 | u[1:-1, 1:-1] = mu * (temp_u[2:, 1:-1] + temp_u[:-2, 1:-1] + 36 | temp_u[1:-1, 2:] + temp_u[1:-1, :-2] - 37 | 4 * temp_u[1:-1, 1:-1]) 38 | temp = u 39 | u = temp_u 40 | temp_u = temp 41 | return u 42 | 43 | def test_diffuse_array_expressions(): 44 | testing_helpers.expect(diffuse_array_expressions, [2], diffuse_array_expressions(2)) 45 | 46 | if __name__ == "__main__": 47 | testing_helpers.run_local_tests() 48 | 49 | -------------------------------------------------------------------------------- /test/algorithms/test_dist.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import time 3 | 4 | import parakeet 5 | from parakeet import testing_helpers 6 | 7 | def sqr_dist(x,y): 8 | return sum( (x-y) ** 2) 9 | 10 | def allpairs_dist_adverb(X,Y): 11 | return parakeet.allpairs(sqr_dist, X, Y) 12 | 13 | def allpairs_dist_comprehensions_external(X,Y): 14 | return np.array([[sqr_dist(x,y) for y in Y] for x in X]) 15 | 16 | def allpairs_dist_comprehensions_internal(X,Y): 17 | def local_sqr_dist(x,y): 18 | return np.sum( (x-y)**2 ) 19 | return np.array([[local_sqr_dist(x,y) for y in Y] for x in X]) 20 | 21 | m = 2 22 | n = 3 23 | d = 5 24 | X = np.random.randn(m,d) 25 | Y = np.random.randn(n,d) 26 | python_dists = np.array([[sqr_dist(x,y) for y in Y] for x in X]) 27 | 28 | def test_dists_adverb(): 29 | testing_helpers.expect(allpairs_dist_adverb, [X,Y], python_dists) 30 | 31 | def test_dists_comprehensions_external(): 32 | testing_helpers.expect(allpairs_dist_comprehensions_external, [X,Y], python_dists) 33 | 34 | def test_dists_comprehensions_internal(): 35 | testing_helpers.expect(allpairs_dist_comprehensions_external, [X,Y], python_dists) 36 | 37 | if __name__ == '__main__': 38 | testing_helpers.run_local_tests() 39 | -------------------------------------------------------------------------------- /test/algorithms/test_dot.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect_allpairs, run_local_tests 3 | 4 | bool_vec = np.array([True, False, True, ]) 5 | int_vec = np.array([1,2,3,]) 6 | float_vec = np.array([10.0, 20.0, 30.0 ]) 7 | 8 | vectors = [bool_vec, int_vec, float_vec] 9 | 10 | def loop_dot(x,y): 11 | n = x.shape[0] 12 | result = x[0] * y[0] 13 | i = 1 14 | while i < n: 15 | result += x[i] * y[i] 16 | i = i + 1 17 | return result 18 | 19 | def test_loopdot(): 20 | expect_allpairs(loop_dot, np.dot, vectors) 21 | 22 | def dot(x,y): 23 | return sum(x*y) 24 | 25 | def test_adverb_dot(): 26 | expect_allpairs(dot, lambda x,y: np.sum(x*y), vectors) 27 | 28 | if __name__ == '__main__': 29 | run_local_tests() 30 | -------------------------------------------------------------------------------- /test/algorithms/test_find_border.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet.testing_helpers import expect, run_local_tests 4 | 5 | parakeet.config.print_untyped_function = True 6 | parakeet.config.print_specialized_function = True 7 | 8 | def find_border(is_background): 9 | h, w = is_background.shape[:2] 10 | 11 | top, left, right, bottom = (-1, -1, -1, -1) 12 | # find top 13 | for i in range(h): 14 | if is_background[i, :].sum() != w and top == -1: 15 | top = i 16 | 17 | for i in range(h - 1, 0, -1): 18 | if is_background[i, :].sum() != w and bottom == -1: 19 | bottom = i 20 | 21 | for i in range(w): 22 | if is_background[:, i].sum() != h and left == -1: 23 | left = i 24 | 25 | for i in range(w - 1, 0, -1): 26 | if is_background[:, i].sum() != h and right == -1: 27 | right = i 28 | 29 | return top, left, right, bottom 30 | 31 | def test_find_border(): 32 | is_background = np.empty((20, 20), dtype=np.bool) 33 | expect(find_border, [is_background], find_border(is_background)) 34 | 35 | 36 | if __name__ == '__main__': 37 | run_local_tests() 38 | -------------------------------------------------------------------------------- /test/algorithms/test_growcut.py: -------------------------------------------------------------------------------- 1 | 2 | # Authors: Nathan Faggian, Stefan van der Walt, Aron Ahmadia, Olivier Grisel 3 | # https://github.com/stefanv/growcut_py 4 | 5 | import numpy as np 6 | 7 | def growcut_python(image, state, state_next, window_radius): 8 | changes = 0 9 | height = image.shape[0] 10 | width = image.shape[1] 11 | for j in xrange(width): 12 | for i in xrange(height): 13 | winning_colony = state[i, j, 0] 14 | defense_strength = state[i, j, 1] 15 | for jj in xrange(max(j-window_radius,0), min(j+window_radius+1, width)): 16 | for ii in xrange(max(i-window_radius, 0), min(i+window_radius+1, height)): 17 | if ii != i or jj != j: 18 | d = image[i, j, :] - image[ii, jj, :] 19 | s = np.sum(d**2) 20 | gval = 1.0 - np.sqrt(s) / np.sqrt(3) 21 | attack_strength = gval * state[ii, jj, 1] 22 | if attack_strength > defense_strength: 23 | defense_strength = attack_strength 24 | winning_colony = state[ii, jj, 0] 25 | changes += 1 26 | state_next[i, j, 0] = winning_colony 27 | state_next[i, j, 1] = defense_strength 28 | return changes 29 | 30 | from parakeet.testing_helpers import expect, run_local_tests 31 | 32 | def run_growcut(N = 3, window_radius = 2): 33 | image = np.zeros((N, N, 3), dtype=np.double) 34 | state = np.zeros((N, N, 2), dtype=np.double) 35 | state_next = np.empty_like(state) 36 | 37 | # colony 1 is strength 1 at position 0,0 38 | # colony 0 is strength 0 at all other positions 39 | state[0, 0, 0] = 1 40 | state[0, 0, 1] = 1 41 | growcut_python(image, state, state_next, window_radius) 42 | return state_next 43 | 44 | def test_growcut(): 45 | res = run_growcut() 46 | expect(run_growcut, [], res) 47 | 48 | 49 | if __name__ == "__main__": 50 | run_local_tests() 51 | -------------------------------------------------------------------------------- /test/algorithms/test_harris_corner.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import time 3 | 4 | import parakeet 5 | from parakeet.testing_helpers import expect_each, run_local_tests 6 | 7 | 8 | size = (5,5) 9 | float_mat = np.random.uniform(0,1,size=size) 10 | int_mat = np.random.random_integers(0,255,size=size) 11 | 12 | matrices = [float_mat, int_mat] 13 | 14 | def harris(I): 15 | m,n = I.shape 16 | dx = (I[1:, :] - I[:m-1, :])[:, 1:] 17 | dy = (I[:, 1:] - I[:, :n-1])[1:, :] 18 | # 19 | # At each point we build a matrix 20 | # of derivative products 21 | # M = 22 | # | A = dx^2 C = dx * dy | 23 | # | C = dy * dx B = dy * dy | 24 | # 25 | # and the score at that point is: 26 | # det(M) - k*trace(M)^2 27 | # 28 | A = dx * dx 29 | B = dy * dy 30 | C = dx * dy 31 | tr = A + B 32 | det = A * B - C * C 33 | k = 0.05 34 | return det - k * tr * tr 35 | 36 | 37 | def test_harris(): 38 | expect_each(harris, harris, matrices) 39 | 40 | 41 | 42 | if __name__ == '__main__': 43 | run_local_tests() 44 | -------------------------------------------------------------------------------- /test/algorithms/test_histogram_intersection.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit, testing_helpers 2 | import numpy as np 3 | 4 | 5 | 6 | def kernel(X): 7 | return np.array([[np.sum(np.minimum(x,y)) for y in X] for x in X]) 8 | 9 | def test_histogram_intersection_kernel(): 10 | n,d = 3,4 11 | X = np.arange(n*d).reshape((n,d)) 12 | K = kernel(X) 13 | testing_helpers.expect(kernel, [X], K) 14 | 15 | if __name__ == "__main__": 16 | testing_helpers.run_local_tests 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/algorithms/test_hyst.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test for Issue #18: https://github.com/iskandr/parakeet/issues/18 3 | # 4 | import numpy as np 5 | from parakeet import jit 6 | from parakeet.testing_helpers import expect, run_local_tests 7 | 8 | def hyst_(mag, edge_map, labels, num_labels, high_thresh): 9 | for i in range(num_labels): 10 | if np.max(mag[labels == i]) < high_thresh: 11 | edge_map[labels == i] = False 12 | return edge_map 13 | 14 | def hyst(n): 15 | mag = np.arange(n) 16 | labels = np.ones(n) 17 | labels[int(n/2)] = 0 18 | edge_map = np.ones(n, dtype=np.bool) 19 | num_labels = 2 20 | high_thresh = int(n/2) 21 | return hyst_(mag, edge_map, labels, num_labels, high_thresh) 22 | 23 | """ 24 | TODO: implement boolean indexing 25 | def test_hyst(): 26 | expect(hyst, [10], hyst(10)) 27 | """ 28 | if __name__ == '__main__': 29 | run_local_tests() 30 | 31 | -------------------------------------------------------------------------------- /test/algorithms/test_is_prime.py: -------------------------------------------------------------------------------- 1 | 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | 5 | def is_prime(n): 6 | for i in xrange(2,n-1): 7 | if n % i == 0: 8 | return False 9 | return True 10 | 11 | def test_is_prime(): 12 | expect(is_prime, [2], True) 13 | expect(is_prime, [3], True) 14 | expect(is_prime, [4], False) 15 | expect(is_prime, [5], True) 16 | expect(is_prime, [6], False) 17 | 18 | if __name__ == '__main__': 19 | run_local_tests() 20 | -------------------------------------------------------------------------------- /test/algorithms/test_julia.py: -------------------------------------------------------------------------------- 1 | """ 2 | Authors: Kurt W. Smith, Serge Guelton 3 | License: MIT 4 | Source: https://github.com/numfocus/python-benchmarks/blob/master/julia/julia_python.py 5 | """ 6 | 7 | import numpy as np 8 | from parakeet import testing_helpers 9 | 10 | def kernel(zr, zi, cr, ci, lim, cutoff): 11 | ''' Computes the number of iterations `n` such that 12 | |z_n| > `lim`, where `z_n = z_{n-1}**2 + c`. 13 | ''' 14 | count = 0 15 | while ((zr*zr + zi*zi) < (lim*lim)) and count < cutoff: 16 | zr, zi = zr * zr - zi * zi + cr, 2 * zr * zi + ci 17 | count += 1 18 | return count 19 | 20 | def julia_loops(cr, ci, N, bound=1.5, lim=1000., cutoff=1e6): 21 | ''' Pure Python calculation of the Julia set for a given `c`. No NumPy 22 | array operations are used. 23 | ''' 24 | julia = np.empty((N, N), dtype=np.uint32) 25 | grid_x = np.linspace(-bound, bound, N) 26 | for i, x in enumerate(grid_x): 27 | for j, y in enumerate(grid_x): 28 | julia[i,j] = kernel(x, y, cr, ci, lim, cutoff=cutoff) 29 | return julia 30 | 31 | def test_julia(): 32 | cr=0.285 33 | ci=0.01 34 | N=10 35 | testing_helpers.expect(julia_loops, [cr, ci, N], julia_loops(cr,ci,N)) 36 | 37 | 38 | if __name__ == "__main__": 39 | testing_helpers.run_local_tests() 40 | -------------------------------------------------------------------------------- /test/algorithms/test_local_maxima.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | import parakeet.c_backend 4 | 5 | from parakeet.testing_helpers import run_local_tests, expect 6 | def wrap(pos, offset, bound): 7 | return ( pos + offset ) % bound 8 | 9 | def clamp(pos, offset, bound): 10 | return min(bound-1,max(0,pos+offset)) 11 | 12 | def reflect(pos, offset, bound): 13 | idx = pos+offset 14 | return min(2*(bound-1)-idx,max(idx,-idx)) 15 | 16 | 17 | def python_local_maxima(data, wsize, mode=wrap): 18 | result = np.ones(shape=data.shape,dtype='bool') 19 | for pos in np.ndindex(data.shape): 20 | myval = data[pos] 21 | for offset in np.ndindex(wsize): 22 | neighbor_idx = tuple(mode(p, o-w/2, w) for (p, o, w) in zip(pos, offset, wsize)) 23 | result[pos] &= (data[neighbor_idx] <= myval) 24 | return result 25 | 26 | @parakeet.jit 27 | def local_maxima(data, wsize, mode=wrap): 28 | def is_max(pos): 29 | def is_smaller_neighbor(offset): 30 | neighbor_idx = tuple(mode(p, o-w/2, w) for (p, o, w) in zip(pos, offset, wsize)) 31 | return data[neighbor_idx] <= data[pos] 32 | return np.all(parakeet.imap(is_smaller_neighbor, wsize)) 33 | return parakeet.imap(is_max, data.shape) 34 | 35 | 36 | shape = (4,3,3,3) 37 | x = np.random.randn(*shape) 38 | wsize = (3,3,3,3) 39 | 40 | def test_local_maxima(): 41 | expect(local_maxima, [x, wsize], python_local_maxima(x, wsize)) 42 | 43 | 44 | 45 | if __name__ == '__main__': 46 | run_local_tests() 47 | 48 | -------------------------------------------------------------------------------- /test/algorithms/test_matmult_allpairs.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet import jit, allpairs 4 | from parakeet.testing_helpers import run_local_tests, expect 5 | 6 | int_mat = np.reshape(np.arange(6), (2,3)) 7 | float_mat = np.sqrt(int_mat) 8 | bool_mat = int_mat % 2 9 | 10 | matrices = [int_mat, float_mat, bool_mat] 11 | 12 | @jit 13 | def dot(x,y): 14 | return sum(x*y) 15 | 16 | @jit 17 | def matmult_allpairs(X,Y): 18 | return allpairs(dot, X, Y, axis = (0,1)) 19 | 20 | def test_matmult_allpairs(): 21 | for X in matrices: 22 | for Y in matrices: 23 | res = np.dot(X, Y.T) 24 | expect(matmult_allpairs, [X,Y.T], res) 25 | 26 | 27 | if __name__ == "__main__": 28 | run_local_tests() 29 | -------------------------------------------------------------------------------- /test/algorithms/test_matmult_comprehensions.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet import jit 4 | from parakeet.testing_helpers import run_local_tests, expect 5 | 6 | int64_mat = np.reshape(np.arange(6), (2,3)).astype('int64') 7 | int32_mat = int64_mat.astype('int32') 8 | 9 | float64_mat = int64_mat.astype('float64') 10 | float32_mat = int64_mat.astype('float32') 11 | bool_mat = int64_mat % 2 12 | 13 | matrices = [int64_mat, int32_mat, float64_mat, float32_mat, bool_mat] 14 | 15 | def matmult_comprehensions(X,Y): 16 | return np.array([[np.dot(x,y) for y in Y.T] for x in X]) 17 | 18 | def test_matmult_int64_int32(): 19 | expect(matmult_comprehensions, [int64_mat, int32_mat.T], np.dot(int64_mat, int32_mat.T)) 20 | 21 | def test_matmult_int32_int32(): 22 | expect(matmult_comprehensions, [int32_mat, int32_mat.T], np.dot(int32_mat, int32_mat.T)) 23 | 24 | def test_matmult_float64_float32(): 25 | expect(matmult_comprehensions, [float64_mat, float32_mat.T], np.dot(float64_mat, float32_mat.T)) 26 | 27 | def test_matmult_float32_float32(): 28 | expect(matmult_comprehensions, [float32_mat, float32_mat.T], np.dot(float32_mat, float32_mat.T)) 29 | 30 | def test_matmult_float32_int32(): 31 | expect(matmult_comprehensions, [float32_mat, int32_mat.T], np.dot(float32_mat, int32_mat.T)) 32 | 33 | def test_matmult_float64_bool(): 34 | expect(matmult_comprehensions, [float64_mat, bool_mat.T], np.dot(float64_mat, bool_mat.T)) 35 | 36 | def test_matmult_bool_bool(): 37 | expect(matmult_comprehensions, [bool_mat, bool_mat.T], np.dot(bool_mat, bool_mat.T)) 38 | 39 | def test_matmult_bool_int32(): 40 | expect(matmult_comprehensions, [bool_mat, int32_mat.T], np.dot(bool_mat, int32_mat.T)) 41 | 42 | if __name__ == "__main__": 43 | run_local_tests() 44 | -------------------------------------------------------------------------------- /test/algorithms/test_matmult_loops.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet import jit 4 | from parakeet.testing_helpers import run_local_tests, expect 5 | 6 | int_mat = np.reshape(np.arange(6), (2,3)) 7 | float_mat = np.sqrt(int_mat) 8 | bool_mat = int_mat % 2 9 | 10 | matrices = [int_mat, float_mat, bool_mat] 11 | 12 | @jit 13 | def mm_loops(X,Y,Z): 14 | m,d = X.shape 15 | n = Y.shape[1] 16 | 17 | for i in range(m): 18 | for j in range(n): 19 | total = 0 20 | for k in range(d): 21 | total += X[i,k] * Y[k,j] 22 | Z[i,j] = total 23 | return Z 24 | 25 | def test_matmult_loops(): 26 | for X in matrices: 27 | for Y in matrices: 28 | res = np.dot(X, Y.T) 29 | Z = np.zeros(res.shape, dtype = res.dtype) 30 | expect(mm_loops, [X,Y.T,Z], res) 31 | 32 | if __name__ == "__main__": 33 | run_local_tests() -------------------------------------------------------------------------------- /test/algorithms/test_matmult_tropical.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | import parakeet.testing_helpers 3 | import numpy as np 4 | 5 | 6 | def matmult_high_level(X,Y): 7 | return np.array([[np.min(x+y) for y in Y.T] for x in X]) 8 | 9 | def test_matmult_tropical(): 10 | n, d = 4,5 11 | m = 3 12 | X = np.random.randn(m,d) 13 | Y = np.random.randn(d,n) 14 | parakeet.testing_helpers.expect(matmult_high_level, [X,Y], matmult_high_level(X,Y)) 15 | 16 | if __name__ == '__main__': 17 | parakeet.testing_helpers.run_local_tests() 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/algorithms/test_maxpool.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import parakeet 4 | from parakeet import jit, testing_helpers 5 | 6 | @jit 7 | def maxpool(array, pool_size): 8 | n, w, h = array.shape 9 | def _inner(args): 10 | img, x, y = args 11 | max_val = -1e12 12 | for i in xrange(0, pool_size): 13 | for j in xrange(0, pool_size): 14 | if x + i < w and y + j < h: 15 | max_val = max(array[img, x + i, y + j]) 16 | return max_val 17 | return parakeet.imap(_inner, (n, w, h)) 18 | 19 | def test_maxpool(): 20 | x = np.array([[1,2,3], 21 | [4,5,6], 22 | [7,8,9]]) 23 | xs = np.array([x,x]) 24 | expected_single = np.array([[5, 6, 6], 25 | [8, 9, 9], 26 | [8, 9, 9]]) 27 | expected = np.array([expected_single, expected_single]) 28 | testing_helpers.expect(maxpool, [xs, 2], expected) 29 | 30 | if __name__ == "__main__": 31 | testing_helpers.run_local_tests() 32 | -------------------------------------------------------------------------------- /test/algorithms/test_nn_simple.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit, testing_helpers 2 | import numpy as np 3 | 4 | def init_layer(input_size, n_elts): 5 | return np.random.randn(n_elts, input_size) 6 | 7 | def create_mlp(n_inputs, n_hidden, n_outputs): 8 | W1 = init_layer(n_inputs, n_hidden) 9 | W2 = init_layer(n_hidden, n_outputs) 10 | return (W1, W2) 11 | 12 | def dot(x,y): 13 | return sum(x*y) 14 | 15 | def fprop_elt(x,w): 16 | return np.tanh(dot(x,w)) 17 | 18 | def fprop_layer(layer, x): 19 | return [fprop_elt(x,w) for w in layer] 20 | 21 | fprop_layer_parakeet = jit(fprop_layer) 22 | 23 | def fprop(network, x): 24 | for layer in network: 25 | x = fprop_layer_parakeet(layer, x) 26 | return x 27 | 28 | def fprop_python(network, x): 29 | for layer in network: 30 | x = np.array(fprop_layer(layer,x)) 31 | return x 32 | 33 | n = 1000 34 | d = 500 35 | Xpos = np.random.randn(n,d)+1.0 36 | Xneg = np.random.randn(n,d)-1.0 37 | X = np.vstack([Xpos, Xneg]) 38 | Y = np.vstack([np.ones(n), np.ones(n)*-1]) 39 | 40 | network = create_mlp(d,50,1) 41 | 42 | def test_fprop(): 43 | parakeet_result = fprop(network, X[0]) 44 | print "Parakeet result", parakeet_result 45 | python_result = fprop_python(network, X[0]) 46 | print "Python result", python_result 47 | assert testing_helpers.eq(parakeet_result, python_result) 48 | 49 | if __name__ == '__main__': 50 | testing_helpers.run_local_tests() 51 | -------------------------------------------------------------------------------- /test/algorithms/test_norm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Example taken from Numba discussion list 3 | https://groups.google.com/a/continuum.io/forum/#!topic/numba-users/pCpNGdtKlRc 4 | """ 5 | 6 | import math 7 | import numpy as np 8 | from parakeet import testing_helpers 9 | 10 | def norm(vec): 11 | """ Calculate the norm of a 3d vector. """ 12 | return math.sqrt(vec[0]**2 + vec[1]**2 + vec[2]**2) 13 | 14 | def normalize(vec): 15 | """ Calculate the normalized vector (norm: one). """ 16 | return vec / norm(vec) 17 | 18 | 19 | def test_normalize(): 20 | v = np.array((1.0, 2.0, 3.0)) 21 | testing_helpers.expect(normalize, [v], normalize(v)) 22 | 23 | if __name__ == "__main__": 24 | testing_helpers.run_local_tests() 25 | 26 | -------------------------------------------------------------------------------- /test/algorithms/test_partialDU.py: -------------------------------------------------------------------------------- 1 | def gradients(d, re, preDz, preWz, SRW, RSW, yxV, xyU, resid): 2 | """ computes the linear algebra intensive part of the gradients of the grae 3 | """ 4 | fprime = lambda x: 1 - power(tanh(x), 2) 5 | 6 | partialDU = zeros((d+1, re, 2*d, d)) 7 | for k in range(2*d): 8 | for i in range(d): 9 | partialDU[:,:,k,i] = fprime(preDz[k]) * fprime(preWz[i]) * (SRW[i,k] + RSW[i,k]) * yxV[:,:,i] 10 | 11 | return partialDU 12 | 13 | def test_gradients(): 14 | pass 15 | -------------------------------------------------------------------------------- /test/algorithms/test_rad2deg.py: -------------------------------------------------------------------------------- 1 | 2 | from parakeet.testing_helpers import run_local_tests, expect, expect_eq 3 | 4 | def rad2deg(rad): 5 | return (rad * 180) / 3.14159265359 6 | 7 | import numpy as np 8 | 9 | def test_rad2deg_int32(): 10 | rads = np.array([0,1]).astype('int32') 11 | degs = rad2deg(rads) 12 | expected = np.rad2deg(rads) 13 | expect_eq(degs, expected) 14 | 15 | def test_rad2deg_bool(): 16 | rads = np.array([False,True]) 17 | degs = rad2deg(rads) 18 | expected = np.rad2deg(rads) 19 | expect_eq(degs, expected) 20 | 21 | def test_rad2deg_float32(): 22 | rads = np.array([0.1, 0.2]).astype('float32') 23 | degs = rad2deg(rads) 24 | expected = np.rad2deg(rads) 25 | expect_eq(degs, expected) 26 | 27 | 28 | def test_rad2deg_float64(): 29 | rads = np.array([0.1, 0.2]).astype('float64') 30 | degs = rad2deg(rads) 31 | expected = np.rad2deg(rads) 32 | expect_eq(degs, expected) 33 | 34 | if __name__ == '__main__': 35 | run_local_tests() 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test/algorithms/test_rotate.py: -------------------------------------------------------------------------------- 1 | from numpy import sin, cos, dot, array 2 | 3 | 4 | def rotate(phi, theta, orig): 5 | """ 6 | This function rotates the point at orig about axis u(depends on phi) by the angle theta. 7 | orig and output are in Cartesian coordinates 8 | """ 9 | 10 | u = (-sin(phi), cos(phi), 0.0) 11 | rotM = array([ 12 | [cos(theta)+u[0]**2*(1-cos(theta)), u[0]*u[1]*(1-cos(theta)), u[1]*sin(theta)], 13 | [u[0]*u[1]*(1-cos(theta)), cos(theta)+u[1]**2*(1-cos(theta)), -u[0]*sin(theta)], 14 | [-u[1]*sin(theta), u[0]*sin(theta), cos(theta)] 15 | ]) 16 | rotP = dot(rotM,orig) 17 | return rotP 18 | 19 | 20 | from parakeet import testing_helpers 21 | import numpy as np 22 | 23 | def test_rotate(): 24 | x = np.arange(3) / 2.0 25 | for phi in (0, 0.25): 26 | for theta in (0, 0.25): 27 | testing_helpers.expect(rotate, [phi, theta, x], rotate(phi, theta, x)) 28 | 29 | if __name__ == "__main__": 30 | testing_helpers.run_local_tests() 31 | -------------------------------------------------------------------------------- /test/algorithms/test_rule_30.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | 4 | from parakeet.testing_helpers import eq, run_local_tests 5 | 6 | size = 21 7 | init = np.array(([0] * (size/2)) + [1] + ([0] * (size - size/2 - 1))) 8 | 9 | def rule30(extended, i): 10 | a = extended[i-1] 11 | b = extended[i] 12 | c = extended[i+1] 13 | 14 | if ((a == 1 and b == 0 and c == 0) or 15 | (a == 0 and b == 1 and c == 1) or 16 | (a == 0 and b == 1 and c == 0) or 17 | (a == 0 and b == 0 and c == 1)): 18 | return 1 19 | else: 20 | return 0 21 | 22 | 23 | def test_rule30(): 24 | output = init.copy() 25 | cur = init 26 | zero_array = np.array([0]) 27 | indices = np.arange(1,size+1) 28 | for _ in range(size/2): 29 | extended = np.concatenate((zero_array, cur, zero_array)) 30 | 31 | def run_rule30(i): 32 | return rule30(extended, i) 33 | parakeet_iter = parakeet.map(run_rule30, indices) 34 | cur = np.array(map(run_rule30, indices)) 35 | assert eq(parakeet_iter, cur), \ 36 | "Parakeet result (%s) didn't match Python result(%s)" % \ 37 | (parakeet_iter, cur) 38 | output = np.vstack((output,cur)) 39 | 40 | 41 | if __name__ == '__main__': 42 | run_local_tests() 43 | -------------------------------------------------------------------------------- /test/algorithms/test_simple_regression.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | 4 | def covariance(x,y): 5 | return ((x-x.mean()) * (y-y.mean())).mean() 6 | 7 | def fit_simple_regression(x,y): 8 | slope = covariance(x,y) / covariance(x,x) 9 | offset = y.mean() - slope * x.mean() 10 | return slope, offset 11 | 12 | import numpy as np 13 | 14 | def test_simple_regression(): 15 | N = 10 16 | x = np.random.randn(N).astype('float64') 17 | slope = 903.29 18 | offset = 102.1 19 | y = slope * x + offset 20 | expect(fit_simple_regression, [x,y], (slope,offset)) 21 | 22 | 23 | if __name__ == '__main__': 24 | run_local_tests() 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/algorithms/test_sph_kernel.py: -------------------------------------------------------------------------------- 1 | """ 2 | Kernel from SPH renderer, modified from Numba version at: 3 | https://gist.github.com/rokroskar/bdcf6c6b210ff0efc738#file-gistfile1-txt-L55 4 | """ 5 | 6 | 7 | import numpy as np 8 | from parakeet import testing_helpers, config 9 | 10 | 11 | def kernel_func(d, h) : 12 | if d < 1 : 13 | f = 1.-(3./2)*d**2 + (3./4.)*d**3 14 | elif d<2 : 15 | f = 0.25*(2.-d)**3 16 | else : 17 | f = 0 18 | return f/(np.pi*h**3) 19 | 20 | 21 | def compute_kernel( start = 0, stop = 2.01, step = 0.01, h = 1.0): 22 | # set up the kernel values 23 | kernel_samples = np.arange(start, stop, step) 24 | return np.array([kernel_func(x, h) for x in kernel_samples]) 25 | 26 | 27 | print compute_kernel(0, 0.1, 0.05) 28 | 29 | def test_kernel(): 30 | testing_helpers.expect(compute_kernel, [0, 0.5], compute_kernel(0,0.5)) 31 | 32 | if __name__ == "__main__": 33 | testing_helpers.run_local_tests() 34 | -------------------------------------------------------------------------------- /test/algorithms/test_sum_primes.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def sum_primes(n): 4 | total = 0 5 | count = 0 6 | for i in xrange(2, n): 7 | found_divisor = False 8 | for j in xrange(2,i-1): 9 | if i % j == 0: 10 | found_divisor = True 11 | if not found_divisor: 12 | total += i 13 | count += 1 14 | return total, count 15 | 16 | def test_sum_primes(): 17 | expect(sum_primes, [20], sum_primes(20)) 18 | 19 | if __name__ == '__main__': 20 | run_local_tests() 21 | -------------------------------------------------------------------------------- /test/algorithms/test_tanh_rescale.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit, testing_helpers 3 | 4 | 5 | alpha = 0.5 6 | beta = 0.3 7 | x = np.array([1,2,3]) 8 | y = np.tanh(x) * alpha + beta 9 | 10 | @jit 11 | def numpy_expressions(x, alpha = 0.5, beta = 0.3): 12 | return np.tanh(x) * alpha + beta 13 | 14 | def test_numpy_expressions(): 15 | res = numpy_expressions(x) 16 | assert np.allclose(res, y), "Expected %s but got %s" % (y, res) 17 | 18 | @jit 19 | def loopy(x, alpha = 0.5, beta = 0.3): 20 | y = np.empty_like(x, dtype=float) 21 | for i in xrange(len(x)): 22 | y[i] = np.tanh(x[i]) * alpha + beta 23 | return y 24 | 25 | def test_loopy(): 26 | res = loopy(x) 27 | assert np.allclose(res, y), "Expected %s but got %s" % (y, res) 28 | 29 | @jit 30 | def comprehension(x, alpha = 0.5, beta = 0.3): 31 | return np.array([np.tanh(xi)*alpha + beta for xi in x]) 32 | 33 | def test_comprehensions(): 34 | res = comprehension(x) 35 | assert np.allclose(res, y), "Expected %s but got %s" % (y, res) 36 | 37 | if __name__ == "__main__": 38 | testing_helpers.run_local_tests() 39 | 40 | -------------------------------------------------------------------------------- /test/algorithms/test_thresholds.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import time 3 | 4 | 5 | import parakeet 6 | from parakeet import testing_helpers 7 | 8 | def count_thresh_orig(values, thresh): 9 | n = 0 10 | for elt in values: 11 | n += elt < thresh 12 | return n 13 | 14 | count_thresh = parakeet.jit(count_thresh_orig) 15 | 16 | def np_thresh(values, thresh): 17 | return np.sum(values < thresh) 18 | 19 | def par_thresh(values, thresh): 20 | return parakeet.sum(values < thresh) 21 | 22 | def test_count_thresh(): 23 | v = np.array([1.2, 1.4, 5.0, 2, 3]) 24 | parakeet_result = count_thresh(v, 2.0) 25 | python_result = count_thresh_orig(v,2.0) 26 | testing_helpers.expect(count_thresh, [v, 2.0], count_thresh_orig(v, 2.0)) 27 | 28 | 29 | if __name__ == '__main__': 30 | testing_helpers.run_local_tests() 31 | -------------------------------------------------------------------------------- /test/arrays/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/arrays/__init__.py -------------------------------------------------------------------------------- /test/arrays/test_arange.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | from parakeet import jit, config 5 | from parakeet.testing_helpers import expect, run_local_tests 6 | 7 | 8 | 9 | @jit 10 | def arange1(a): 11 | return np.arange(a) 12 | 13 | @jit 14 | def arange2(a,b): 15 | return np.arange(a,b) 16 | 17 | @jit 18 | def arange3(a,b,c): 19 | return np.arange(a,b,c) 20 | 21 | def test_range1_int(): 22 | a = 5 23 | expect(arange1, [a], np.arange(a)) 24 | 25 | def test_range1_float(): 26 | a = 3.5 27 | expect(arange1, [a], np.arange(a)) 28 | 29 | def test_range2_int(): 30 | a = 2 31 | b = 6 32 | expect(arange2, [a,b], np.arange(a,b)) 33 | 34 | def test_range2_float(): 35 | a = 3.5 36 | b = 7.1 37 | expect(arange2, [a,b], np.arange(a,b)) 38 | 39 | def test_range3_int(): 40 | a = 2 41 | b = 10 42 | c = 3 43 | expect(arange3, [a,b,c], np.arange(a,b,c)) 44 | 45 | def test_range3_float(): 46 | a = 3.5 47 | b = 9.1 48 | c = 1.7 49 | expect(arange3, [a,b,c], np.arange(a,b,c)) 50 | 51 | def test_range3_int_reverse(): 52 | a = 10 53 | b = 2 54 | c = -3 55 | expect(arange3, [a,b,c], np.arange(a,b,c)) 56 | 57 | def test_range3_float_reverse(): 58 | a = 9.1 59 | b = 3.5 60 | c = -1.7 61 | expect(arange3, [a,b,c], np.arange(a,b,c)) 62 | 63 | 64 | 65 | if __name__ == '__main__': 66 | run_local_tests() 67 | -------------------------------------------------------------------------------- /test/arrays/test_array_literal.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet.testing_helpers import expect, run_local_tests 4 | 5 | def create_const(x): 6 | return [x,x,x,x] 7 | 8 | def test_create_const(): 9 | expect(create_const, [1], np.array([1,1,1,1])) 10 | expect(create_const, [1.0], np.array([1.0, 1.0, 1.0, 1.0])) 11 | expect(create_const, [True], np.array([True, True, True, True])) 12 | 13 | 14 | def test_nested_2d(): 15 | expect(create_const, [np.array([1,2])] , np.array([[1,2],[1,2],[1,2],[1,2]])) 16 | expect(create_const, [np.array([1.0,2.0])] , np.array([[1.0,2.0],[1.0,2.0],[1.0,2.0],[1.0,2.0]])) 17 | expect(create_const, [np.array([True,False])] , 18 | np.array([[True,False],[True,False],[True,False],[True,False]])) 19 | 20 | if __name__ == '__main__': 21 | run_local_tests() 22 | -------------------------------------------------------------------------------- /test/arrays/test_assign_slice.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | from parakeet import testing_helpers 3 | import numpy as np 4 | 5 | @parakeet.jit 6 | def setidx(x, idx, y): 7 | x[idx] = y 8 | return x 9 | 10 | def test_set_1d_simple_slice(): 11 | x = np.array([1,2,3,4,5,6]) 12 | idx = slice(2,4) 13 | y = [10, 20] 14 | x2 = x.copy() 15 | x[idx] = y 16 | testing_helpers.expect(setidx, [x2, idx, y], x) 17 | 18 | def test_set_1d_simple_slice_to_const(): 19 | x = np.array([1,2,3,4,5,6]) 20 | idx = slice(2,4) 21 | y = 0 22 | x2 = x.copy() 23 | x[idx] = y 24 | testing_helpers.expect(setidx, [x2, idx, y], x) 25 | 26 | def test_set_1d_step_slice_to_const(): 27 | x = np.array([1,2,3,4,5,6]) 28 | idx = slice(2,4,2) 29 | y = 0 30 | x2 = x.copy() 31 | x[idx] = y 32 | testing_helpers.expect(setidx, (x2, idx, y), x) 33 | 34 | def test_set_1d_negative_slice(): 35 | x = np.array([1,2,3,4,5,6]) 36 | idx = slice(4,2,-1) 37 | y = [10, 20] 38 | x2 = x.copy() 39 | x[idx] = y 40 | testing_helpers.expect(setidx, (x2, idx, y), x) 41 | 42 | if __name__ == '__main__': 43 | testing_helpers.run_local_tests() 44 | 45 | -------------------------------------------------------------------------------- /test/arrays/test_broadcasting.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit 3 | from parakeet.testing_helpers import expect_eq, run_local_tests 4 | 5 | @jit 6 | def add(x,y): 7 | return x + y 8 | 9 | def test_2d_scalar(): 10 | x = np.zeros((2,3)) 11 | res = add(x, 1) 12 | expect_eq(res, x + 1) 13 | 14 | def test_2d_1d(): 15 | x = np.zeros((2,3)) 16 | y = np.ones((3,)) 17 | res = add(x, y) 18 | expect_eq(res, x + y) 19 | 20 | def test_2d_2d(): 21 | x = np.zeros((2,3)) 22 | y = np.ones((2,3)) 23 | res = add(x, y) 24 | expect_eq(res, x + y) 25 | 26 | 27 | 28 | if __name__ == '__main__': 29 | run_local_tests() 30 | 31 | -------------------------------------------------------------------------------- /test/arrays/test_empty.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | 4 | from parakeet.testing_helpers import expect, run_local_tests 5 | 6 | 7 | def test_empty(): 8 | s = (20, 20, 3) 9 | x = np.empty(s) 10 | assert x.shape == s 11 | 12 | def test_empty_int(): 13 | s = (2,2,2,2) 14 | x = np.empty(s, dtype=np.uint8) 15 | assert x.shape == s 16 | assert x.dtype == np.uint8 17 | 18 | 19 | if __name__ == '__main__': 20 | run_local_tests() 21 | -------------------------------------------------------------------------------- /test/arrays/test_fancy_indexing.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | n = 8 5 | vec_int = np.arange(n) 6 | vec_bool = vec_int % 2 7 | vec_float = vec_bool * 2.75 8 | vectors = [vec_int, vec_bool, vec_float] 9 | 10 | indices = np.arange(n)[vec_bool] 11 | 12 | def idx(x,i): 13 | return x[i] 14 | 15 | def test_1d_by_1d(): 16 | for v in vectors: 17 | expect(idx, [v, indices], idx(v,indices)) 18 | 19 | mat_int = np.array([vec_int]*n) 20 | mat_float = np.array([vec_float]*n) 21 | mat_bool = np.array([vec_bool]*n) 22 | matrices = [mat_int, mat_float, mat_bool] 23 | 24 | def test_2d_by_idx(): 25 | for m in matrices: 26 | expect(idx, [m, indices], idx(m, indices)) 27 | 28 | if __name__ == '__main__': 29 | run_local_tests() 30 | -------------------------------------------------------------------------------- /test/arrays/test_indexing.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | shape_1d = 40 5 | ints_1d = np.arange(shape_1d) 6 | floats_1d = np.arange(shape_1d, dtype='float') 7 | bools_1d = ints_1d % 2 8 | 9 | vecs = [ints_1d, floats_1d, bools_1d] 10 | 11 | shape_2d = (4,10) 12 | matrices = [np.reshape(vec, shape_2d) for vec in vecs] 13 | 14 | shape_3d = (4,5,2) 15 | tensors = [np.reshape(mat, shape_3d) for mat in matrices] 16 | 17 | def index_1d(x, i): 18 | return x[i] 19 | 20 | def test_index_1d(): 21 | for vec in vecs: 22 | expect(index_1d, [vec, 20], vec[20]) 23 | 24 | def index_2d(x, i, j): 25 | return x[i, j] 26 | 27 | def test_index_2d(): 28 | for mat in matrices: 29 | expect(index_2d, [mat, 2, 5], mat[2,5]) 30 | 31 | def index_3d(x, i, j, k): 32 | return x[i, j, k] 33 | 34 | def test_index_3d(): 35 | for x in tensors: 36 | expect(index_3d, [x, 2, 2, 1], x[2,2,1]) 37 | 38 | 39 | 40 | 41 | if __name__ == '__main__': 42 | run_local_tests() 43 | -------------------------------------------------------------------------------- /test/arrays/test_methods.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import testing_helpers, jit 3 | 4 | values = [np.array(0), np.array(1.0), np.array([True]), 5 | np.array([1,2,3]), np.array([1.0, 2.0, 3.0]), np.array([True, False]), 6 | np.array([[1,2,3],[10,20,30]]), np.array([[1.0,2.0,3.0],[10.0,20.0, 30.0]]), 7 | np.array([[True], [False]]) 8 | ] 9 | 10 | def run(fn, method_name): 11 | fn = jit(fn) 12 | for v in values: 13 | method = getattr(v, method_name) 14 | expected = method() 15 | result = fn(v) 16 | try: 17 | if result == expected: 18 | return 19 | except: 20 | pass 21 | if hasattr(expected, 'dtype') and hasattr(result, 'dtype'): 22 | assert expected.dtype == result.dtype, \ 23 | "Mismatching dtype, expected %s but got %s" % (expected.dtype, result.dtype) 24 | else: 25 | assert type(expected) == type(result), \ 26 | "Mismatching type, expected %s but got %s" % (type(expected), type(result)) 27 | assert np.allclose(expected, result), \ 28 | "For test input %s, expected %s but got %s" % (v, expected, result) 29 | 30 | def test_min(): 31 | def call_min(x): 32 | return x.min() 33 | run(call_min, 'min') 34 | 35 | 36 | def test_max(): 37 | def call_max(x): 38 | return x.max() 39 | run(call_max, 'max') 40 | 41 | 42 | def test_any(): 43 | def call_any(x): 44 | return x.any() 45 | run(call_any, 'any') 46 | 47 | def test_all(): 48 | def call_all(x): 49 | return x.all() 50 | run(call_all, 'all') 51 | 52 | def test_copy(): 53 | def call_copy(x): 54 | return x.copy() 55 | run(call_copy, 'copy') 56 | x = np.array([1,2,3]) 57 | y = jit(call_copy)(x) 58 | old_val = x[0] 59 | x[0] = 10 60 | assert y[0] == old_val 61 | assert y[1] == x[1] 62 | 63 | def test_ravel(): 64 | def call_ravel(x): 65 | return x.ravel() 66 | run(call_ravel, 'ravel') 67 | 68 | def test_flatten(): 69 | def call_flatten(x): 70 | return x.flatten() 71 | run(call_flatten, 'flatten') 72 | 73 | if __name__ == '__main__': 74 | testing_helpers.run_local_tests() 75 | -------------------------------------------------------------------------------- /test/arrays/test_negative_indexing.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | from parakeet import config 4 | 5 | config.print_specialized_function = False 6 | config.print_loopy_function = False 7 | 8 | 9 | vec = np.arange(16) 10 | mat = vec.reshape(4,4) 11 | 12 | def negative_stop_1d(x): 13 | return x[:-2] 14 | 15 | def test_negative_stop_1d_vec(): 16 | expect(negative_stop_1d, [vec], negative_stop_1d(vec)) 17 | 18 | def test_negative_stop_1d_mat(): 19 | expect(negative_stop_1d, [mat], negative_stop_1d(mat)) 20 | 21 | def negative_stop_2d(x): 22 | return x[:-2, :-3] 23 | 24 | def test_negative_stop_2d(): 25 | expect(negative_stop_2d, [mat], negative_stop_2d(mat)) 26 | 27 | def negative_start_1d(x): 28 | return x[-2:] 29 | 30 | def test_negative_start_1d_vec(): 31 | expect(negative_start_1d, [vec], vec[-2:]) 32 | 33 | def test_negative_start_1d_mat(): 34 | expect(negative_start_1d, [mat], mat[-2:]) 35 | 36 | def negative_start_2d(x): 37 | return x[-2:, -3:] 38 | 39 | def test_negative_start_2d(): 40 | expect(negative_start_2d, [mat], mat[-2:, -3:]) 41 | 42 | def negative_step_1d(x): 43 | return x[::-2] 44 | 45 | def test_negative_step_1d_vec(): 46 | expect(negative_step_1d, [vec], vec[::-2]) 47 | 48 | def test_negative_step_1d_mat(): 49 | expect(negative_step_1d, [mat], mat[::-2]) 50 | 51 | def negative_step_2d(x): 52 | return x[::-2, ::-3] 53 | 54 | def test_negative_step_2d(): 55 | expect(negative_step_2d, [mat], mat[::-2, ::-3]) 56 | 57 | if __name__ == "__main__": 58 | run_local_tests() 59 | 60 | -------------------------------------------------------------------------------- /test/arrays/test_ones.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | 4 | from parakeet.testing_helpers import expect, run_local_tests 5 | 6 | def test_ones_1d(): 7 | expect(np.ones, [(10,)], np.ones(10)) 8 | 9 | def test_ones_2d(): 10 | expect(np.ones, [(10,2)], np.ones((10,2))) 11 | 12 | def test_ones_1d_int64(): 13 | expect(np.ones, [(10,), np.int64], np.ones(10, dtype=np.int64)) 14 | 15 | def test_ones_2d_int64(): 16 | expect(np.ones, [(10,2), np.int64], np.ones((10,2), dtype=np.int64)) 17 | 18 | def test_ones_1d_float64(): 19 | expect(np.ones, [(10,), np.float64], np.ones(10, dtype=np.float64)) 20 | 21 | def test_ones_2d_float64(): 22 | expect(np.ones, [(10,2), np.float64], np.ones((10,2), dtype=np.float64)) 23 | 24 | def test_ones_4d_float64(): 25 | expect(np.ones, [(10,2,2,2), np.float64], np.ones((10,2,2,2), dtype=np.float64)) 26 | 27 | if __name__ == "__main__": 28 | run_local_tests() 29 | -------------------------------------------------------------------------------- /test/arrays/test_ones_like.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | 4 | from parakeet.testing_helpers import expect, run_local_tests 5 | 6 | 7 | int_vec = np.array([1,2,3]) 8 | float_vec = np.array([1.0,2.0,3.0]) 9 | bool_vec = np.array([True,False]) 10 | 11 | int_mat = np.array([int_vec, int_vec]) 12 | float_mat = np.array([float_vec, float_vec]) 13 | bool_mat = np.array([bool_vec, bool_vec]) 14 | 15 | 16 | def test_ones_like(): 17 | expect(np.ones_like, [int_vec], np.ones_like(int_vec)) 18 | 19 | def test_ones_like_intmat(): 20 | expect(np.ones_like, [int_mat], np.ones_like(int_mat)) 21 | 22 | def test_ones_like_floatvec(): 23 | expect(np.ones_like, [float_vec], np.ones_like(float_vec)) 24 | 25 | def test_ones_like_floatmat(): 26 | expect(np.ones_like, [float_mat], np.ones_like(float_mat)) 27 | 28 | def test_ones_like_boolvec(): 29 | expect(np.ones_like, [bool_vec], np.ones_like(bool_vec)) 30 | 31 | def test_ones_like_boolmat(): 32 | expect(np.ones_like, [bool_mat], np.ones_like(bool_mat)) 33 | 34 | def test_ones_like_boolvec_to_float(): 35 | expect(np.ones_like, [bool_vec, np.dtype('float')], np.ones_like(bool_vec, dtype = np.dtype('float'))) 36 | 37 | def test_ones_like_boolmat_to_float(): 38 | expect(np.ones_like, [bool_mat, np.dtype('float')], np.ones_like(bool_mat, dtype = np.dtype('float'))) 39 | 40 | 41 | if __name__ == '__main__': 42 | run_local_tests() -------------------------------------------------------------------------------- /test/arrays/test_properties.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet import testing_helpers 4 | 5 | values = [np.array(0), np.array(0.0), np.array(True), 6 | np.array([0]), 7 | np.array([[0],[1]]), 8 | np.array([[0.0], [1.0]]), 9 | np.array([[True], [False]]) 10 | ] 11 | 12 | def run(fn, prop ): 13 | fn = parakeet.jit(fn) 14 | for v in values: 15 | expected = getattr(v, prop) 16 | result = fn(v) 17 | assert np.allclose(expected, result), "Expected %s but got %s" % (expected, result) 18 | 19 | 20 | def test_prop_real(): 21 | def get_real(x): 22 | return x.real 23 | run(get_real, 'real') 24 | 25 | #def test_prop_imag(): 26 | # def get_imag(x): 27 | # return x.imag 28 | # run(get_imag, 'imag') 29 | 30 | def test_prop_ndim(): 31 | def get_ndim(x): 32 | return x.ndim 33 | run(get_ndim, 'ndim') 34 | 35 | def test_prop_size(): 36 | def get_size(x): 37 | return x.size 38 | run(get_size, 'size') 39 | 40 | def test_prop_shape(): 41 | def get_shape(x): 42 | return x.shape 43 | run(get_shape, 'shape') 44 | 45 | def test_prop_T(): 46 | def get_T(x): 47 | return x.T 48 | run(get_T, 'T') 49 | 50 | if __name__ == '__main__': 51 | testing_helpers.run_local_tests() 52 | -------------------------------------------------------------------------------- /test/arrays/test_range.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet import testing_helpers 4 | 5 | 6 | 7 | @parakeet.jit 8 | def range1(n): 9 | return range(n) 10 | 11 | def test_range1(): 12 | n = 10 13 | numpy_result = np.arange(n) 14 | parakeet_result = range1(n) 15 | testing_helpers.assert_eq_arrays(numpy_result, parakeet_result, "range1") 16 | 17 | @parakeet.jit 18 | def range2(start, stop): 19 | return range(start, stop) 20 | 21 | def test_range2(): 22 | shape = (100,111) 23 | numpy_result = np.arange(*shape) 24 | parakeet_result = range2(*shape) 25 | testing_helpers.assert_eq_arrays(numpy_result, parakeet_result, "range2") 26 | 27 | @parakeet.jit 28 | def range3(start, stop, step): 29 | return range(start, stop, step) 30 | 31 | def test_range3(): 32 | shape = (10,20,2) 33 | numpy_result = np.arange(*shape) 34 | parakeet_result = range3(10,20,2) 35 | testing_helpers.assert_eq_arrays(numpy_result, parakeet_result, "range3") 36 | 37 | 38 | """ 39 | def test_big_step(): 40 | shape = (10,20,100) 41 | numpy_result = np.arange(*shape) 42 | parakeet_result = range3(*shape) 43 | 44 | assert_eq_arrays(numpy_result, parakeet_result,"range_big_step") 45 | """ 46 | 47 | if __name__ == '__main__': 48 | testing_helpers.run_local_tests() 49 | -------------------------------------------------------------------------------- /test/arrays/test_ravel.py: -------------------------------------------------------------------------------- 1 | from parakeet import testing_helpers 2 | import numpy as np 3 | 4 | def ravel_method(x): 5 | return x.ravel() 6 | 7 | vec = np.arange(12) 8 | 9 | def run(x): 10 | testing_helpers.expect(ravel_method, [x], x.ravel()) 11 | # testing_helpers.expect(np.ravel, [x], x.ravel()) 12 | 13 | def test_ravel_vec(): 14 | run(vec) 15 | 16 | def test_ravel_mat_row_major(): 17 | matrix_row_major = np.reshape(vec, (3,4), order = "C") 18 | run(matrix_row_major) 19 | 20 | def test_ravel_mat_col_major(): 21 | matrix_col_major = np.reshape(vec, (3,4), order = "F") 22 | run(matrix_col_major) 23 | 24 | def test_ravel_cube(): 25 | cube = np.reshape(vec, (3,2,2)) 26 | run(cube) 27 | 28 | if __name__ == '__main__': 29 | testing_helpers.run_local_tests() 30 | -------------------------------------------------------------------------------- /test/arrays/test_setidx.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | shape_1d = 40 5 | ints_1d = np.arange(shape_1d) 6 | floats_1d = np.arange(shape_1d, dtype='float') 7 | bools_1d = ints_1d % 2 8 | 9 | vecs = [ints_1d, floats_1d, bools_1d] 10 | 11 | shape_2d = (4,10) 12 | matrices = [np.reshape(vec, shape_2d) for vec in vecs] 13 | 14 | shape_3d = (4,5,2) 15 | tensors = [np.reshape(mat, shape_3d) for mat in matrices] 16 | 17 | def set_idx_1d(arr,i,val): 18 | arr[i] = val 19 | return arr 20 | 21 | def test_set_idx_1d(): 22 | idx = 10 23 | for vec in vecs: 24 | vec1, vec2 = vec.copy(), vec.copy() 25 | val = -vec[idx] 26 | vec2[idx] = val 27 | expect(set_idx_1d, [vec1, idx, val], vec2) 28 | 29 | def set_idx_2d(arr,i,j,val): 30 | arr[i, j] = val 31 | return arr 32 | 33 | def test_set_idx_2d(): 34 | i = 2 35 | j = 2 36 | for mat in matrices: 37 | mat1, mat2 = mat.copy(), mat.copy() 38 | val = -mat[i,j] 39 | mat2[i,j] = val 40 | expect(set_idx_2d, [mat1, i, j, val], mat2) 41 | 42 | def set_idx_3d(arr, i, j, k, val): 43 | arr[i, j, k] = val 44 | return arr 45 | 46 | def test_set_idx_3d(): 47 | i = 2 48 | j = 3 49 | k = 1 50 | for x in tensors: 51 | x1, x2 = x.copy(), x.copy() 52 | val = -x[i, j, k] 53 | x2[i, j, k] = val 54 | expect(set_idx_3d, [x1, i, j, k, val], x2) 55 | 56 | 57 | if __name__ == '__main__': 58 | run_local_tests() 59 | -------------------------------------------------------------------------------- /test/arrays/test_slice_arith.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import testing_helpers 3 | 4 | def add_2d(x): 5 | return x[1:-1, 2:] + x[1:-1, :-2] - 4 * x[1:-1, 1:-1] 6 | 7 | def test_add_2d(): 8 | x = np.array([[1,2,3,4,5,6],[10,20,30,40,50,60]]) 9 | testing_helpers.expect(add_2d, [x], add_2d(x)) 10 | 11 | if __name__ == "__main__": 12 | testing_helpers.run_local_tests() 13 | 14 | -------------------------------------------------------------------------------- /test/arrays/test_zeros.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet.testing_helpers import expect, run_local_tests 4 | 5 | def test_zeros_1d(): 6 | expect(np.zeros, [(10,)], np.zeros(10)) 7 | 8 | def test_zeros_2d(): 9 | expect(np.zeros, [(10,2)], np.zeros((10,2))) 10 | 11 | def test_zeros_1d_int64(): 12 | expect(np.zeros, [(10,), np.int64], np.zeros(10, dtype=np.int64)) 13 | 14 | def test_zeros_2d_int64(): 15 | expect(np.zeros, [(10,2), np.int64], np.zeros((10,2), dtype=np.int64)) 16 | 17 | def test_zeros_1d_float64(): 18 | expect(np.zeros, [(10,), np.float64], np.zeros(10, dtype=np.float64)) 19 | 20 | def test_zeros_2d_float64(): 21 | expect(np.zeros, [(10,2), np.float64], np.zeros((10,2), dtype=np.float64)) 22 | 23 | def test_zeros_4d_float64(): 24 | expect(np.zeros, [(10,2,2,2), np.float64], np.zeros((10,2,2,2), dtype=np.float64)) 25 | 26 | 27 | if __name__ == "__main__": 28 | run_local_tests() 29 | 30 | -------------------------------------------------------------------------------- /test/arrays/test_zeros_like.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | 4 | from parakeet.testing_helpers import expect, run_local_tests 5 | 6 | 7 | int_vec = np.array([1,2,3]) 8 | float_vec = np.array([1.0,2.0,3.0]) 9 | bool_vec = np.array([True,False]) 10 | 11 | int_mat = np.array([int_vec, int_vec]) 12 | float_mat = np.array([float_vec, float_vec]) 13 | bool_mat = np.array([bool_vec, bool_vec]) 14 | 15 | 16 | # 17 | # ZEROS_LIKE 18 | # 19 | def test_zeros_like_intvec(): 20 | expect(np.zeros_like, [int_vec], np.zeros_like(int_vec)) 21 | 22 | def test_zeros_like_intmat(): 23 | expect(np.zeros_like, [int_mat], np.zeros_like(int_mat)) 24 | 25 | def test_zeros_like_floatvec(): 26 | expect(np.zeros_like, [float_vec], np.zeros_like(float_vec)) 27 | 28 | def test_zeros_like_floatmat(): 29 | expect(np.zeros_like, [float_mat], np.zeros_like(float_mat)) 30 | 31 | def test_zeros_like_boolvec(): 32 | expect(np.zeros_like, [bool_vec], np.zeros_like(bool_vec)) 33 | 34 | def test_zeros_like_boolmat(): 35 | expect(np.zeros_like, [bool_mat], np.zeros_like(bool_mat)) 36 | 37 | def test_zeros_like_boolvec_to_float(): 38 | expect(np.zeros_like, [bool_vec, np.dtype('float')], np.zeros_like(bool_vec, dtype = np.dtype('float'))) 39 | 40 | def test_zeros_like_boolmat_to_float(): 41 | expect(np.zeros_like, [bool_mat, np.dtype('float')], np.zeros_like(bool_mat, dtype = np.dtype('float'))) 42 | 43 | if __name__ == "__main__": 44 | run_local_tests() 45 | 46 | -------------------------------------------------------------------------------- /test/builtins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/builtins/__init__.py -------------------------------------------------------------------------------- /test/builtins/test_max.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def test_max_int(): 4 | expect(max, [3,4], 4) 5 | 6 | def test_max_float(): 7 | expect(max, [3.0,4.0], 4.0) 8 | 9 | def test_max_int_float(): 10 | expect(max, [3, 4.0], 4.0) 11 | 12 | def test_max_bool(): 13 | expect(max, [False, True], True) 14 | 15 | if __name__ == '__main__': 16 | run_local_tests() 17 | -------------------------------------------------------------------------------- /test/builtins/test_min.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def test_min_int(): 4 | expect(min, [-3, 4], -3) 5 | 6 | def test_min_float(): 7 | expect(min, [-3.0, 4.0], -3.0) 8 | 9 | 10 | if __name__ == '__main__': 11 | run_local_tests() 12 | -------------------------------------------------------------------------------- /test/builtins/test_range.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit 3 | from parakeet.testing_helpers import expect, run_local_tests 4 | 5 | @jit 6 | def range1(a): 7 | return range(a) 8 | 9 | def test_range1(): 10 | expect(range1, [10], np.arange(10)) 11 | 12 | @jit 13 | def range2(a,b): 14 | return range(a,b) 15 | 16 | def test_range2(): 17 | expect(range2, [10, 20], np.arange(10,20)) 18 | 19 | @jit 20 | def range3(a,b,c): 21 | return range(a,b,c) 22 | 23 | def test_range3(): 24 | expect(range3, [20,45,3], np.arange(20,45,3)) 25 | 26 | if __name__ == '__main__': 27 | run_local_tests() 28 | -------------------------------------------------------------------------------- /test/builtins/test_sum.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | 5 | def test_sum_int(): 6 | x = np.array([1,2,3]) 7 | expect(sum, [x], sum(x)) 8 | 9 | def test_sum_float(): 10 | x = np.array([1.0,2.0,3.0]) 11 | expect(sum, [x], sum(x)) 12 | 13 | def sum_bool(): 14 | x = np.array([True, False, True]) 15 | expect(sum, [x], sum(x)) 16 | 17 | if __name__ == '__main__': 18 | run_local_tests() 19 | -------------------------------------------------------------------------------- /test/builtins/test_types.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def test_float_to_int(): 4 | expect(int, [1.2], 1) 5 | 6 | def test_int_to_float(): 7 | expect(float, [1], 1.0) 8 | 9 | def test_bool_to_float(): 10 | expect(float, [True], 1.0) 11 | 12 | def test_float_to_long(): 13 | expect(long, [-1.0], -1) 14 | 15 | if __name__ == '__main__': 16 | run_local_tests() 17 | -------------------------------------------------------------------------------- /test/compiler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/compiler/__init__.py -------------------------------------------------------------------------------- /test/compiler/test_call_overhead.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit 2 | from parakeet.testing_helpers import run_local_tests, expect 3 | import time 4 | 5 | def f(x,y,z=1,q=3): 6 | return x + y + z + q 7 | 8 | 9 | jitf = jit(f) 10 | 11 | def test_call_overhead_identity(): 12 | n = 2000 13 | x = 3 14 | start_t = time.time() 15 | for i in xrange(n): 16 | f(x,x,x,x) 17 | python_time = time.time() - start_t 18 | print "Python time for %d calls: %f" % (n, python_time) 19 | # warm up! 20 | jitf(x,x,x,x) 21 | start_t = time.time() 22 | for i in xrange(n): 23 | jitf(x,x,x,x) 24 | parakeet_time = time.time() - start_t 25 | print "Parakeet time for %d calls: %f" % (n, parakeet_time) 26 | print "Slowdown = %f" % (parakeet_time / python_time ) 27 | assert parakeet_time < 1000 * python_time, "Excessive call overhead: %f Python vs. %f Parakeet" % (python_time, parakeet_time) 28 | 29 | 30 | if __name__ == "__main__": 31 | run_local_tests() 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/compiler/test_codegen_add_scalars.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | from parakeet.testing_helpers import run_local_tests, expect_eq 3 | 4 | def mk_adder(t): 5 | f, b, (x,y) = parakeet.build_fn([t,t], t) 6 | b.return_(b.add(x,y)) 7 | return f 8 | 9 | def double_i64(x): 10 | fn = mk_adder(parakeet.Int64) 11 | return parakeet.run_typed_fn(fn, (x,x)) 12 | 13 | def double_f64(x): 14 | fn = mk_adder(parakeet.Float64) 15 | return parakeet.run_typed_fn(fn, (x,x)) 16 | 17 | def test_add(): 18 | expect_eq(double_i64(1), 2) 19 | expect_eq(double_i64(-1), -2) 20 | expect_eq(double_f64(1.0), 2.0) 21 | expect_eq(double_f64(-1.0), -2.0) 22 | 23 | 24 | if __name__ == '__main__': 25 | run_local_tests() 26 | -------------------------------------------------------------------------------- /test/compiler/test_codegen_add_vecs.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import run_local_tests, expect_eq 3 | import parakeet 4 | 5 | def mk_scalar_add(t): 6 | f, b, (x,y) = parakeet.build_fn([t,t], t) 7 | b.return_(b.add(x,y)) 8 | return f 9 | 10 | def mk_vec_add(array_t): 11 | elt_t = parakeet.elt_type(array_t) 12 | add_fn = mk_scalar_add(elt_t) 13 | fn, builder, inputs = parakeet.build_fn([array_t, array_t, array_t]) 14 | x,y,z = inputs 15 | n = builder.len(x) 16 | def loop_body(idx): 17 | elt_x = builder.index(x, idx) 18 | elt_y = builder.index(y, idx) 19 | builder.setidx(z, idx, builder.call(add_fn, (elt_x, elt_y))) 20 | builder.loop(0, n, loop_body) 21 | builder.return_(builder.none) 22 | return fn 23 | 24 | 25 | def vec_add(x,y): 26 | assert x.dtype == y.dtype 27 | assert len(x.shape) == len(y.shape) == 1 28 | z = np.zeros_like(x) 29 | array_t = parakeet.typeof(x) 30 | fn = mk_vec_add(array_t) 31 | parakeet.run_typed_fn(fn, (x,y,z)) 32 | return z 33 | 34 | def test_vec_add(): 35 | xs,ys = np.array([1,2,3]), np.array([10,20,30]) 36 | zs = vec_add(xs, ys) 37 | expected = xs + ys 38 | expect_eq(zs, expected) 39 | 40 | 41 | if __name__ == '__main__': 42 | run_local_tests() 43 | -------------------------------------------------------------------------------- /test/compiler/test_codegen_identity.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import run_local_tests, expect_eq 2 | 3 | import parakeet 4 | 5 | 6 | def identity_i64(x): 7 | fn = parakeet.mk_identity_fn(parakeet.Int64) 8 | print repr(fn) 9 | return parakeet.run_typed_fn(fn, (x,)) 10 | 11 | def identity_f64(x): 12 | fn = parakeet.mk_identity_fn(parakeet.Float64) 13 | return parakeet.run_typed_fn(fn, (x,)) 14 | 15 | def test_identity(): 16 | expect_eq(identity_i64(1), 1) 17 | expect_eq(identity_i64(-1), -1) 18 | expect_eq(identity_f64(1.0), 1.0) 19 | expect_eq(identity_f64(-1.0), -1.0) 20 | 21 | 22 | if __name__ == '__main__': 23 | 24 | run_local_tests() 25 | -------------------------------------------------------------------------------- /test/compiler/test_codegen_sum_loop.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import run_local_tests, expect_eq 3 | 4 | import parakeet 5 | 6 | def mk_sum(elt_t): 7 | array_t = parakeet.ndtypes.make_array_type(elt_t, 1) 8 | f, b, (x,) = parakeet.build_fn([array_t], elt_t) 9 | n = b.len(x) 10 | total, total_after, merge = b.loop_var('total', b.zero(elt_t)) 11 | def loop_body(idx): 12 | b.assign(total_after, b.add(total, b.index(x,idx))) 13 | b.loop(0, n, loop_body, merge = merge) 14 | b.return_(total) 15 | return f 16 | 17 | def sum_i64(x): 18 | fn = mk_sum(parakeet.Int64) 19 | print fn 20 | return parakeet.run_typed_fn(fn, (x,)) 21 | 22 | def sum_f64(x): 23 | fn = mk_sum(parakeet.Float64) 24 | return parakeet.run_typed_fn(fn, (x,)) 25 | 26 | def test_sum(): 27 | expect_eq(sum_i64(np.array([1,2,3])), 6) 28 | expect_eq(sum_f64(np.array([-1.0, 1.0, 2.0])), 2.0) 29 | 30 | 31 | if __name__ == '__main__': 32 | 33 | run_local_tests() 34 | -------------------------------------------------------------------------------- /test/compiler/test_licm.py: -------------------------------------------------------------------------------- 1 | 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | def volatile_licm_mistake(): 5 | i = 0 6 | x = [0] 7 | while i < 10: 8 | alloc = [1] 9 | if i == 5: 10 | x = alloc 11 | else: 12 | alloc[0] = 100 13 | i = i + 1 14 | return x[0] 15 | 16 | def test_volatile_licm_mistake(): 17 | expect(volatile_licm_mistake, [], volatile_licm_mistake()) #np.array([1])) 18 | 19 | def licm_nested_loops(): 20 | 21 | total = 0 22 | a = [1,2,3,4,5] 23 | for _ in range(3): 24 | for _ in range(2): 25 | for j in range(len(a)): 26 | a[j] *= 10 27 | total += a[1] 28 | return total 29 | 30 | def test_licm_nested_loops(): 31 | expect(licm_nested_loops, [], licm_nested_loops()) 32 | 33 | def loop_invariant_alloc(): 34 | b = [1,2,3] 35 | total = 0 36 | for i in xrange(3): 37 | a = [0,0,0] 38 | for j in xrange(3): 39 | a[j] = b[j] 40 | total += a[i] 41 | return total 42 | 43 | def test_loop_invariant_alloc(): 44 | expect(loop_invariant_alloc, [], loop_invariant_alloc()) 45 | 46 | 47 | if __name__ == "__main__": 48 | run_local_tests() -------------------------------------------------------------------------------- /test/compiler/test_mutability_analysis.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | 5 | from parakeet.analysis import mutability_analysis 6 | from parakeet import make_array_type, Int64, Bool, ptr_type, specialize 7 | from parakeet.transforms.pipeline import lowering 8 | from parakeet.testing_helpers import run_local_tests 9 | 10 | def f(x,y): 11 | x[0] = True 12 | return y 13 | 14 | def test_mutable_array(): 15 | bool_vec = np.array([True, False]) 16 | int_vec = np.array([1,2]) 17 | typed, _, = specialize(f, [bool_vec, int_vec]) 18 | 19 | mutable_types = mutability_analysis.find_mutable_types(typed) 20 | int_array_t = make_array_type(Int64, 1) 21 | bool_array_t = make_array_type(Bool, 1) 22 | assert int_array_t not in mutable_types, \ 23 | "Didn't expect %s in mutable_types %s" % (int_array_t, mutable_types) 24 | assert bool_array_t in mutable_types, \ 25 | "Expected %s in mutable_types %s" % (bool_array_t, mutable_types) 26 | 27 | lowered = lowering.apply(typed) 28 | mutable_types = mutability_analysis.find_mutable_types(lowered) 29 | ptr_bool_t = ptr_type(Bool) 30 | ptr_int_t = ptr_type(Int64) 31 | assert ptr_int_t not in mutable_types, \ 32 | "Didn't expect %s in lowered mutable types %s" % \ 33 | (ptr_int_t, mutable_types) 34 | assert ptr_bool_t in mutable_types, \ 35 | "Expected %s in lowered mutable_types %s" % (ptr_bool_t, mutable_types) 36 | 37 | """ 38 | # Removed this test when I made attributes immutable 39 | def f(): 40 | x = slice(1, 2, 3) 41 | x.start = 10 42 | x.stop = 20 43 | y = slice(1,2,3) 44 | if 3 < y.step: 45 | y.step = y.step + 1 46 | else: 47 | y.step = 0 48 | 49 | def test_mutable_slice(): 50 | _, typed, _, _ = testing_helpers.specialize_and_compile(f, []) 51 | mutable_types = mutability_analysis.find_mutable_types(typed) 52 | 53 | assert len(mutable_types) == 1, mutable_types 54 | lowered = lowering.apply(typed) 55 | mutable_types = mutability_analysis.find_mutable_types(lowered) 56 | assert len(mutable_types) == 1, mutable_types 57 | """ 58 | if __name__ == '__main__': 59 | run_local_tests() 60 | -------------------------------------------------------------------------------- /test/compiler/test_subtypes.py: -------------------------------------------------------------------------------- 1 | from parakeet.ndtypes import Int8, Int16, Int32, Float32, Float64 2 | from parakeet.ndtypes import is_scalar_subtype 3 | from parakeet.testing_helpers import run_local_tests 4 | 5 | def test_int32_subtypes(): 6 | assert is_scalar_subtype(Int8, Int32) 7 | assert not is_scalar_subtype(Int32, Int8) 8 | assert is_scalar_subtype(Int32, Float32) 9 | assert not is_scalar_subtype(Float32, Int32) 10 | 11 | def test_float32_subtypes(): 12 | assert is_scalar_subtype(Int8, Float32) 13 | assert not is_scalar_subtype(Float32, Int8) 14 | assert is_scalar_subtype(Float32, Float64) 15 | assert not is_scalar_subtype(Float64, Float32) 16 | 17 | if __name__ == '__main__': 18 | run_local_tests() 19 | -------------------------------------------------------------------------------- /test/compiler/test_type_inference.py: -------------------------------------------------------------------------------- 1 | from parakeet import UInt8, Int8, Int32, Int64, Float32, Float64, Bool 2 | from parakeet.testing_helpers import expect_type, run_local_tests 3 | 4 | def add1(x): 5 | return x + 1 6 | 7 | def call_add1(x): 8 | return add1(x) 9 | 10 | def test_add1(): 11 | expect_type(add1, [Int32], Int64) 12 | expect_type(add1, [Int8], Int64) 13 | expect_type(add1, [UInt8], Int64) 14 | expect_type(add1, [Bool], Int64) 15 | expect_type(add1, [Int64], Int64) 16 | expect_type(add1, [Float32], Float64) 17 | 18 | def test_call_add1(): 19 | expect_type(call_add1, [Int32], Int64) 20 | expect_type(call_add1, [Float32], Float64) 21 | expect_type(call_add1, [Bool], Int64) 22 | expect_type(add1, [Float32], Float64) 23 | 24 | def add(x,y): 25 | return x + y 26 | 27 | def test_add_bools(): 28 | """ 29 | test_add_bools: 30 | Parakeet booleans don't behave like the default Python type but rather like 31 | numpy.bool8, where (+) == (or) and (*) == (and) 32 | """ 33 | expect_type(add, [Bool, Bool], Bool) 34 | 35 | def branch_return(b): 36 | if b: 37 | return 1 38 | else: 39 | return 1.0 40 | 41 | def test_branch_return(): 42 | expect_type(branch_return, [Bool], Float64) 43 | 44 | def branch_assign(b): 45 | if b: 46 | x = 0 47 | else: 48 | x = 1.0 49 | return x 50 | 51 | def test_branch_assign(): 52 | expect_type(branch_assign, [Bool], Float64) 53 | 54 | def incr_loop(init, count): 55 | x = init 56 | while x < count: 57 | x = x + 1 58 | return x 59 | 60 | def test_incr_loop(): 61 | expect_type(incr_loop, [Int32, Int32], Int64) 62 | expect_type(incr_loop, [Float64, Int32], Float64) 63 | 64 | if __name__ == '__main__': 65 | run_local_tests() 66 | -------------------------------------------------------------------------------- /test/core_language/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/core_language/__init__.py -------------------------------------------------------------------------------- /test/core_language/test_arith.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit, testing_helpers 3 | 4 | 5 | values = [1, 6 | 1.0, 7 | np.array([True, True, True]), 8 | #np.array([1,2,3], dtype='int8'), 9 | np.array([1,2,3], dtype='int16'), 10 | #np.array([1,2,3], dtype='int32'), 11 | #np.array([1,2,3], dtype='int64'), 12 | np.array([1,2,3], dtype='float32'), 13 | 14 | #np.array([1,2,3], dtype='float64') 15 | ] 16 | 17 | def run(parakeet_fn, python_fn): 18 | testing_helpers.expect_allpairs(jit(parakeet_fn), python_fn, values) 19 | 20 | def add(x,y): 21 | return x + y 22 | 23 | def test_add(): 24 | run(add, np.add) 25 | 26 | def sub(x,y): 27 | return x - y 28 | 29 | def test_sub(): 30 | run(sub, np.subtract) 31 | 32 | def mult(x,y): 33 | return x * y 34 | 35 | def test_mult(): 36 | run(mult, np.multiply) 37 | 38 | def div(x,y): 39 | return x / y 40 | 41 | def test_div(): 42 | run(div, np.divide) 43 | 44 | def mod(x,y): 45 | return x % y 46 | 47 | def test_mod(): 48 | run(mod, np.mod) 49 | 50 | if __name__ == '__main__': 51 | testing_helpers.run_local_tests() 52 | -------------------------------------------------------------------------------- /test/core_language/test_cast.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def implicit_to_float(x): 4 | return x + 0.5 5 | 6 | def test_implicit_to_float(): 7 | expect(implicit_to_float, [1], 1.5) 8 | expect(implicit_to_float, [True], 1.5) 9 | 10 | def implicit_to_bool(b): 11 | if b: 12 | return 10 13 | else: 14 | return -10 15 | 16 | def test_implicit_to_bool(): 17 | expect(implicit_to_bool, [1], 10) 18 | expect(implicit_to_bool, [2], 10) 19 | expect(implicit_to_bool, [0], -10) 20 | expect(implicit_to_bool, [1.0], 10) 21 | expect(implicit_to_bool, [2.0], 10) 22 | expect(implicit_to_bool, [0.0], -10) 23 | 24 | if __name__ == '__main__': 25 | run_local_tests() 26 | -------------------------------------------------------------------------------- /test/core_language/test_closure_args.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | import numpy as np 3 | 4 | global_int = 5 5 | global_tuple = (5,3.0) 6 | global_array = np.array([1,2,3]) 7 | 8 | def use_globals(x): 9 | return x + global_int + global_array + global_tuple[1] 10 | 11 | def test_use_globals(): 12 | expect(use_globals, [2], use_globals(2)) 13 | 14 | def use_locals(x): 15 | local_int = global_int 16 | local_array = global_array 17 | local_tuple = global_tuple 18 | local_int2 = 3 19 | local_tuple2 = (5.0,9.0) 20 | local_array2 = np.array([4,5,6]) 21 | def nested(y): 22 | return x + y + local_int + local_array + local_tuple[1] + local_int2 + local_tuple2[1] + local_array2 23 | return nested(x+1) 24 | 25 | def test_use_locals(): 26 | expect(use_locals, [True], use_locals(True)) 27 | 28 | if __name__ == "__main__": 29 | run_local_tests() 30 | -------------------------------------------------------------------------------- /test/core_language/test_div_bool.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import jit, testing_helpers 3 | 4 | @jit 5 | def true_divided(x): 6 | return True / x 7 | 8 | def test_true_divided_bool(): 9 | testing_helpers.expect(true_divided, [True], True) 10 | 11 | def test_true_divided_int(): 12 | testing_helpers.expect(true_divided, [1], 1) 13 | testing_helpers.expect(true_divided, [2], 0) 14 | 15 | def test_true_divided_float(): 16 | testing_helpers.expect(true_divided, [1.0], 1.0) 17 | testing_helpers.expect(true_divided, [2.0], 0.5) 18 | 19 | def test_true_divided_uint8(): 20 | testing_helpers.expect(true_divided, [np.uint8(1)], 1) 21 | testing_helpers.expect(true_divided, [np.uint8(2)], 0) 22 | 23 | if __name__ == '__main__': 24 | testing_helpers.run_local_tests() 25 | -------------------------------------------------------------------------------- /test/core_language/test_lambda.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def call_const_lambda(): 4 | return (lambda: 1)() 5 | 6 | def test_call_const_lambda(): 7 | expect(call_const_lambda, [], 1) 8 | 9 | def call_identity_lambda(x): 10 | return (lambda y: y)(x) 11 | 12 | def test_call_identity_lambda(): 13 | expect(call_identity_lambda, [1], 1) 14 | 15 | def call_closure_lambda(x): 16 | return (lambda y: x + y)(x) 17 | 18 | def test_call_closure_lambda(): 19 | expect(call_closure_lambda, [1], 2) 20 | 21 | if __name__ == "__main__": 22 | run_local_tests() 23 | -------------------------------------------------------------------------------- /test/core_language/test_list_comp.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | 5 | x = np.array([1,2,3,4,5]) 6 | 7 | def identity_comprehension(x): 8 | return [xi for xi in x] 9 | 10 | def test_identity_comprehension(): 11 | expect(identity_comprehension, [x], x) 12 | 13 | 14 | def sqr_elts(x): 15 | return [xi**2 for xi in x] 16 | 17 | def test_sqr_elts(): 18 | expect(sqr_elts, [x], x**2) 19 | 20 | def outer_prod(x, y): 21 | return [[xi * yi for xi in x] for yi in y] 22 | 23 | 24 | def test_outer_prod(): 25 | x = np.array([1.0,2.0,3.0]) 26 | y = np.array([10,20]) 27 | res = np.array(outer_prod(x,y)) 28 | expect(outer_prod, [x,y], res) 29 | 30 | def triple_nesting(x): 31 | return [[[zi + yi + xi for zi in x] for yi in x] for xi in x] 32 | 33 | def test_triple_nesting(): 34 | x = np.array([1,2,3]) 35 | expect(triple_nesting, [x], np.array(triple_nesting(x))) 36 | 37 | def repeat_elts(x): 38 | return [x[i:i+2] for i in range(len(x)-1)] 39 | 40 | def test_repeat_elts(): 41 | x = np.array([0,1,2,3,4,5]) 42 | y = np.array([[0,1], [1,2], [2,3], [3,4], [4,5]]) 43 | expect(repeat_elts, [x], y) 44 | 45 | 46 | if __name__ == '__main__': 47 | run_local_tests() 48 | 49 | -------------------------------------------------------------------------------- /test/core_language/test_loops.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import expect, run_local_tests 2 | 3 | def for_range_loop(start, stop, step): 4 | x = 0 5 | for _ in range(start, stop, step): 6 | x = x + 1 7 | return x 8 | 9 | def test_for_range_loop(): 10 | expect(for_range_loop, [1,10,2], for_range_loop(1,10,2)) 11 | 12 | def test_for_backwards(): 13 | expect(for_range_loop, [10,1,-1], for_range_loop(10,1,-1)) 14 | 15 | def count_loop(init, count): 16 | x = init 17 | while x < count: 18 | x = x + 1 19 | return x 20 | 21 | def test_count_loop(): 22 | expect(count_loop, [0, 300], 300) 23 | expect(count_loop, [0.0, 400], 400.0) 24 | expect(count_loop, [0.0, 500.0], 500.0) 25 | 26 | def nested_double_count(x): 27 | total = 0 28 | i = 0 29 | while i < x: 30 | j = 0 31 | total = total + 1 32 | while j < x: 33 | total = total + 1 34 | j = j + 1 35 | i = i + 1 36 | return total 37 | 38 | def test_nested_double_count(): 39 | expect(nested_double_count, [10], 110) 40 | 41 | def nested_mult(x,y): 42 | total_count = 0 43 | i = 0 44 | while i < x: 45 | j = 0 46 | while j < y: 47 | total_count = total_count + 1 48 | j = j + 1 49 | i = i + 1 50 | return total_count 51 | 52 | def test_nested_mult(): 53 | expect(nested_mult, [10, 11], 110) 54 | 55 | def conditional_loop(x): 56 | i = 0 57 | if x: 58 | while i < 10: 59 | i = i + 1 60 | return i 61 | 62 | def test_conditional_loop(): 63 | expect(conditional_loop, [True], 10) 64 | expect(conditional_loop, [False], 0) 65 | 66 | if __name__ == '__main__': 67 | run_local_tests() 68 | -------------------------------------------------------------------------------- /test/core_language/test_modulo.py: -------------------------------------------------------------------------------- 1 | from parakeet import jit 2 | from parakeet.testing_helpers import run_local_tests, expect 3 | 4 | @jit 5 | def mod(x,y): 6 | return x % y 7 | 8 | def run_mod(x, y): 9 | expect(mod, [x,y], x%y) 10 | 11 | def test_mod_positive(): 12 | run_mod(0,4) 13 | run_mod(4,4) 14 | run_mod(4,5) 15 | run_mod(5,4) 16 | run_mod(1,10000001) 17 | run_mod(10000001,1) 18 | 19 | def test_mod_1st_negative(): 20 | run_mod(-4,4) 21 | run_mod(-4,5) 22 | run_mod(-5,4) 23 | run_mod(-1,10000001) 24 | run_mod(-10000001,1) 25 | 26 | def test_mod_2nd_negative(): 27 | run_mod(0,-4) 28 | run_mod(4,-4) 29 | run_mod(4,-5) 30 | run_mod(5,-4) 31 | run_mod(1,-10000001) 32 | run_mod(10000001,-1) 33 | 34 | 35 | def test_mod_both_negative(): 36 | run_mod(-4,-4) 37 | run_mod(-4,-5) 38 | run_mod(-5,-4) 39 | run_mod(-1,-10000001) 40 | run_mod(-10000001,-1) 41 | 42 | if __name__ == '__main__': 43 | run_local_tests() 44 | -------------------------------------------------------------------------------- /test/core_language/test_square.py: -------------------------------------------------------------------------------- 1 | from parakeet.testing_helpers import run_local_tests, expect_eq 2 | 3 | def square(x): 4 | return np.square(x) 5 | 6 | def test_square_scalars(): 7 | expect_eq(square(1), 1) 8 | expect_eq(square(2), 4) 9 | expect_eq(square(-2), 4) 10 | expect_eq(square(True), True) 11 | expect_eq(square(False), False) 12 | expect_eq(square(-4.0), 16.0) 13 | 14 | import numpy as np 15 | intvec = np.array([-3,-2,-1,0,1,2,3]) 16 | floatvec = intvec.astype('float') 17 | 18 | def test_square_vectors(): 19 | expect_eq(square(intvec), intvec*intvec) 20 | expect_eq(square(floatvec), floatvec*floatvec) 21 | 22 | intmat = np.array([intvec, intvec]) 23 | floatmat = intmat.astype('float') 24 | 25 | def test_square_matrices(): 26 | expect_eq(square(intmat), intmat*intmat) 27 | expect_eq(square(floatmat), floatmat*floatmat) 28 | 29 | 30 | if __name__ == '__main__': 31 | run_local_tests() 32 | -------------------------------------------------------------------------------- /test/core_language/test_tuples.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import expect, run_local_tests 3 | 4 | def return_pair(): 5 | return (-1.0, 200) 6 | 7 | def test_return_pair(): 8 | expect(return_pair, [], (-1.0, 200)) 9 | 10 | ints = (np.int32(1), np.int32(2)) 11 | mixed = (1.0, 200L) 12 | nested = (ints, mixed) 13 | nested2 = (nested, nested) 14 | 15 | def all_tuples(f, unpack_args = True): 16 | """ 17 | Given a function which should act as the identity, test it on multiple tuples 18 | """ 19 | 20 | for t in [ints, mixed, nested2, nested2]: 21 | if unpack_args: 22 | expect(f, t, t) 23 | else: 24 | expect(f, [t], t) 25 | 26 | def create_tuple(x,y): 27 | return (x,y) 28 | 29 | def test_create_tuple(): 30 | all_tuples(create_tuple) 31 | 32 | #def tuple_arg((x,y)): 33 | # return (x,y) 34 | 35 | #def test_tuple_arg(): 36 | # all_tuples(tuple_arg, unpack_args = False) 37 | 38 | def tuple_lhs(t): 39 | x,y = t 40 | return x,y 41 | 42 | def test_tuple_lhs(): 43 | all_tuples(tuple_lhs, unpack_args = False) 44 | 45 | def tuple_lhs_sum(t): 46 | x, y, z = t 47 | return x + y + z 48 | 49 | def test_tuple_lhs_sum(): 50 | tuples = [(True, 0, 1.0), (1, True, 0)] 51 | for t in tuples: 52 | expect(tuple_lhs_sum, [t], sum(t)) 53 | 54 | def tuple_indexing(t): 55 | return (t[0], t[1]) 56 | 57 | def test_tuple_indexing(): 58 | all_tuples(tuple_indexing, unpack_args = False) 59 | 60 | def or_elts((b1,b2)): 61 | if b1 or b2: 62 | return 1 63 | else: 64 | return 0 65 | 66 | def test_or_elts(): 67 | expect(or_elts, [(True, True)], 1) 68 | expect(or_elts, [(True, False)], 1) 69 | expect(or_elts, [(False, True)], 1) 70 | expect(or_elts, [(False, False)], 0) 71 | 72 | if __name__ == '__main__': 73 | run_local_tests() 74 | -------------------------------------------------------------------------------- /test/core_language/test_zip.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet.testing_helpers import run_local_tests, expect 3 | 4 | def use_zip(x,y): 5 | return zip(x,y) 6 | 7 | def test_zip_tuples(): 8 | a = (1,2,3) 9 | b = (np.array([1.0]), np.array([2.0]), np.array([3.0])) 10 | expect(use_zip, [a,b], tuple(zip(a,b))) 11 | 12 | # TODO: 13 | # Figure out some plan for returning 'dtype' containing 14 | # multiple 15 | #def test_zip_arrays(): 16 | # a = np.array([1,2,3]) 17 | # b = np.array([True,False,False]) 18 | # expect(use_zip, [a,b], zip(a,b)) 19 | 20 | 21 | if __name__ == '__main__': 22 | run_local_tests() 23 | 24 | -------------------------------------------------------------------------------- /test/neighborhood/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/neighborhood/__init__.py -------------------------------------------------------------------------------- /test/neighborhood/test_patchmap.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import parakeet 4 | from parakeet import testing_helpers 5 | 6 | def erode(x, shape): 7 | return parakeet.pmap2(min, x, shape) 8 | 9 | x = np.array([[1,2,3],[4,5,6]]) 10 | 11 | def test_erode_identity_shape(): 12 | testing_helpers.expect(erode, [x, (1,1)], x) 13 | 14 | def test_erode(): 15 | shape = (3,3) 16 | expected = np.array([[1, 1, 2], [1,1,2]]) 17 | testing_helpers.expect(erode, [x, shape], expected) 18 | 19 | if __name__ == '__main__': 20 | testing_helpers.run_local_tests() 21 | -------------------------------------------------------------------------------- /test/neighborhood/test_windowed.py: -------------------------------------------------------------------------------- 1 | import parakeet 2 | from parakeet import jit, testing_helpers, c_backend, config 3 | import numpy as np 4 | 5 | c_backend.print_function_source = True 6 | c_backend.print_module_source = True 7 | 8 | @jit 9 | def avg1d(x): 10 | return sum(x) / float(len(x)) 11 | 12 | def test_avg1d(): 13 | x = np.random.randn(20) 14 | testing_helpers.eq(x.mean(), avg1d(x)) 15 | 16 | @jit 17 | def winmap_avg1d(x, w = 3): 18 | return parakeet.pmap1(avg1d, x, w) 19 | 20 | def test_winmap_avg1d(): 21 | x = np.random.randn(20)**2 22 | y = winmap_avg1d(x) 23 | assert x.shape == y.shape 24 | 25 | 26 | @jit 27 | def avg2d(x): 28 | nelts = x.shape[0] * x.shape[1] 29 | return sum(sum(x)) / float(nelts) 30 | 31 | def test_avg2d(): 32 | x = np.random.randn(20,30) 33 | testing_helpers.eq(x.mean(), avg2d(x)) 34 | 35 | @jit 36 | def winmap_zeros(x, wx = 3, wy = 3): 37 | def zero(_): 38 | return 0 39 | return parakeet.pmap2(zero, x, (wx, wy)) 40 | 41 | def test_winmap_zeros(): 42 | x = np.random.randn(100,100) 43 | y = winmap_zeros(x) 44 | assert y.sum() == 0 45 | 46 | @jit 47 | def winmap_first_elt(x, wx = 3, wy = 3): 48 | def f(window): 49 | return window[0,0] 50 | return parakeet.pmap2(f, x, wx, wy) 51 | 52 | 53 | def test_window_shapes(): 54 | x = np.array([0,1,2,3,4]) 55 | def winshape(x): 56 | return x.shape[0] 57 | y = parakeet.pmap1(winshape, x, 3) 58 | 59 | expected = np.array([2,3,3,3,2]) 60 | assert y.shape == expected.shape, "Expected shape %s but got %s" % (expected.shape, y.shape) 61 | assert np.all(y == expected), "Expected array %s but got %s" % (expected, y) 62 | 63 | @jit 64 | def winavg2d( x, wx = 3, wy = 3): 65 | return parakeet.pmap2(avg2d, x, (wx, wy)) 66 | 67 | def test_winavg2d(): 68 | x = np.random.rand(100,100) 69 | x[50:65, 50:65] = 0 70 | y = winavg2d(x) 71 | assert x.shape==y.shape 72 | assert x.max() >= y.max() 73 | assert x.min() <= y.min() 74 | 75 | if __name__ == '__main__': 76 | testing_helpers.run_local_tests() 77 | 78 | -------------------------------------------------------------------------------- /test/numpy_lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iskandr/parakeet/98eeb0c9355e446ff46925b01e3234795d6e762e/test/numpy_lib/__init__.py -------------------------------------------------------------------------------- /test/numpy_lib/test_linspace.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from parakeet import testing_helpers 3 | 4 | def test_simple_linspace(): 5 | testing_helpers.expect(np.linspace, [0.2, 0.9], np.linspace(0.2, 0.9)) 6 | 7 | def test_linspace_with_count(): 8 | testing_helpers.expect(np.linspace, [-0.2, 0.9, 30], np.linspace(-0.2, 0.9, 30)) 9 | 10 | if __name__ == "__main__": 11 | testing_helpers.run_local_tests() 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/numpy_lib/test_log1p.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | from parakeet import config 5 | from parakeet.testing_helpers import run_local_tests, expect 6 | 7 | config.print_transform_times = True 8 | 9 | w,h = 2,2 10 | n = w *h 11 | vec = np.arange(n) 12 | mat = vec.reshape((w,h)) 13 | 14 | dtypes = ['int8', 'int16', 'int32', 'int64', 15 | 'uint8', 'uint16', 'uint32', 'uint64', 16 | 'float32', 'float64', 'bool'] 17 | 18 | scalars = [True, 1, 1.0] 19 | vecs = [] 20 | mats = [] 21 | for dtype_name in dtypes: 22 | scalars.append(np.dtype(dtype_name).type(3)) 23 | vecs.append(vec.astype(dtype_name)) 24 | mats.append(mat.astype(dtype_name)) 25 | 26 | def test_log1p_scalar(): 27 | for scalar in scalars: 28 | print scalar, type(scalar) 29 | expect(np.log1p, [scalar], np.log1p(scalar)) 30 | 31 | def test_log1p_vec(): 32 | for vec in vecs: 33 | expect(np.log1p, [vec], np.log1p(vec)) 34 | 35 | def test_log1p_mat(): 36 | for mat in mats: 37 | expect(np.log1p, [mat], np.log1p(mat)) 38 | 39 | if __name__ == "__main__": 40 | run_local_tests() 41 | -------------------------------------------------------------------------------- /test/numpy_lib/test_prob.py: -------------------------------------------------------------------------------- 1 | from parakeet import testing_helpers 2 | import math 3 | 4 | def test_erfc(): 5 | testing_helpers.expect(math.erfc, [0], math.erfc(0)) 6 | testing_helpers.expect(math.erfc, [0.5], math.erfc(0.5)) 7 | testing_helpers.expect(math.erfc, [1], math.erfc(1)) 8 | 9 | def test_erf(): 10 | testing_helpers.expect(math.erf, [0], math.erf(0)) 11 | testing_helpers.expect(math.erf, [0.5], math.erf(0.5)) 12 | testing_helpers.expect(math.erf, [1], math.erf(1)) 13 | 14 | if __name__ == "__main__": 15 | testing_helpers.run_local_tests() -------------------------------------------------------------------------------- /test/numpy_lib/test_rint.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet.testing_helpers import run_local_tests 4 | 5 | 6 | @parakeet.jit 7 | def rint(x): 8 | return np.rint(x) 9 | 10 | def test_rint(): 11 | assert np.rint(1.2) == rint(1.2) 12 | assert np.rint(-1) == rint(-1) 13 | assert np.rint(-0.1) == rint(-0.1) 14 | x = np.array([-1, 2, 0]) 15 | assert np.allclose(np.rint(x), rint(x)) 16 | y = np.array([-1.1, -0.6, -0.4, 0.4, 0.6]) 17 | assert np.allclose(np.rint(y), rint(y)) 18 | 19 | if __name__ == "__main__": 20 | run_local_tests() 21 | -------------------------------------------------------------------------------- /test/numpy_lib/test_sum.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import parakeet 3 | from parakeet.testing_helpers import expect, run_local_tests, expect_each 4 | 5 | 6 | m = 5 7 | n = 3 8 | float_mat = np.random.random((m,n)) 9 | int_mat = float_mat.astype('int16') 10 | bool_mat = int_mat > 0 11 | matrices = [float_mat, int_mat, bool_mat] 12 | 13 | def each_sum(X): 14 | return parakeet.each(np.sum, X) 15 | 16 | def test_each_sum(): 17 | expect_each(each_sum, lambda X: np.sum(X, axis=1), matrices) 18 | 19 | def sum_cols(X): 20 | return np.sum(X, axis = 0) 21 | 22 | def test_col_sum(): 23 | expect_each(sum_cols, lambda X: np.sum(X, axis=0), matrices) 24 | 25 | def sum_rows(X): 26 | return np.sum(X, axis = 1) 27 | 28 | def test_sum_rows(): 29 | expect_each(sum_rows, lambda X: np.sum(X, axis=1), matrices) 30 | 31 | def test_sum_elts(): 32 | expect_each(np.sum, np.sum, matrices) 33 | 34 | if __name__ == '__main__': 35 | run_local_tests() 36 | -------------------------------------------------------------------------------- /test/numpy_lib/test_transcendental.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy as np 3 | import parakeet 4 | from parakeet.testing_helpers import run_local_tests, expect_each 5 | 6 | xs = [0.1, 0.5, 2.0] 7 | 8 | def test_sin(): 9 | expect_each(parakeet.sin, np.sin, xs) 10 | expect_each(math.sin, math.sin, xs) 11 | expect_each(np.sin, np.sin, xs) 12 | 13 | 14 | def test_parakeet_sinh(): 15 | expect_each(parakeet.sinh, np.sinh, xs) 16 | expect_each(math.sinh, np.sinh, xs) 17 | expect_each(np.sinh, np.sinh, xs) 18 | 19 | 20 | def test_cos(): 21 | expect_each(parakeet.cos, np.cos, xs) 22 | expect_each(math.cos, np.cos, xs) 23 | expect_each(np.cos, np.cos, xs) 24 | 25 | def test_cosh(): 26 | expect_each(parakeet.cosh, np.cosh, xs) 27 | expect_each(math.cosh, np.cosh, xs) 28 | expect_each(np.cosh, np.cosh, xs) 29 | 30 | def test_tan(): 31 | expect_each(parakeet.tan, np.tan, xs) 32 | expect_each(math.tan, np.tan, xs) 33 | expect_each(np.tan, np.tan, xs) 34 | 35 | def test_tanh(): 36 | expect_each(parakeet.tanh, np.tanh, xs) 37 | expect_each(math.tanh, np.tanh, xs) 38 | expect_each(np.tanh, np.tanh, xs) 39 | 40 | def test_log(): 41 | expect_each(parakeet.log, np.log, xs) 42 | expect_each(math.log, np.log, xs) 43 | expect_each(np.log, np.log, xs) 44 | 45 | def test_log10(): 46 | expect_each(parakeet.log10, np.log10, xs) 47 | expect_each(math.log10, np.log10, xs) 48 | expect_each(np.log10, np.log10, xs) 49 | 50 | def test_exp(): 51 | expect_each(parakeet.exp, np.exp, xs) 52 | expect_each(math.exp, np.exp, xs) 53 | expect_each(np.exp, np.exp, xs) 54 | 55 | if __name__ == '__main__': 56 | run_local_tests() 57 | -------------------------------------------------------------------------------- /test/numpy_lib/test_ufunc_math_binary.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet.testing_helpers import run_local_tests, expect 4 | 5 | 6 | int_vec = np.array([2,3]) 7 | int_mat = np.array([int_vec, int_vec]) 8 | 9 | bool_vec = np.array([True, True]) 10 | bool_mat = np.array([bool_vec, bool_vec]) 11 | 12 | float32_vec = np.array([1.0, 2.0], dtype='float32') 13 | float32_mat = np.array([float32_vec, float32_vec]) 14 | 15 | float64_vec = np.array([1.0, 10.0]) 16 | float64_mat = np.array([float64_vec, float64_vec]) 17 | 18 | vecs = [int_vec, bool_vec, float32_vec, float64_vec] 19 | mats = [int_mat, bool_mat, float32_mat, float64_mat] 20 | 21 | def binary(fn): 22 | for x in mats: 23 | for y in mats: 24 | expect(fn, [x,y], fn(x,y), x.dtype) 25 | 26 | def test_add(): 27 | binary(np.add) 28 | 29 | def test_subtract(): 30 | binary(np.subtract) 31 | 32 | def test_multiply(): 33 | binary(np.multiply) 34 | 35 | def test_divide(): 36 | binary(np.divide) 37 | 38 | def test_logaddexp(): 39 | binary(np.logaddexp) 40 | 41 | def test_logaddexp2(): 42 | binary(np.logaddexp2) 43 | 44 | def test_true_divide(): 45 | binary(np.true_divide) 46 | 47 | def test_floor_divide(): 48 | binary(np.floor_divide) 49 | def test_power(): 50 | binary(np.power) 51 | 52 | def test_remainder(): 53 | binary(np.remainder) 54 | 55 | def test_mod(): 56 | binary(np.mod) 57 | 58 | def test_fmod(): 59 | binary(np.fmod) 60 | 61 | 62 | if __name__ == '__main__': 63 | run_local_tests() 64 | 65 | -------------------------------------------------------------------------------- /test/numpy_lib/test_ufunc_math_unary.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | from parakeet.testing_helpers import run_local_tests, expect 5 | 6 | int_vec = np.array([2,3]) 7 | int_mat = np.array([int_vec, int_vec]) 8 | 9 | bool_vec = np.array([True, True]) 10 | bool_mat = np.array([bool_vec, bool_vec]) 11 | 12 | float32_vec = np.array([1.0, 2.0], dtype='float32') 13 | float32_mat = np.array([float32_vec, float32_vec]) 14 | 15 | float64_vec = np.array([1.0, 10.0]) 16 | float64_mat = np.array([float64_vec, float64_vec]) 17 | 18 | vecs = [int_vec, bool_vec, float32_vec, float64_vec] 19 | mats = [int_mat, bool_mat, float32_mat, float64_mat] 20 | 21 | 22 | def unary(fn): 23 | for x in mats: 24 | try: 25 | expected = fn(x) 26 | except: 27 | expected = fn(x.astype('int')) 28 | if expected.dtype == 'float16': 29 | expected = fn(x.astype('int')) 30 | expect(fn, [x], expected, fn.__name__ + "-" + str(x.dtype) + str(len(x.shape))) 31 | 32 | def test_negative(): 33 | unary(np.negative) 34 | 35 | def test_absolute(): 36 | unary(np.absolute) 37 | 38 | def test_rint(): 39 | unary(np.rint) 40 | 41 | def test_sign(): 42 | unary(np.sign) 43 | 44 | def test_conj(): 45 | unary(np.conj) 46 | 47 | def test_exp(): 48 | unary(np.exp) 49 | 50 | def test_exp2(): 51 | unary(np.exp2) 52 | 53 | def test_log(): 54 | unary(np.log) 55 | 56 | def test_log2(): 57 | unary(np.log2) 58 | 59 | def test_log10(): 60 | unary(np.log10) 61 | 62 | def test_expm1(): 63 | unary(np.expm1) 64 | 65 | def test_log1p(): 66 | unary(np.log1p) 67 | 68 | def test_sqrt(): 69 | unary(np.sqrt) 70 | 71 | def test_square(): 72 | unary(np.square) 73 | 74 | def test_reciprocal(): 75 | unary(np.reciprocal) 76 | 77 | def test_ones_like(): 78 | unary(np.ones_like) 79 | -------------------------------------------------------------------------------- /test/numpy_lib/test_ufunc_trig.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from parakeet.testing_helpers import run_local_tests, expect 4 | 5 | 6 | int_array = np.array([0,1]) 7 | bool_array = np.array([False,True]) 8 | float_array = np.array([0.1, 0.2]) 9 | arrays = [int_array, bool_array, float_array] 10 | 11 | def unary(fn, data = None): 12 | for x in (arrays if data is None else data): 13 | expect(fn, [x], fn(x)) 14 | 15 | def binary(fn): 16 | for x in arrays: 17 | for y in arrays: 18 | expect(fn, [x,y], fn(x,y)) 19 | 20 | def test_sin(): 21 | unary(np.sin) 22 | 23 | def test_cos(): 24 | unary(np.cos) 25 | 26 | def test_tan(): 27 | unary(np.tan) 28 | 29 | def test_arcsin(): 30 | unary(np.arcsin) 31 | 32 | def test_arccos(): 33 | unary(np.arccos) 34 | 35 | def test_arctan(): 36 | unary(np.arctan) 37 | 38 | def test_arctan2(): 39 | binary(np.arctan2) 40 | 41 | 42 | def test_sinh(): 43 | unary(np.sinh) 44 | 45 | def test_cosh(): 46 | unary(np.cosh) 47 | 48 | def test_tanh(): 49 | unary(np.tanh) 50 | 51 | def test_arcsinh(): 52 | unary(np.arcsinh) 53 | 54 | def test_arccosh(): 55 | unary(np.arccosh, data = np.array([2.0, 3.0])) 56 | 57 | def test_arctanh(): 58 | unary(np.arctanh, data = np.array([0.2, 0.3])) 59 | 60 | def test_deg2rad(): 61 | unary(np.deg2rad) 62 | 63 | def test_rad2deg(): 64 | unary(np.rad2deg) 65 | 66 | #def test_hypot(): 67 | # binary(np.hypot) 68 | 69 | if __name__ == '__main__': 70 | run_local_tests() 71 | --------------------------------------------------------------------------------