| Viewing file:  extending_distributions.py (1.99 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
r"""Building the required library in this example requires a source distribution
 of NumPy or clone of the NumPy git repository since distributions.c is not
 included in binary distributions.
 
 On *nix, execute in numpy/random/src/distributions
 
 export ${PYTHON_VERSION}=3.8 # Python version
 export PYTHON_INCLUDE=#path to Python's include folder, usually \
 ${PYTHON_HOME}/include/python${PYTHON_VERSION}m
 export NUMPY_INCLUDE=#path to numpy's include folder, usually \
 ${PYTHON_HOME}/lib/python${PYTHON_VERSION}/site-packages/numpy/core/include
 gcc -shared -o libdistributions.so -fPIC distributions.c \
 -I${NUMPY_INCLUDE} -I${PYTHON_INCLUDE}
 mv libdistributions.so ../../_examples/numba/
 
 On Windows
 
 rem PYTHON_HOME and PYTHON_VERSION are setup dependent, this is an example
 set PYTHON_HOME=c:\Anaconda
 set PYTHON_VERSION=38
 cl.exe /LD .\distributions.c -DDLL_EXPORT \
 -I%PYTHON_HOME%\lib\site-packages\numpy\core\include \
 -I%PYTHON_HOME%\include %PYTHON_HOME%\libs\python%PYTHON_VERSION%.lib
 move distributions.dll ../../_examples/numba/
 """
 import os
 
 import numba as nb
 import numpy as np
 from cffi import FFI
 
 from numpy.random import PCG64
 
 ffi = FFI()
 if os.path.exists('./distributions.dll'):
 lib = ffi.dlopen('./distributions.dll')
 elif os.path.exists('./libdistributions.so'):
 lib = ffi.dlopen('./libdistributions.so')
 else:
 raise RuntimeError('Required DLL/so file was not found.')
 
 ffi.cdef("""
 double random_standard_normal(void *bitgen_state);
 """)
 x = PCG64()
 xffi = x.cffi
 bit_generator = xffi.bit_generator
 
 random_standard_normal = lib.random_standard_normal
 
 
 def normals(n, bit_generator):
 out = np.empty(n)
 for i in range(n):
 out[i] = random_standard_normal(bit_generator)
 return out
 
 
 normalsj = nb.jit(normals, nopython=True)
 
 # Numba requires a memory address for void *
 # Can also get address from x.ctypes.bit_generator.value
 bit_generator_address = int(ffi.cast('uintptr_t', bit_generator))
 
 norm = normalsj(1000, bit_generator_address)
 print(norm[:12])
 
 |