def test(): import os dir_name = os.path.dirname(os.path.abspath(__file__)) test_name = os.path.basename(dir_name) fort_file = os.path.join(dir_name, f"{test_name}.f03") build_dir = os.path.join(dir_name, f"fmodpy_{test_name}") print(f" {test_name}..", end=" ", flush=True) import fmodpy fort = fmodpy.fimport(fort_file, build_dir=build_dir, output_dir=dir_name, verbose=False, wrap=True, rebuild=True, show_warnings=False) # --------------------------------------------------------------- # Begin specific testing code. import numpy as np a = np.array([True, False, True, False, True, False, True, False], dtype=bool) temp = np.asarray(a, dtype='int32') out = temp.copy() assert (all(out == fort.test_simple_logical(temp, b=out, c=False))) assert (not any(fort.test_simple_logical(temp, b=out, c=True))) # End specific testing code. # --------------------------------------------------------------- print("passed", flush=True)
def test(): import os dir_name = os.path.dirname(os.path.abspath(__file__)) test_name = os.path.basename(dir_name) fort_file = os.path.join(dir_name, f"test_{test_name}.f03") build_dir = os.path.join(dir_name, f"fmodpy_{test_name}") print(f" {test_name}..", end=" ", flush=True) import fmodpy fort = fmodpy.fimport(fort_file, build_dir=build_dir, output_dir=dir_name, verbose=False, wrap=True, rebuild=True, show_warnings=False) # --------------------------------------------------------------- # Begin specific testing code. import ctypes import numpy as np a = np.array([True, False, True, False, True, False, True, False], dtype="int32") out = a.copy().astype(ctypes.c_bool) # Construct the answers (that are expected). b12 = np.array([(i + 1) % 3 == 0 for i in range(len(a))]) b3 = np.array([(i + 1) % 2 == 0 for i in range(len(a))]) assert (all(b12 == fort.test_simple_logical(a, b=out))) assert (all(b12 == fort.test_simple_logical(a, b=out, c=False))) assert (all(b3 == fort.test_simple_logical(a, b=out, c=True))) # End specific testing code. # --------------------------------------------------------------- print("passed", flush=True) import shutil shutil.rmtree(os.path.join(dir_name, f"test_{test_name}"))
class BoxMesh(WeightedApproximator): meshes = fmodpy.fimport( os.path.join(CWD,"meshes.f90"), output_directory=CWD, autocompile_extra_files=True) error_tolerance = 0.0 # Fit a set of points def _fit(self, points): from util.math import is_none # Sort points by their distance from the center of the data. center = (np.max(points, axis=0) - np.min(points, axis=0)) / 2 dists = np.linalg.norm(points - center, axis=1) indices = np.argsort(dists) if not is_none(self.y): self.y = [self.y[i] for i in indices] # Get points in a specific order. self.points = np.asarray(points[indices].T, order="F") self.box_sizes = np.ones((self.points.shape[0]*2,self.points.shape[1]), dtype=np.float64, order="F") * -1 self.meshes.build_ibm(self.points, self.box_sizes) # Generate a prediction for a new point def _predict(self, xs): to_predict = np.asarray(xs.T, order="F") all_weights = np.zeros((to_predict.shape[1], self.points.shape[1]), dtype=np.float64, order="F") self.meshes.eval_box_mesh(self.points, self.box_sizes, to_predict, all_weights) idx = np.arange(self.points.shape[1]) indices = [] weights = [] # Normalize the weights (so they are convex). for i in range(len(all_weights)): to_keep = idx[all_weights[i,:] > 0] indices.append( to_keep ) weights.append( all_weights[i,to_keep] ) return indices, weights
def test(): import os dir_name = os.path.dirname(os.path.abspath(__file__)) test_name = os.path.basename(dir_name) fort_file = os.path.join(dir_name, f"test_{test_name}.f03") build_dir = os.path.join(dir_name, f"fmodpy_{test_name}") print(f" {test_name}..", end=" ", flush=True) import fmodpy fort = fmodpy.fimport(fort_file, build_dir=build_dir, output_dir=dir_name, verbose=False, wrap=True, rebuild=True, show_warnings=False) # --------------------------------------------------------------- # Begin specific testing code. import ctypes import numpy as np a = np.array(list(map(ord,['1', '0', '1', '0', '1', '0', '1', '0'])), dtype=ctypes.c_char, order='F') out = a.copy() # Check for successful copy. result = fort.test_simple_character(a, b=out, c=ord('1')) assert(all(result.view('uint8') == a.view('uint8'))) # Check for successful overwrite. result = fort.test_simple_character(a, b=out, c=ord('0')) assert(all(result.view('uint8') == [1, 2, 0, 1, 2, 0, 1, 2])) # End specific testing code. # --------------------------------------------------------------- print("passed", flush=True) import shutil shutil.rmtree(os.path.join(dir_name,f"test_{test_name}"))
def __init__(self): self.modified_shepard = fmodpy.fimport(os.path.join( CWD, "modified_shepard.f95"), output_directory=CWD) self.shepmod = self.modified_shepard.shepmod self.shepmodval = self.modified_shepard.shepmodval self.ierrors = {} self.x = self.rw = None
def __init__(self): # Get the source fortran code module path_to_src = os.path.join(CWD, "voronoi.f90") # Compile the fortran source (with OpenMP for acceleration) self.voronoi = fmodpy.fimport( path_to_src, output_directory=CWD, f_compiler_options=["-fPIC", "-O3", "-fopenmp"], module_link_args=["-lgfortran", "-fopenmp"])
def __init__(self): self.linear_shepard = fmodpy.fimport( os.path.join(CWD,"linear_shepard.f95"), module_link_args=["-lblas","-llapack","-lgfortran"], output_directory=CWD, autocompile_extra_files=True) self.lshep = self.linear_shepard.lshep self.lshepval = self.linear_shepard.lshepval self.ierrors = {} self.x = self.f = self.a = self.rw = None
def ortho_basis(vec_iterator, num_bases=None, steps=float('inf'), parallel=False): import fmodpy path_to_src = os.path.join(CWD,"fort_stats.f90") basis_update = fmodpy.fimport(path_to_src, output_directory=CWD).basis_update # Determine the functions being used based on parallelism. if not parallel: from numpy import zeros from util.parallel import builtin_map as map else: from util.parallel import map, killall from util.parallel import shared_array as zeros # Get the first vector from the iterator and store as the first basis. for vec in vec_iterator: break # Store the "dimension" dim = len(vec) # Automatically set the number of bases if not provided. if type(num_bases) == type(None): num_bases = dim else: num_bases = min(dim, num_bases) bases_shape = (num_bases, len(vec)) # Create global arrays that are safe for multiprocessing (without copies) if parallel: global _bases, _lengths, _counts _bases = zeros(bases_shape) _lengths = zeros((num_bases,)) _counts = zeros((num_bases,)) # Store the first basis vector (the vector that was pulled out). _bases[0,:] = vec _counts[0] = 1.0 _lengths[0] = np.sqrt(np.sum(vec**2)) # Given a vec, update the basis vectors iteratively according to # the provided vector (ignore race conditions). def update_bases(vec): for basis in range(num_bases): _counts[basis] += 1 # Compute the basis update (with fortran code that's faster) _,_,vec_length = basis_update(_counts[basis], _bases[basis], vec) _lengths[basis] += vec_length / _counts[basis] # Perform rounds of updates using a (parallel) map operation. step = 1 for _ in map(update_bases, vec_iterator): step += 1 if step >= steps: break # Kill all hanging processes (because we may not have exausted the iterator). if parallel: killall() # Identify those bases that were actually computed, reduce to them. to_keep = _counts > 0 bases = _bases[to_keep] lengths = _lengths[to_keep] # Normalize the bases and lengths (so that users can understand relative weight). bases = (bases.T / np.sqrt(np.sum(bases**2, axis=1))).T lengths /= np.sum(lengths) # Delete the temporary global variables (used for parallelism) if parallel: del _bases, _lengths, _counts return bases, lengths
def test(): import os dir_name = os.path.dirname(os.path.abspath(__file__)) test_name = os.path.basename(dir_name) fort_file = os.path.join(dir_name, f"test_{test_name}.f03") build_dir = os.path.join(dir_name, f"fmodpy_{test_name}") print(f" {test_name}..", end=" ", flush=True) import fmodpy fort = fmodpy.fimport(fort_file, build_dir=build_dir, rebuild=True, wrap=False, verbose=True, output_dir=dir_name) # --------------------------------------------------------------- # Begin specific testing code. import numpy as np n = 10 array_in = np.asarray(np.arange(n), dtype=np.complex256, order='F') array_out = np.zeros(n//2 - 1, dtype=np.complex256, order='F') sing_in = complex(7,0) out = fort.test_standard(sing_in, array_in, array_out) # Test the standard functionality. assert(out[0] == 8), out[0] assert(all(out[1] == [0,1,2,3])) assert(all(out[2] == [1,2,3,4])) assert(np.all(out[3] == [[2,3,4,5], [3,4,5,6], [4,5,6,7]])) assert(out[4] == None) # Test the extended functionality. out = fort.test_extended(4) assert(out[0] == None) assert(out[1] == None) assert(all(out[2] == [4, 3, 2, 1])) # WARNING: In the current code, the memory associated with out[2a] # will be freed by Fortran on subsequent calls to the # function "test_extended". Copy for object permanance. out2 = fort.test_extended(10, known_opt_array_out=True) assert(all(out2[0] == [1,2,3])) assert(out2[1] == None) assert(all(out2[2] == list(reversed(range(11)[1:])))) # WARNING: Similar to before, the memory at out2[0] and out2[2] # will be freed by Fortran on subsequent calls to # "test_extended". Copies should be made for permanence. out3 = fort.test_extended(6, opt_alloc_array_out=True) assert(out3[0] == None) assert(all(out3[1] == [3,2,1])) assert(all(out3[2] == list(reversed(range(7)[1:])))) # End specific testing code. # --------------------------------------------------------------- print("passed", flush=True) import shutil shutil.rmtree(os.path.join(dir_name,f"test_{test_name}"))
def test(): import os import shutil dir_name = os.path.dirname(os.path.abspath(__file__)) test_name = os.path.basename(dir_name) build_dir = os.path.join(dir_name, f"fmodpy_{test_name}") import fmodpy # --------------------------------------------------------------- # Begin specific testing code. fort_file = os.path.join(dir_name, f"subroutine_with_type.f90") print(f" {os.path.basename(fort_file)}..", end=" ", flush=True) fort = fmodpy.fimport( fort_file, build_dir=build_dir, output_dir=dir_name, rebuild=True, ) assert (fort.one_up(1) == fort.FANCY(shirt=2.0, pants=3)), "Failed!" print("passed", flush=True) shutil.rmtree(os.path.join(dir_name, fort_file[:-4]))
# Allow OpenMP to create nested threads. from multiprocessing import cpu_count # Set OpenMP variables to allow for greatest parallelism when building tree. if "OMP_NUM_THREADS" not in os.environ: os.environ["OMP_NUM_THREADS"] = str(cpu_count()) if "OMP_MAX_ACTIVE_LEVELS" not in os.environ: os.environ["OMP_MAX_ACTIVE_LEVELS"] = str( int(np.ceil(np.log2(cpu_count())))) if "OMP_NESTED" not in os.environ: os.environ["OMP_NESTED"] = "TRUE" # Import the Fortran utilities. PATH_TO_BT_R64 = os.path.join(PATH_TO_HERE, "ball_tree_r64.f90") ball_tree_r64 = fmodpy.fimport(PATH_TO_BT_R64, output_directory=PATH_TO_HERE, autocompile_extra_files=True, omp=True) PATH_TO_BT_I8 = os.path.join(PATH_TO_HERE, "ball_tree_i8.f90") ball_tree_i8 = fmodpy.fimport(PATH_TO_BT_I8, output_directory=PATH_TO_HERE, autocompile_extra_files=True, omp=True) PATH_TO_PRUNE = os.path.join(PATH_TO_HERE, "prune.f90") prune = fmodpy.fimport(PATH_TO_PRUNE, output_directory=PATH_TO_HERE, autocompile_extra_files=True) PATH_TO_SORT = os.path.join(PATH_TO_HERE, "fast_sort.f90") fast_sort = fmodpy.fimport(PATH_TO_SORT, output_directory=PATH_TO_HERE, autocompile_extra_files=True) PATH_TO_SELECT = os.path.join(PATH_TO_HERE, "fast_select.f90")
import numpy as np import fmodpy import time # Update the link arguments to include blas and lapack module_link_args = ["-lblas", "-llapack", "-lgfortran"] meshes = fmodpy.fimport("meshes.f90", requested_funcs=[ "length", "most_central_point", "linear_basis_value", "train_vm", "predict_vm", "train_mbm", "train_ibm", "predict_box_mesh" ], module_link_args=module_link_args) # ,working_directory="fmodpy_meshes" # ,force_rebuild=False # ,verbose=True) ERROR_TOLERANCE = 0.0 def run_tests(): # length vector = np.array([1, 2, 3, 4, 5, 6], dtype=np.float64) print("length") print(" default value") print(" meshes.length(vector): ", meshes.length(vector)) for norm in range(1, 4): true_length = np.sum(vector**norm)**(1 / norm) print(" norm: ", norm) print(" meshes.length(vector, norm): ", meshes.length(vector, norm)) print(" True length with 'norm': ", true_length)
import numpy as np import fmodpy fs = fmodpy.fimport("fast_select.f90", autocompile_extra_files=True) # Test function for "bubble_median" function. def _test_bubble_sort(): for i in range(1000): for j in range(1, 10): v = np.random.random(size=(j, )) fs.bubble_sort(v) try: assert (sum(v - np.array(sorted(v))) == 0) except: print("ERROR:", v) # Test the function "partition". def _test_partition(): # Case 1 v = np.array([3, 1, 1, 3, 4, 5], dtype=float) out = fs.partition(v, 6, 2) assert (out == 5) assert (sum(v - np.array([3, 1, 1, 3, 4, 5], dtype=float)) == 0) # Case 2 v = np.array([3, 1, 1, 3, 4, 5], dtype=float) out = fs.partition(v, 1, 2) assert (out == 2) assert (sum(v - np.array([1, 1, 5, 3, 4, 3], dtype=float)) == 0) # Case 3
# Compile and build the fekete point generation code. import os, fmodpy CWD = os.path.dirname(os.path.abspath(__file__)) fp_mod = fmodpy.fimport(os.path.join(CWD,"fekete.f90"), module_link_args=["-lblas","-llapack"], output_directory=CWD) # Given an "n", construct the 1D Chebyshev-Guass-Lobatto nodes # (equally spaced on a unit semicircle). def chebyshev(n, d=1, sample=None): from numpy import array, cos, pi x = [] for k in range(1,n+1): x.append(cos( (2*k - 1) / (2*n) * pi )) # Reormalize the points to be in the range [0,1]. x = (array(x) + 1) / 2 # Create a tensor product to fill the desired dimension. return mesh(x, multiplier=d, sample=sample) # Create a tensor mesh of "len(nodes) * multiplier" dimension of all # lists provided inside of "nodes". If "sample" is provided, then a # random sample of size "sample" is drawn from the mesh. def mesh(*nodes, multiplier=1, sample=None): from numpy import vstack, meshgrid if sample: # Compute the multiplicative product of a list of integers. # Make sure everything is PYTHON INTEGER to avoid overflow. def product(integers): p = int(integers[0])
import fmodpy vmesh = fmodpy.fimport("voronoi_mesh.f90") import numpy as np class VoronoiMesh: # Fit a set of points def fit(self, points, values): self.points = np.asarray(points.T.copy(), order="F") self.values = np.asarray(values.copy(), order="F") # Wrapper for 'predict' that returns a single value for a single # prediction, or an array of values for an array of predictions def __call__(self, x: np.ndarray, *args, **kwargs): single_response = len(x.shape) == 1 if single_response: x = np.array([x]) if len(x.shape) != 2: raise (Exception("ERROR: Bad input shape.")) response = np.asarray(self.predict(x, *args, **kwargs), dtype=float) # Return the response values return response[0] if single_response else response # Generate a prediction for a new point def predict(self, xs): to_predict = np.asarray(xs.T, order="F") predictions = np.ones((len(xs), )) vmesh.voronoi_mesh(self.points, self.values, to_predict, predictions) return predictions
def test(): import os dir_name = os.path.dirname(os.path.abspath(__file__)) test_name = os.path.basename(dir_name) fort_file = os.path.join(dir_name, f"test_{test_name}.f03") build_dir = os.path.join(dir_name, f"fmodpy_{test_name}") print(f" {test_name}..", end=" ", flush=True) import fmodpy fort = fmodpy.fimport( fort_file, build_dir=build_dir, output_dir=dir_name, rebuild=True, ) # --------------------------------------------------------------- # Begin specific testing code. import numpy as np n = 10 array_test = np.asarray(np.arange(n), dtype="float32", order='F') # Assign some internal variables. # a_pub (float) fort.addition.a_pub = 1.5 assert (fort.addition.a_pub == 1.5) fort.addition.a_pub = 2.5 assert (fort.addition.a_pub == 2.5) # b_pub (integer) fort.addition.b_pub = 2 assert (fort.addition.b_pub == 2) fort.addition.b_pub = 1 assert (fort.addition.b_pub == 1) # Verify that the public subtraction routine works correctly. assert (3.5 == fort.addition.add_ab()) # a_vec_pub (real vector of size 10) import numpy as np a = np.asarray(np.random.random(size=(10, )), dtype=np.float32) # testing using the "get" before assignment fort.addition.a_vec_pub # test assignment. fort.addition.a_vec_pub = a assert (all(a == fort.addition.a_vec_pub)) # try assigning with a vector that is too small.. a = np.asarray(np.random.random(size=(8, )), dtype=np.float32) fort.addition.a_vec_pub = a assert (all(a == fort.addition.a_vec_pub[:len(a)])) # try assigning with a vector that is too big, might seg-fault.. a = np.asarray(np.random.random(size=(80, )), dtype=np.float32) fort.addition.a_vec_pub = a assert (all(a[:len(fort.addition.a_vec_pub)] == fort.addition.a_vec_pub)) # reassign a normal value. a = np.asarray(np.random.random(size=(10, )), dtype=np.float32) fort.addition.a_vec_pub = a # Make sure the vector is correctly negated internally and returned. result = fort.addition.sub_vecs() assert (all(result == -a)) # b_vec_pub (real vector of size 10) b = np.asarray(np.arange(4), dtype=np.float32) # testing using the "get" before assignment # test assignment. fort.addition.b_vec_pub = b assert (all(b == fort.addition.b_vec_pub)) # try assigning over top with a new vector b = np.asarray(np.arange(10), dtype=np.float32) fort.addition.b_vec_pub = b assert (all(b == fort.addition.b_vec_pub)) # Make sure the vectors are correctly subtracted internally and returned. result = fort.addition.sub_vecs() assert (all(b == result + a)) # TODO: check size of array, if large enough, warn about copy in SETTER # TODO: provide some protection against incorrectly sized array assignments # End specific testing code. # --------------------------------------------------------------- print("passed", flush=True) import shutil shutil.rmtree(os.path.join(dir_name, f"test_{test_name}"))