Exemplo n.º 1
0
def array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0):
    # We're going to ignore this for now
    # if(subok is not False):
    #     raise NotImplementedError
    if(order is not None and order is not 'K' and order is not 'C'):
        raise NotImplementedError

    # If it's not a numpy or afnumpy array first create a numpy array from it
    if(not isinstance(object, ndarray) and
       not isinstance(object, numpy.ndarray)):
        object = numpy.array(object, dtype=dtype, copy=copy, order=order, subok=subok, ndmin=ndmin)

    shape = object.shape
    while(ndmin > len(shape)):
        shape = (1,)+shape
    if(dtype is None):
        dtype = object.dtype
    if(isinstance(object, ndarray)):
        if(copy):
            s = arrayfire.cast(object.d_array.copy(), pu.typemap(dtype))
        else:
            s = arrayfire.cast(object.d_array, pu.typemap(dtype))
        a = ndarray(shape, dtype=dtype, af_array=s)
        a._eval()
        return a
    elif(isinstance(object, numpy.ndarray)):
        return ndarray(shape, dtype=dtype, buffer=numpy.ascontiguousarray(object.astype(dtype, copy=copy)))
    else:
        raise AssertionError
Exemplo n.º 2
0
def deconvolve_single_gpu(vol_a: Volume, n: int, psf_a: np.ndarray) -> Volume:
    """
    Perform joint Richardson-Lucy deconvolution on two volumes using two specified PSFs on the GPU

    :param vol_a: The first volume
    :param n: The number of Richardson-Lucy iterations
    :param psf_a: The PSF for the first volume
    :return: The fused RL deconvolution
    """
    from functools import partial
    from dispim.metrics import DECONV_MSE_DELTA
    import arrayfire as af

    print(vol_a.shape)

    view_a = vol_a.astype(np.float)

    psf_a = psf_a.astype(np.float) / np.sum(psf_a).astype(np.float)
    psf_Ai = psf_a[::-1, ::-1, ::-1]

    view_a = af.cast(af.from_ndarray(np.array(view_a)), af.Dtype.f32)

    psf_a = af.cast(af.from_ndarray(psf_a), af.Dtype.f32)
    psf_Ai = af.cast(af.from_ndarray(psf_Ai), af.Dtype.f32)

    estimate = view_a

    convolve = partial(af.fft_convolve3)

    with progressbar.ProgressBar(max_value=n, redirect_stderr=True) as bar:
        for _ in bar(range(n)):
            if metrack.is_tracked(DECONV_MSE_DELTA):
                prev = estimate
            estimate = estimate * convolve(
                view_a / (convolve(estimate, psf_a) + 1), psf_Ai)

            if metrack.is_tracked(DECONV_MSE_DELTA):
                metrack.append_metric(DECONV_MSE_DELTA,
                                      (_, float(np.mean(
                                          (prev - estimate)**2))))

    CURSOR_UP_ONE = '\x1b[1A'
    ERASE_LINE = '\x1b[2K'
    print(CURSOR_UP_ONE + ERASE_LINE + CURSOR_UP_ONE)

    logger.debug(
        f'Deconved min: {np.min(estimate)}, max: {np.max(estimate)}, has nan: {np.any(np.isnan(estimate))}'
    )

    result = estimate.to_ndarray()
    del estimate

    return Volume(result.astype(np.uint16),
                  inverted=False,
                  spacing=vol_a.spacing,
                  is_skewed=False)
Exemplo n.º 3
0
def array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0):
    # We're going to ignore this for now
    # if(subok is not False):
    #     raise NotImplementedError
    if (order is not None and order is not 'K' and order is not 'C'):
        raise NotImplementedError

    # If it's not a numpy or afnumpy array first create a numpy array from it
    if (not isinstance(object, ndarray)
            and not isinstance(object, numpy.ndarray)
            and not isinstance(object, arrayfire.array.Array)):
        object = numpy.array(object,
                             dtype=dtype,
                             copy=copy,
                             order=order,
                             subok=subok,
                             ndmin=ndmin)

    if isinstance(object, arrayfire.array.Array):
        shape = pu.c2f(object.dims())
    else:
        shape = object.shape
    while (ndmin > len(shape)):
        shape = (1, ) + shape
    if (dtype is None):
        if isinstance(object, arrayfire.array.Array):
            dtype = pu.typemap(object.dtype())
        else:
            dtype = object.dtype
    if (isinstance(object, ndarray)):
        if (copy):
            s = arrayfire.cast(object.d_array.copy(), pu.typemap(dtype))
        else:
            s = arrayfire.cast(object.d_array, pu.typemap(dtype))
        a = ndarray(shape, dtype=dtype, af_array=s)
        a._eval()
        return a
    elif (isinstance(object, arrayfire.array.Array)):
        if (copy):
            s = arrayfire.cast(object.copy(), pu.typemap(dtype))
        else:
            s = arrayfire.cast(object, pu.typemap(dtype))
        a = ndarray(shape, dtype=dtype, af_array=s)
        a._eval()
        return a
    elif (isinstance(object, numpy.ndarray)):
        return ndarray(shape,
                       dtype=dtype,
                       buffer=numpy.ascontiguousarray(
                           object.astype(dtype, copy=copy)))
    else:
        raise AssertionError
Exemplo n.º 4
0
def test_cast():
    a = afnumpy.random.rand(2, 3)
    # Check that device_ptr does not cause a copy
    assert a.d_array.device_ptr() == a.d_array.device_ptr()
    # Check that cast does not cause a copy
    assert arrayfire.cast(
        a.d_array, a.d_array.dtype()).device_ptr() == a.d_array.device_ptr()
Exemplo n.º 5
0
 def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True):
     if(order != 'K'):
         raise NotImplementedError('only order=K implemented')
     if(casting != 'unsafe'):
         raise NotImplementedError('only casting=unsafe implemented')
     if(copy == False and order == 'K' and dtype == self.dtype):
         return self
     s = arrayfire.cast(self.d_array, pu.typemap(dtype))
     a = ndarray(self.shape, dtype=dtype, af_array=s)
     a._eval()
     return a
Exemplo n.º 6
0
    def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True):
        if(self.d_array is not None):
            if(order != 'K'):
                raise NotImplementedError('only order=K implemented')
            if(casting != 'unsafe'):
                raise NotImplementedError('only casting=unsafe implemented')
            if(copy == False and order == 'K' and dtype == self.dtype):
                return self
#            s = self.d_array.astype(pu.typemap(dtype))
            s = arrayfire.cast(self.d_array, pu.typemap(dtype))
            return ndarray(self.shape, dtype=dtype, af_array=s)
        else:
            return array(self.h_array.astype(dtype, order, casting, subok, copy), dtype=dtype)
Exemplo n.º 7
0
 def astype(self,
            dtype,
            order='K',
            casting='unsafe',
            subok=True,
            copy=True):
     if (order != 'K'):
         raise NotImplementedError('only order=K implemented')
     if (casting != 'unsafe'):
         raise NotImplementedError('only casting=unsafe implemented')
     if (copy == False and order == 'K' and dtype == self.dtype):
         return self
     s = arrayfire.cast(self.d_array, pu.typemap(dtype))
     a = ndarray(self.shape, dtype=dtype, af_array=s)
     a._eval()
     return a
Exemplo n.º 8
0
    def initialize_magnetic_fields(self):

        if ('initialize_B' in dir(self.initialize)):

            B1, B2, B3 = self.initialize.initialize_B(self.q1_center,
                                                      self.q2_center,
                                                      self.params)

        # elif('initialize_A' in dir(self.initialize)):

        #     A1, A2, A3 = self.initialize.initialize_A(self.q1_center,
        #                                               self.q2_center,
        #                                               self.params
        #                                              )

        #     A1_hat = 2 * fft2(A1) / (self.N_q1 * self.N_q2)
        #     A2_hat = 2 * fft2(A2) / (self.N_q1 * self.N_q2)
        #     A3_hat = 2 * fft2(A3) / (self.N_q1 * self.N_q2)

        #     B1 =  ifft2(A3_hat * 1j * self.k_q2)
        #     B2 = -ifft2(A3_hat * 1j * self.k_q1)
        #     B3 =  ifft2(A2_hat * 1j * self.k_q1 - A1_hat * 1j * self.k_q2)

        elif ('initialize_A3_B3' in dir(self.initialize)):

            A3 = self.initialize.initialize_A3_B3(self.q1_center,
                                                  self.q2_center,
                                                  self.params)[0]

            A3_hat = fft2(A3)

            B1 = ifft2(A3_hat * 1j * self.k_q2)
            B2 = -ifft2(A3_hat * 1j * self.k_q1)

            B3 = self.initialize.initialize_A3_B3(self.q1_center,
                                                  self.q2_center,
                                                  self.params)[1]
            B3 = af.cast(B3, af.Dtype.c64)

        else:
            raise NotImplementedError(
                'Initialization method for magnetic fields not valid/found')

        af.eval(B1, B2, B3)
        return (B1, B2, B3)
Exemplo n.º 9
0
    def sum(self, s, axis):
        if self.dtype == numpy.bool:
            s = arrayfire.cast(s, pu.typemap(numpy.int64))
#            s = s.astype(pu.typemap(numpy.int64))
        return arrayfire.sum(s, dim=axis)
Exemplo n.º 10
0
c = a
c >>= 2
af.display(c)

af.display(a << b)
af.display(a << 2)
c = a
c <<= 2
af.display(c)

af.display(-a)
af.display(+a)
af.display(~a)
af.display(a)

af.display(af.cast(a, af.c32))
af.display(af.maxof(a, b))
af.display(af.minof(a, b))
af.display(af.rem(a, b))

a = af.randu(3, 3) - 0.5
b = af.randu(3, 3) - 0.5

af.display(af.abs(a))
af.display(af.arg(a))
af.display(af.sign(a))
af.display(af.round(a))
af.display(af.trunc(a))
af.display(af.floor(a))
af.display(af.ceil(a))
af.display(af.hypot(a, b))
Exemplo n.º 11
0
def simple_arith(verbose=False):
    display_func = _util.display_func(verbose)
    print_func = _util.print_func(verbose)

    a = af.randu(3, 3)
    b = af.constant(4, 3, 3)
    display_func(a)
    display_func(b)

    c = a + b
    d = a
    d += b

    display_func(c)
    display_func(d)
    display_func(a + 2)
    display_func(3 + a)

    c = a - b
    d = a
    d -= b

    display_func(c)
    display_func(d)
    display_func(a - 2)
    display_func(3 - a)

    c = a * b
    d = a
    d *= b

    display_func(c * 2)
    display_func(3 * d)
    display_func(a * 2)
    display_func(3 * a)

    c = a / b
    d = a
    d /= b

    display_func(c / 2.0)
    display_func(3.0 / d)
    display_func(a / 2)
    display_func(3 / a)

    c = a % b
    d = a
    d %= b

    display_func(c % 2.0)
    display_func(3.0 % d)
    display_func(a % 2)
    display_func(3 % a)

    c = a**b
    d = a
    d **= b

    display_func(c**2.0)
    display_func(3.0**d)
    display_func(a**2)
    display_func(3**a)

    display_func(a < b)
    display_func(a < 0.5)
    display_func(0.5 < a)

    display_func(a <= b)
    display_func(a <= 0.5)
    display_func(0.5 <= a)

    display_func(a > b)
    display_func(a > 0.5)
    display_func(0.5 > a)

    display_func(a >= b)
    display_func(a >= 0.5)
    display_func(0.5 >= a)

    display_func(a != b)
    display_func(a != 0.5)
    display_func(0.5 != a)

    display_func(a == b)
    display_func(a == 0.5)
    display_func(0.5 == a)

    a = af.randu(3, 3, dtype=af.Dtype.u32)
    b = af.constant(4, 3, 3, dtype=af.Dtype.u32)

    display_func(a & b)
    display_func(a & 2)
    c = a
    c &= 2
    display_func(c)

    display_func(a | b)
    display_func(a | 2)
    c = a
    c |= 2
    display_func(c)

    display_func(a >> b)
    display_func(a >> 2)
    c = a
    c >>= 2
    display_func(c)

    display_func(a << b)
    display_func(a << 2)
    c = a
    c <<= 2
    display_func(c)

    display_func(-a)
    display_func(+a)
    display_func(~a)
    display_func(a)

    display_func(af.cast(a, af.Dtype.c32))
    display_func(af.maxof(a, b))
    display_func(af.minof(a, b))
    display_func(af.rem(a, b))

    a = af.randu(3, 3) - 0.5
    b = af.randu(3, 3) - 0.5

    display_func(af.abs(a))
    display_func(af.arg(a))
    display_func(af.sign(a))
    display_func(af.round(a))
    display_func(af.trunc(a))
    display_func(af.floor(a))
    display_func(af.ceil(a))
    display_func(af.hypot(a, b))
    display_func(af.sin(a))
    display_func(af.cos(a))
    display_func(af.tan(a))
    display_func(af.asin(a))
    display_func(af.acos(a))
    display_func(af.atan(a))
    display_func(af.atan2(a, b))

    c = af.cplx(a)
    d = af.cplx(a, b)
    display_func(c)
    display_func(d)
    display_func(af.real(d))
    display_func(af.imag(d))
    display_func(af.conjg(d))

    display_func(af.sinh(a))
    display_func(af.cosh(a))
    display_func(af.tanh(a))
    display_func(af.asinh(a))
    display_func(af.acosh(a))
    display_func(af.atanh(a))

    a = af.abs(a)
    b = af.abs(b)

    display_func(af.root(a, b))
    display_func(af.pow(a, b))
    display_func(af.pow2(a))
    display_func(af.sigmoid(a))
    display_func(af.exp(a))
    display_func(af.expm1(a))
    display_func(af.erf(a))
    display_func(af.erfc(a))
    display_func(af.log(a))
    display_func(af.log1p(a))
    display_func(af.log10(a))
    display_func(af.log2(a))
    display_func(af.sqrt(a))
    display_func(af.cbrt(a))

    a = af.round(5 * af.randu(3, 3) - 1)
    b = af.round(5 * af.randu(3, 3) - 1)

    display_func(af.factorial(a))
    display_func(af.tgamma(a))
    display_func(af.lgamma(a))
    display_func(af.iszero(a))
    display_func(af.isinf(a / b))
    display_func(af.isnan(a / a))

    a = af.randu(5, 1)
    b = af.randu(1, 5)
    c = af.broadcast(lambda x, y: x + y, a, b)
    display_func(a)
    display_func(b)
    display_func(c)

    @af.broadcast
    def test_add(aa, bb):
        return aa + bb

    display_func(test_add(a, b))
Exemplo n.º 12
0
    def __init__(self, physical_system, performance_test_flag=False):
        """
        Constructor for the nonlinear_solver object. It takes the physical
        system object as an argument and uses it in intialization and
        evolution of the system in consideration. 

        Additionally, a performance test flag is also passed which when true,
        stores time which is consumed by each of the major solver routines.
        This proves particularly useful in analyzing performance bottlenecks 
        and obtaining benchmarks.
        
        Parameters:
        -----------

        physical_system: The defined physical system object which holds
                         all the simulation information such as the initial
                         conditions, and the domain info is passed as an
                         argument in defining an instance of the
                         nonlinear_solver. This system is then evolved, and
                         monitored using the various methods under the
                         nonlinear_solver class.
        """
        self.physical_system = physical_system

        # Holding Domain Info:
        self.q1_start, self.q1_end = physical_system.q1_start,\
                                     physical_system.q1_end
        self.q2_start, self.q2_end = physical_system.q2_start,\
                                     physical_system.q2_end
        self.p1_start, self.p1_end = physical_system.p1_start,\
                                     physical_system.p1_end
        self.p2_start, self.p2_end = physical_system.p2_start,\
                                     physical_system.p2_end
        self.p3_start, self.p3_end = physical_system.p3_start,\
                                     physical_system.p3_end

        # Holding Domain Resolution:
        self.N_q1, self.dq1 = physical_system.N_q1, physical_system.dq1
        self.N_q2, self.dq2 = physical_system.N_q2, physical_system.dq2
        self.N_p1, self.dp1 = physical_system.N_p1, physical_system.dp1
        self.N_p2, self.dp2 = physical_system.N_p2, physical_system.dp2
        self.N_p3, self.dp3 = physical_system.N_p3, physical_system.dp3

        # Getting number of ghost zones, and the boundary
        # conditions that are utilized:
        N_g_q = self.N_ghost_q = physical_system.N_ghost_q
        N_g_p = self.N_ghost_p = physical_system.N_ghost_p

        self.boundary_conditions = physical_system.boundary_conditions

        # Declaring the communicator:
        self._comm = PETSc.COMM_WORLD.tompi4py()
        if (self.physical_system.params.num_devices > 1):
            af.set_device(self._comm.rank %
                          self.physical_system.params.num_devices)

        # Getting number of species:
        self.N_species = len(physical_system.params.mass)

        # Having the mass and charge along axis 1:
        self.physical_system.params.mass  = \
            af.cast(af.moddims(af.to_array(physical_system.params.mass),
                               1, self.N_species
                              ),
                    af.Dtype.f64
                   )

        self.physical_system.params.charge  = \
            af.cast(af.moddims(af.to_array(physical_system.params.charge),
                               1, self.N_species
                              ),
                    af.Dtype.f64
                   )

        PETSc.Sys.Print('\nBackend Details for Nonlinear Solver:')

        # Printing the backend details for each rank/device/node:
        PETSc.Sys.syncPrint(
            indent('Rank ' + str(self._comm.rank) + ' of ' +
                   str(self._comm.size - 1)))
        PETSc.Sys.syncPrint(indent('On Node: ' + socket.gethostname()))
        PETSc.Sys.syncPrint(indent('Device Details:'))
        PETSc.Sys.syncPrint(indent(af.info_str(), 2))
        PETSc.Sys.syncPrint(
            indent('Device Bandwidth = ' + str(bandwidth_test(100)) +
                   ' GB / sec'))
        PETSc.Sys.syncPrint()
        PETSc.Sys.syncFlush()

        self.performance_test_flag = performance_test_flag

        # Initializing variables which are used to time the components of the solver:
        if (performance_test_flag == True):

            self.time_ts = 0

            self.time_interp2 = 0
            self.time_sourcets = 0

            self.time_fvm_solver = 0
            self.time_reconstruct = 0
            self.time_riemann = 0

            self.time_fieldstep = 0
            self.time_interp3 = 0

            self.time_apply_bcs_f = 0
            self.time_communicate_f = 0

        petsc_bc_in_q1 = 'ghosted'
        petsc_bc_in_q2 = 'ghosted'

        # Only for periodic boundary conditions or shearing-box boundary conditions
        # do the boundary conditions passed to the DA need to be changed. PETSc
        # automatically handles the application of periodic boundary conditions when
        # running in parallel. For shearing box boundary conditions, an interpolation
        # operation needs to be applied on top of the periodic boundary conditions.
        # In all other cases, ghosted boundaries are used.

        if (self.boundary_conditions.in_q1_left == 'periodic'
                or self.boundary_conditions.in_q1_left == 'shearing-box'):
            petsc_bc_in_q1 = 'periodic'

        if (self.boundary_conditions.in_q2_bottom == 'periodic'
                or self.boundary_conditions.in_q2_bottom == 'shearing-box'):
            petsc_bc_in_q2 = 'periodic'

        if (self.boundary_conditions.in_q1_left == 'periodic'):
            try:
                assert (self.boundary_conditions.in_q1_right == 'periodic')
            except:
                raise Exception(
                    'Periodic boundary conditions need to be applied to \
                                 both the boundaries of a particular axis')

        if (self.boundary_conditions.in_q1_left == 'shearing-box'):
            try:
                assert (self.boundary_conditions.in_q1_right == 'shearing-box')
            except:
                raise Exception(
                    'Shearing box boundary conditions need to be applied to \
                                 both the boundaries of a particular axis')

        if (self.boundary_conditions.in_q2_bottom == 'periodic'):
            try:
                assert (self.boundary_conditions.in_q2_top == 'periodic')
            except:
                raise Exception(
                    'Periodic boundary conditions need to be applied to \
                                 both the boundaries of a particular axis')

        if (self.boundary_conditions.in_q2_bottom == 'shearing-box'):
            try:
                assert (self.boundary_conditions.in_q2_top == 'shearing-box')
            except:
                raise Exception(
                    'Shearing box boundary conditions need to be applied to \
                                 both the boundaries of a particular axis')

        nproc_in_q1 = PETSc.DECIDE
        nproc_in_q2 = PETSc.DECIDE

        # Since shearing boundary conditions require interpolations which are non-local:
        if (self.boundary_conditions.in_q2_bottom == 'shearing-box'):
            nproc_in_q1 = 1

        if (self.boundary_conditions.in_q1_left == 'shearing-box'):
            nproc_in_q2 = 1

        # DMDA is a data structure to handle a distributed structure
        # grid and its related core algorithms. It stores metadata of
        # how the grid is partitioned when run in parallel which is
        # utilized by the various methods of the solver.
        self._da_f = PETSc.DMDA().create(
            [self.N_q1, self.N_q2],
            dof=(self.N_species * (self.N_p1 + 2 * N_g_p) *
                 (self.N_p2 + 2 * N_g_p) * (self.N_p3 + 2 * N_g_p)),
            stencil_width=N_g_q,
            boundary_type=(petsc_bc_in_q1, petsc_bc_in_q2),
            proc_sizes=(nproc_in_q1, nproc_in_q2),
            stencil_type=1,
            comm=self._comm)

        # This DA is used by the FileIO routine dump_distribution_function():
        self._da_dump_f = PETSc.DMDA().create(
            [self.N_q1, self.N_q2],
            dof=(self.N_species * self.N_p1 * self.N_p2 * self.N_p3),
            stencil_width=N_g_q,
            boundary_type=(petsc_bc_in_q1, petsc_bc_in_q2),
            proc_sizes=(nproc_in_q1, nproc_in_q2),
            stencil_type=1,
            comm=self._comm)

        # This DA is used by the FileIO routine dump_moments():
        # Finding the number of definitions for the moments:
        attributes = [
            a for a in dir(self.physical_system.moments)
            if not a.startswith('_')
        ]

        # Removing utility functions:
        if ('integral_over_v' in attributes):
            attributes.remove('integral_over_v')

        self._da_dump_moments = PETSc.DMDA().create(
            [self.N_q1, self.N_q2],
            dof=self.N_species * len(attributes),
            proc_sizes=(nproc_in_q1, nproc_in_q2),
            comm=self._comm)

        # Creation of the local and global vectors from the DA:
        # This is for the distribution function
        self._glob_f = self._da_f.createGlobalVec()
        self._local_f = self._da_f.createLocalVec()

        # The following vector is used to dump the data to file:
        self._glob_dump_f = self._da_dump_f.createGlobalVec()
        self._glob_moments = self._da_dump_moments.createGlobalVec()

        # Getting the arrays for the above vectors:
        self._glob_f_array = self._glob_f.getArray()
        self._local_f_array = self._local_f.getArray()

        self._glob_moments_array = self._glob_moments.getArray()
        self._glob_dump_f_array = self._glob_dump_f.getArray()

        # Setting names for the objects which will then be
        # used as the key identifiers for the HDF5 files:
        PETSc.Object.setName(self._glob_dump_f, 'distribution_function')
        PETSc.Object.setName(self._glob_moments, 'moments')

        # Obtaining the array values of the cannonical variables:
        self.q1_center, self.q2_center = self._calculate_q_center()
        self.p1_center, self.p2_center, self.p3_center = self._calculate_p_center(
        )

        # Initialize according to initial condition provided by user:
        self._initialize(physical_system.params)

        # Obtaining start coordinates for the local zone
        # Additionally, we also obtain the size of the local zone
        ((i_q1_start, i_q2_start), (N_q1_local,
                                    N_q2_local)) = self._da_f.getCorners()
        (i_q1_end, i_q2_end) = (i_q1_start + N_q1_local - 1,
                                i_q2_start + N_q2_local - 1)

        # Applying dirichlet boundary conditions:
        if (self.physical_system.boundary_conditions.in_q1_left == 'dirichlet'
            ):
            # If local zone includes the left physical boundary:
            if (i_q1_start == 0):
                self.f[:, :N_g_q] = self.boundary_conditions.\
                                    f_left(self.f, self.q1_center, self.q2_center,
                                           self.p1_center, self.p2_center, self.p3_center,
                                           self.physical_system.params
                                          )[:, :N_g_q]

        if (self.physical_system.boundary_conditions.in_q1_right == 'dirichlet'
            ):
            # If local zone includes the right physical boundary:
            if (i_q1_end == self.N_q1 - 1):
                self.f[:, -N_g_q:] = self.boundary_conditions.\
                                     f_right(self.f, self.q1_center, self.q2_center,
                                             self.p1_center, self.p2_center, self.p3_center,
                                             self.physical_system.params
                                            )[:, -N_g_q:]

        if (self.physical_system.boundary_conditions.in_q2_bottom ==
                'dirichlet'):
            # If local zone includes the bottom physical boundary:
            if (i_q2_start == 0):
                self.f[:, :, :N_g_q] = self.boundary_conditions.\
                                       f_bot(self.f, self.q1_center, self.q2_center,
                                             self.p1_center, self.p2_center, self.p3_center,
                                             self.physical_system.params
                                            )[:, :, :N_g_q]

        if (self.physical_system.boundary_conditions.in_q2_top == 'dirichlet'):
            # If local zone includes the top physical boundary:
            if (i_q2_end == self.N_q2 - 1):
                self.f[:, :, -N_g_q:] = self.boundary_conditions.\
                                        f_top(self.f, self.q1_center, self.q2_center,
                                              self.p1_center, self.p2_center, self.p3_center,
                                              self.physical_system.params
                                             )[:, :, -N_g_q:]

        # Assigning the value to the PETSc Vecs(for dump at t = 0):
        (af.flat(self.f)).to_ndarray(self._local_f_array)
        (af.flat(self.f[:, :, N_g_q:-N_g_q,
                        N_g_q:-N_g_q])).to_ndarray(self._glob_f_array)

        # Assigning the function objects to methods of the solver:
        self._A_q = physical_system.A_q
        self._C_q = physical_system.C_q
        self._A_p = physical_system.A_p
        self._C_p = physical_system.C_p

        # Source/Sink term:
        self._source = physical_system.source

        # Initializing a variable to track time-elapsed:
        self.time_elapsed = 0
Exemplo n.º 13
0
    def __init__(self, physical_system):
        """
        Constructor for the linear_solver object. It takes the physical
        system object as an argument and uses it in intialization and
        evolution of the system in consideration.

        Parameters
        ----------
        
        physical_system: The defined physical system object which holds
                         all the simulation information such as the initial
                         conditions, and the domain info is passed as an
                         argument in defining an instance of the linear_solver.
                         This system is then evolved, and monitored using the
                         various methods under the linear_solver class.
        """
        self.physical_system = physical_system

        # Storing Domain Information:
        self.q1_start, self.q1_end = physical_system.q1_start,\
                                     physical_system.q1_end
        self.q2_start, self.q2_end = physical_system.q2_start,\
                                     physical_system.q2_end
        self.p1_start, self.p1_end = physical_system.p1_start,\
                                     physical_system.p1_end
        self.p2_start, self.p2_end = physical_system.p2_start,\
                                     physical_system.p2_end
        self.p3_start, self.p3_end = physical_system.p3_start,\
                                     physical_system.p3_end

        # Getting Domain Resolution
        self.N_q1, self.dq1 = physical_system.N_q1, physical_system.dq1
        self.N_q2, self.dq2 = physical_system.N_q2, physical_system.dq2
        self.N_p1, self.dp1 = physical_system.N_p1, physical_system.dp1
        self.N_p2, self.dp2 = physical_system.N_p2, physical_system.dp2
        self.N_p3, self.dp3 = physical_system.N_p3, physical_system.dp3

        # Getting number of species:
        self.N_species = len(physical_system.params.mass)

        # Having the mass and charge along axis 1:
        self.physical_system.params.mass  = \
            af.cast(af.moddims(af.to_array(physical_system.params.mass),
                               1, self.N_species
                              ),
                    af.Dtype.f64
                   )

        self.physical_system.params.charge  = \
            af.cast(af.moddims(af.to_array(physical_system.params.charge),
                               1, self.N_species
                              ),
                    af.Dtype.f64
                   )

        # Initializing variable to hold time elapsed:
        self.time_elapsed = 0

        # Checking that periodic B.C's are utilized:
        if (physical_system.boundary_conditions.in_q1_left != 'periodic' and
                physical_system.boundary_conditions.in_q1_right != 'periodic'
                and
                physical_system.boundary_conditions.in_q2_bottom != 'periodic'
                and
                physical_system.boundary_conditions.in_q2_top != 'periodic'):
            raise Exception('Only systems with periodic boundary conditions \
                             can be solved using the linear solver')

        # Initializing DAs which will be used in file-writing:
        # This is done so that the output format used by the linear solver matches
        # with the output format of the nonlinear solver:
        self._da_dump_f = PETSc.DMDA().create([self.N_q1, self.N_q2],
                                              dof=(self.N_species * self.N_p1 *
                                                   self.N_p2 * self.N_p3))

        # Getting the number of definitions in moments:
        attributes = [
            a for a in dir(self.physical_system.moments)
            if not a.startswith('_')
        ]
        self._da_dump_moments = PETSc.DMDA().create([self.N_q1, self.N_q2],
                                                    dof=self.N_species *
                                                    len(attributes))

        # Printing backend details:
        PETSc.Sys.Print('\nBackend Details for Linear Solver:')
        PETSc.Sys.Print(indent('On Node: ' + socket.gethostname()))
        PETSc.Sys.Print(indent('Device Details:'))
        PETSc.Sys.Print(indent(af.info_str(), 2))
        PETSc.Sys.Print(
            indent('Device Bandwidth = ' + str(bandwidth_test(100)) +
                   ' GB / sec'))
        PETSc.Sys.Print()

        # Creating PETSc Vecs which are used in dumping to file:
        self._glob_f = self._da_dump_f.createGlobalVec()
        self._glob_f_array = self._glob_f.getArray()

        self._glob_moments = self._da_dump_moments.createGlobalVec()
        self._glob_moments_array = self._glob_moments.getArray()

        # Setting names for the objects which will then be
        # used as the key identifiers for the HDF5 files:
        PETSc.Object.setName(self._glob_f, 'distribution_function')
        PETSc.Object.setName(self._glob_moments, 'moments')

        # Intializing position, wavenumber and velocity arrays:
        self.q1_center, self.q2_center = self._calculate_q_center()
        self.k_q1, self.k_q2 = self._calculate_k()
        self.p1, self.p2, self.p3 = self._calculate_p_center()

        # Assigning the function objects to methods of the solver:
        self._A_q = self.physical_system.A_q
        self._A_p = self.physical_system.A_p
        self._source = self.physical_system.source

        # Initializing f, f_hat and the other EM field quantities:
        self._initialize(physical_system.params)
Exemplo n.º 14
0
c = a
c >>= 2
af.display(c)

af.display(a << b)
af.display(a << 2)
c = a
c <<= 2
af.display(c)

af.display(-a)
af.display(+a)
af.display(~a)
af.display(a)

af.display(af.cast(a, af.c32))
af.display(af.maxof(a,b))
af.display(af.minof(a,b))
af.display(af.rem(a,b))

a = af.randu(3,3) - 0.5
b = af.randu(3,3) - 0.5

af.display(af.abs(a))
af.display(af.arg(a))
af.display(af.sign(a))
af.display(af.round(a))
af.display(af.trunc(a))
af.display(af.floor(a))
af.display(af.ceil(a))
af.display(af.hypot(a, b))
def advection_step(u, v):
    '''
    done - Matching u_new and v_new
    '''
    u_w_bc, v_w_bc = add_boundary_conditions(u, v)
    u = af.moddims(u_w_bc, params.n, params.n)
    v = af.moddims(v_w_bc, params.n, params.n)

    u_tile = u[1:-1, 1:-1]
    v_tile = v[1:-1, 1:-1]

    u_new = af.np_to_af_array(np.zeros([params.n, params.n]))
    v_new = af.np_to_af_array(np.zeros([params.n, params.n]))

    x0_tile = af.tile(af.np_to_af_array(np.linspace(0, 1, params.n)), 1,
                      params.n)[1:-1, 1:-1]
    y0_tile = af.transpose(x0_tile)

    reference_0_tile = af.constant(0,
                                   params.n - 2,
                                   params.n - 2,
                                   dtype=af.Dtype.f64)
    reference_1_tile = af.constant(1,
                                   params.n - 2,
                                   params.n - 2,
                                   dtype=af.Dtype.f64)

    x1_tile = af.minof(
        af.maxof(x0_tile - params.delta_t * u_tile, reference_0_tile),
        reference_1_tile)
    y1_tile = af.minof(
        af.maxof(y0_tile - params.delta_t * v_tile, reference_0_tile),
        reference_1_tile)

    i_left_tile = af.minof(af.cast(x1_tile * (params.n - 1), af.Dtype.s64),
                           (params.n - 2) * reference_1_tile)
    i_left_flat = af.flat(i_left_tile)

    i_right_tile = i_left_tile + 1
    i_right_flat = af.flat(i_right_tile)

    j_bottom_tile = af.minof(af.cast(y1_tile * (params.n - 1), af.Dtype.s64),
                             (params.n - 2) * reference_1_tile)
    j_bottom_flat = af.flat(j_bottom_tile * params.n)

    j_top_tile = j_bottom_tile + 1
    j_top_flat = af.flat(j_top_tile * params.n)

    x_left_tile = i_left_tile / (params.n - 1)
    x_right_tile = i_right_tile / (params.n - 1)

    y_bottom_tile = j_bottom_tile / (params.n - 1)
    y_top_tile = j_top_tile / (params.n - 1)

    print(x_left_tile)

    flat_u = af.flat(u)
    flat_v = af.flat(v)

    u_top_left_tile = af.moddims(flat_u[i_left_flat + j_top_flat],
                                 params.n - 2, params.n - 2)

    u_top_right_tile = af.moddims(flat_u[i_right_flat + j_top_flat],
                                  params.n - 2, params.n - 2)

    u_bottom_left_tile = af.moddims(flat_u[i_left_flat + j_bottom_flat],
                                    params.n - 2, params.n - 2)

    u_bottom_right_tile = af.moddims(flat_u[i_right_flat + j_bottom_flat],
                                     params.n - 2, params.n - 2)

    v_top_left_tile = af.moddims(flat_v[i_left_flat + j_top_flat],
                                 params.n - 2, params.n - 2)

    v_top_right_tile = af.moddims(flat_v[i_right_flat + j_top_flat],
                                  params.n - 2, params.n - 2)

    v_bottom_left_tile = af.moddims(flat_v[i_left_flat + j_bottom_flat],
                                    params.n - 2, params.n - 2)

    v_bottom_right_tile = af.moddims(flat_v[i_right_flat + j_bottom_flat],
                                     params.n - 2, params.n - 2)


    u_upper_tile = u_top_left_tile\
                 + (u_top_right_tile - u_top_left_tile)\
                 * (x1_tile - x_left_tile) / params.delta_x


    u_lower_tile = u_bottom_right_tile\
                 + (u_bottom_left_tile - u_bottom_right_tile)\
                 * (x1_tile - x_left_tile) / params.delta_x

    u_new_tile = u_lower_tile + (u_upper_tile - u_lower_tile)\
               * (y1_tile - y_bottom_tile) / params.delta_x

    v_upper_tile = v_top_left_tile + (v_top_right_tile - v_top_left_tile)\
                 * (x1_tile - x_left_tile) / params.delta_x

    v_lower_tile = v_bottom_right_tile + (v_bottom_left_tile - v_bottom_right_tile)\
                 * (x1_tile - x_left_tile) / params.delta_x

    v_new_tile = v_lower_tile + (v_upper_tile - v_lower_tile)\
               * (y1_tile - y_bottom_tile) / params.delta_x

    u_new = af.flat(u_new_tile)
    v_new = af.flat(v_new_tile)

    return u_new, v_new
Exemplo n.º 16
0
def test_af_cast():
    a = afnumpy.arrayfire.randu(2, 3)
    # Check that device_ptr does not cause a copy
    assert a.device_ptr() == a.device_ptr()
    # Check that cast does not cause a copy
    assert arrayfire.cast(a, a.dtype()).device_ptr() == a.device_ptr()
Exemplo n.º 17
0
def test_cast():
    a = afnumpy.random.rand(2,3)
    # Check that device_ptr does not cause a copy
    assert a.d_array.device_ptr() == a.d_array.device_ptr()
    # Check that cast does not cause a copy
    assert arrayfire.cast(a.d_array, a.d_array.dtype()).device_ptr() == a.d_array.device_ptr()
Exemplo n.º 18
0
def simple_arith(verbose = False):
    display_func = _util.display_func(verbose)
    print_func   = _util.print_func(verbose)

    a = af.randu(3,3,dtype=af.Dtype.u32)
    b = af.constant(4, 3, 3, dtype=af.Dtype.u32)
    display_func(a)
    display_func(b)

    c = a + b
    d = a
    d += b

    display_func(c)
    display_func(d)
    display_func(a + 2)
    display_func(3 + a)


    c = a - b
    d = a
    d -= b

    display_func(c)
    display_func(d)
    display_func(a - 2)
    display_func(3 - a)

    c = a * b
    d = a
    d *= b

    display_func(c * 2)
    display_func(3 * d)
    display_func(a * 2)
    display_func(3 * a)

    c = a / b
    d = a
    d /= b

    display_func(c / 2.0)
    display_func(3.0 / d)
    display_func(a / 2)
    display_func(3 / a)

    c = a % b
    d = a
    d %= b

    display_func(c % 2.0)
    display_func(3.0 % d)
    display_func(a % 2)
    display_func(3 % a)

    c = a ** b
    d = a
    d **= b

    display_func(c ** 2.0)
    display_func(3.0 ** d)
    display_func(a ** 2)
    display_func(3 ** a)

    display_func(a < b)
    display_func(a < 0.5)
    display_func(0.5 < a)

    display_func(a <= b)
    display_func(a <= 0.5)
    display_func(0.5 <= a)

    display_func(a > b)
    display_func(a > 0.5)
    display_func(0.5 > a)

    display_func(a >= b)
    display_func(a >= 0.5)
    display_func(0.5 >= a)

    display_func(a != b)
    display_func(a != 0.5)
    display_func(0.5 != a)

    display_func(a == b)
    display_func(a == 0.5)
    display_func(0.5 == a)

    display_func(a & b)
    display_func(a & 2)
    c = a
    c &= 2
    display_func(c)

    display_func(a | b)
    display_func(a | 2)
    c = a
    c |= 2
    display_func(c)

    display_func(a >> b)
    display_func(a >> 2)
    c = a
    c >>= 2
    display_func(c)

    display_func(a << b)
    display_func(a << 2)
    c = a
    c <<= 2
    display_func(c)

    display_func(-a)
    display_func(+a)
    display_func(~a)
    display_func(a)

    display_func(af.cast(a, af.Dtype.c32))
    display_func(af.maxof(a,b))
    display_func(af.minof(a,b))
    display_func(af.rem(a,b))

    a = af.randu(3,3) - 0.5
    b = af.randu(3,3) - 0.5

    display_func(af.abs(a))
    display_func(af.arg(a))
    display_func(af.sign(a))
    display_func(af.round(a))
    display_func(af.trunc(a))
    display_func(af.floor(a))
    display_func(af.ceil(a))
    display_func(af.hypot(a, b))
    display_func(af.sin(a))
    display_func(af.cos(a))
    display_func(af.tan(a))
    display_func(af.asin(a))
    display_func(af.acos(a))
    display_func(af.atan(a))
    display_func(af.atan2(a, b))

    c = af.cplx(a)
    d = af.cplx(a,b)
    display_func(c)
    display_func(d)
    display_func(af.real(d))
    display_func(af.imag(d))
    display_func(af.conjg(d))

    display_func(af.sinh(a))
    display_func(af.cosh(a))
    display_func(af.tanh(a))
    display_func(af.asinh(a))
    display_func(af.acosh(a))
    display_func(af.atanh(a))

    a = af.abs(a)
    b = af.abs(b)

    display_func(af.root(a, b))
    display_func(af.pow(a, b))
    display_func(af.pow2(a))
    display_func(af.exp(a))
    display_func(af.expm1(a))
    display_func(af.erf(a))
    display_func(af.erfc(a))
    display_func(af.log(a))
    display_func(af.log1p(a))
    display_func(af.log10(a))
    display_func(af.log2(a))
    display_func(af.sqrt(a))
    display_func(af.cbrt(a))

    a = af.round(5 * af.randu(3,3) - 1)
    b = af.round(5 * af.randu(3,3) - 1)

    display_func(af.factorial(a))
    display_func(af.tgamma(a))
    display_func(af.lgamma(a))
    display_func(af.iszero(a))
    display_func(af.isinf(a/b))
    display_func(af.isnan(a/a))

    a = af.randu(5, 1)
    b = af.randu(1, 5)
    c = af.broadcast(lambda x,y: x+y, a, b)
    display_func(a)
    display_func(b)
    display_func(c)

    @af.broadcast
    def test_add(aa, bb):
        return aa + bb

    display_func(test_add(a, b))
Exemplo n.º 19
0
def test_af_cast():
    a = afnumpy.arrayfire.randu(2,3)
    # Check that device_ptr does not cause a copy
    assert a.device_ptr() == a.device_ptr()
    # Check that cast does not cause a copy
    assert arrayfire.cast(a, a.dtype()).device_ptr() == a.device_ptr()
Exemplo n.º 20
0
    def sum(self, s, axis):
        if self.dtype == numpy.bool:
            s = arrayfire.cast(s, pu.typemap(numpy.int64))
#            s = s.astype(pu.typemap(numpy.int64))
        return arrayfire.sum(s, dim=axis)
Exemplo n.º 21
0
def deconvolve_gpu_blind(vol_a: Volume, vol_b: Volume, n: int, m: int,
                         psf_a: np.ndarray, psf_b: np.ndarray) -> Volume:
    """
    Perform blind joint Richardson-Lucy deconvolution on two volumes using two specified estimates of the PSF on the
    GPU

    :param vol_a: The first volume
    :param vol_b: The second volume
    :param n: The number of Richardson-Lucy iterations
    :param m: The number of sub-iterations per RL iteration
    :param psf_a: The initial PSF estimate for the first volume
    :param psf_b: The initial PSF estimate for the second volume
    :return: The fused RL deconvolution
    """
    from functools import partial
    import arrayfire as af
    view_a, view_b = vol_a.astype(np.float), vol_b.astype(np.float)

    psf_a = psf_a.astype(np.float) / np.sum(psf_a).astype(np.float)
    psf_b = psf_b.astype(np.float) / np.sum(psf_b).astype(np.float)
    padding = tuple(
        (int(s // 2 - psf_a.shape[i]), int((s - s // 2) - psf_a.shape[i]))
        for i, s in enumerate(view_a.shape))
    psf_a = np.pad(
        psf_a,
        tuple(((s - psf_a.shape[i]) // 2,
               (s - psf_a.shape[i]) - (s - psf_a.shape[i]) // 2)
              for i, s in enumerate(view_a.shape)), 'constant')
    psf_b = np.pad(
        psf_b,
        tuple(((s - psf_b.shape[i]) // 2,
               (s - psf_b.shape[i]) - (s - psf_b.shape[i]) // 2)
              for i, s in enumerate(view_b.shape)), 'constant')

    view_a = af.cast(af.from_ndarray(view_a), af.Dtype.u16)
    view_b = af.cast(af.from_ndarray(view_b), af.Dtype.u16)

    psf_a = af.cast(af.from_ndarray(psf_a), af.Dtype.f32)
    psf_b = af.cast(af.from_ndarray(psf_b), af.Dtype.f32)

    estimate = (view_a + view_b) / 2

    convolve = partial(af.fft_convolve3)

    lamb = 0.002

    with progressbar.ProgressBar(max_value=n, redirect_stderr=True) as bar:
        for _ in bar(range(n)):
            for j in range(m):
                psf_a = psf_a * convolve(
                    view_a / (convolve(psf_a, estimate) + 1e-1),
                    estimate[::-1, ::-1, ::-1])
            for j in range(m):
                estimate = estimate * convolve(
                    view_a /
                    (convolve(estimate, psf_a) + 10), psf_a[::-1, ::-1, ::-1])
            for j in range(m):
                psf_b = psf_b * convolve(
                    view_b / (convolve(psf_b, estimate) + 1e-1),
                    estimate[::-1, ::-1, ::-1])
            for j in range(m):
                estimate = estimate * convolve(
                    view_b /
                    (convolve(estimate, psf_b) + 10), psf_b[::-1, ::-1, ::-1])

    del psf_a, psf_b, view_a, view_b

    CURSOR_UP_ONE = '\x1b[1A'
    ERASE_LINE = '\x1b[2K'
    print(CURSOR_UP_ONE + ERASE_LINE + CURSOR_UP_ONE)

    return Volume(estimate.to_ndarray(),
                  inverted=False,
                  spacing=vol_a.spacing,
                  is_skewed=False)