1*7def3d77Svaleriabarra# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2*7def3d77Svaleriabarra# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3*7def3d77Svaleriabarra# reserved. See files LICENSE and NOTICE for details. 4*7def3d77Svaleriabarra# 5*7def3d77Svaleriabarra# This file is part of CEED, a collection of benchmarks, miniapps, software 6*7def3d77Svaleriabarra# libraries and APIs for efficient high-order finite element and spectral 7*7def3d77Svaleriabarra# element discretizations for exascale applications. For more information and 8*7def3d77Svaleriabarra# source code availability see http://github.com/ceed. 9*7def3d77Svaleriabarra# 10*7def3d77Svaleriabarra# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*7def3d77Svaleriabarra# a collaborative effort of two U.S. Department of Energy organizations (Office 12*7def3d77Svaleriabarra# of Science and the National Nuclear Security Administration) responsible for 13*7def3d77Svaleriabarra# the planning and preparation of a capable exascale ecosystem, including 14*7def3d77Svaleriabarra# software, applications, hardware, advanced system engineering and early 15*7def3d77Svaleriabarra# testbed platforms, in support of the nation's exascale computing imperative. 16*7def3d77Svaleriabarra 17*7def3d77Svaleriabarrafrom _ceed_cffi import ffi, lib 18*7def3d77Svaleriabarraimport tempfile 19*7def3d77Svaleriabarraimport numpy as np 20*7def3d77Svaleriabarrafrom .ceed_constants import MEM_HOST, COPY_VALUES 21*7def3d77Svaleriabarra 22*7def3d77Svaleriabarra# ------------------------------------------------------------------------------ 23*7def3d77Svaleriabarraclass Vector(): 24*7def3d77Svaleriabarra """Ceed Vector: storing and manipulating vectors.""" 25*7def3d77Svaleriabarra 26*7def3d77Svaleriabarra # Attributes 27*7def3d77Svaleriabarra _ceed = ffi.NULL 28*7def3d77Svaleriabarra _pointer = ffi.NULL 29*7def3d77Svaleriabarra 30*7def3d77Svaleriabarra # Constructor 31*7def3d77Svaleriabarra def __init__(self, ceed, size): 32*7def3d77Svaleriabarra # CeedVector object 33*7def3d77Svaleriabarra self._pointer = ffi.new("CeedVector *") 34*7def3d77Svaleriabarra 35*7def3d77Svaleriabarra # Reference to Ceed 36*7def3d77Svaleriabarra self._ceed = ceed 37*7def3d77Svaleriabarra 38*7def3d77Svaleriabarra # libCEED call 39*7def3d77Svaleriabarra lib.CeedVectorCreate(self._ceed._pointer[0], size, self._pointer) 40*7def3d77Svaleriabarra 41*7def3d77Svaleriabarra # Destructor 42*7def3d77Svaleriabarra def __del__(self): 43*7def3d77Svaleriabarra # libCEED call 44*7def3d77Svaleriabarra lib.CeedVectorDestroy(self._pointer) 45*7def3d77Svaleriabarra 46*7def3d77Svaleriabarra # Representation 47*7def3d77Svaleriabarra def __repr__(self): 48*7def3d77Svaleriabarra return "<CeedVector instance at " + hex(id(self)) + ">" 49*7def3d77Svaleriabarra 50*7def3d77Svaleriabarra # String conversion for print() to stdout 51*7def3d77Svaleriabarra def __str__(self): 52*7def3d77Svaleriabarra """View a Vector via print().""" 53*7def3d77Svaleriabarra 54*7def3d77Svaleriabarra # libCEED call 55*7def3d77Svaleriabarra fmt = ffi.new("char[]", "%f".encode('ascii')) 56*7def3d77Svaleriabarra with tempfile.NamedTemporaryFile() as key_file: 57*7def3d77Svaleriabarra with open(key_file.name, 'r+') as stream_file: 58*7def3d77Svaleriabarra stream = ffi.cast("FILE *", stream_file) 59*7def3d77Svaleriabarra 60*7def3d77Svaleriabarra lib.CeedVectorView(self._pointer[0], fmt, stream) 61*7def3d77Svaleriabarra 62*7def3d77Svaleriabarra stream_file.seek(0) 63*7def3d77Svaleriabarra out_string = stream_file.read() 64*7def3d77Svaleriabarra 65*7def3d77Svaleriabarra return out_string 66*7def3d77Svaleriabarra 67*7def3d77Svaleriabarra # Set Vector's data array 68*7def3d77Svaleriabarra def set_array(self, array, memtype=MEM_HOST, cmode=COPY_VALUES): 69*7def3d77Svaleriabarra """Set the array used by a Vector, freeing any previously allocated 70*7def3d77Svaleriabarra array if applicable. 71*7def3d77Svaleriabarra 72*7def3d77Svaleriabarra Args: 73*7def3d77Svaleriabarra *array: Numpy array to be used 74*7def3d77Svaleriabarra **memtype: memory type of the array being passed, default CEED_MEM_HOST 75*7def3d77Svaleriabarra **cmode: copy mode for the array, default CEED_COPY_VALUES""" 76*7def3d77Svaleriabarra 77*7def3d77Svaleriabarra # Setup the numpy array for the libCEED call 78*7def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar *") 79*7def3d77Svaleriabarra array_pointer = ffi.cast("CeedScalar *", array.__array_interface__['data'][0]) 80*7def3d77Svaleriabarra 81*7def3d77Svaleriabarra # libCEED call 82*7def3d77Svaleriabarra lib.CeedVectorSetArray(self._pointer[0], memtype, cmode, array_pointer) 83*7def3d77Svaleriabarra 84*7def3d77Svaleriabarra # Get Vector's data array 85*7def3d77Svaleriabarra def get_array(self, memtype=MEM_HOST): 86*7def3d77Svaleriabarra """Get read/write access to a Vector via the specified memory type. 87*7def3d77Svaleriabarra 88*7def3d77Svaleriabarra Args: 89*7def3d77Svaleriabarra **memtype: memory type of the array being passed, default CEED_MEM_HOST 90*7def3d77Svaleriabarra 91*7def3d77Svaleriabarra Returns: 92*7def3d77Svaleriabarra *array: Numpy array""" 93*7def3d77Svaleriabarra 94*7def3d77Svaleriabarra # Retrieve the length of the array 95*7def3d77Svaleriabarra length_pointer = ffi.new("CeedInt *") 96*7def3d77Svaleriabarra lib.CeedVectorGetLength(self._pointer[0], length_pointer) 97*7def3d77Svaleriabarra 98*7def3d77Svaleriabarra # Setup the pointer's pointer 99*7def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 100*7def3d77Svaleriabarra 101*7def3d77Svaleriabarra # libCEED call 102*7def3d77Svaleriabarra lib.CeedVectorGetArray(self._pointer[0], memtype, array_pointer) 103*7def3d77Svaleriabarra 104*7def3d77Svaleriabarra # Create buffer object from returned pointer 105*7def3d77Svaleriabarra buff = ffi.buffer(array_pointer[0], ffi.sizeof("CeedScalar") * length_pointer[0]) 106*7def3d77Svaleriabarra # Return numpy array created from buffer 107*7def3d77Svaleriabarra return np.frombuffer(buff, dtype="float64") 108*7def3d77Svaleriabarra 109*7def3d77Svaleriabarra # Get Vector's data array in read-only mode 110*7def3d77Svaleriabarra def get_array_read(self, memtype=MEM_HOST): 111*7def3d77Svaleriabarra """Get read-only access to a Vector via the specified memory type. 112*7def3d77Svaleriabarra 113*7def3d77Svaleriabarra Args: 114*7def3d77Svaleriabarra **memtype: memory type of the array being passed, default CEED_MEM_HOST 115*7def3d77Svaleriabarra 116*7def3d77Svaleriabarra Returns: 117*7def3d77Svaleriabarra *array: Numpy array""" 118*7def3d77Svaleriabarra 119*7def3d77Svaleriabarra # Retrieve the length of the array 120*7def3d77Svaleriabarra length_pointer = ffi.new("CeedInt *") 121*7def3d77Svaleriabarra lib.CeedVectorGetLength(self._pointer[0], length_pointer) 122*7def3d77Svaleriabarra 123*7def3d77Svaleriabarra # Setup the pointer's pointer 124*7def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 125*7def3d77Svaleriabarra 126*7def3d77Svaleriabarra # libCEED call 127*7def3d77Svaleriabarra lib.CeedVectorGetArrayRead(self._pointer[0], memtype, array_pointer) 128*7def3d77Svaleriabarra 129*7def3d77Svaleriabarra # Create buffer object from returned pointer 130*7def3d77Svaleriabarra buff = ffi.buffer(array_pointer[0], ffi.sizeof("CeedScalar") * length_pointer[0]) 131*7def3d77Svaleriabarra # Create numpy array from buffer 132*7def3d77Svaleriabarra ret = np.frombuffer(buff, dtype="float64") 133*7def3d77Svaleriabarra # Make the numpy array read-only 134*7def3d77Svaleriabarra ret.flags['WRITEABLE'] = False 135*7def3d77Svaleriabarra return ret 136*7def3d77Svaleriabarra 137*7def3d77Svaleriabarra # Restore the Vector's data array 138*7def3d77Svaleriabarra def restore_array(self): 139*7def3d77Svaleriabarra """Restore an array obtained using get_array().""" 140*7def3d77Svaleriabarra 141*7def3d77Svaleriabarra # Setup the pointer's pointer 142*7def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 143*7def3d77Svaleriabarra 144*7def3d77Svaleriabarra # libCEED call 145*7def3d77Svaleriabarra lib.CeedVectorRestoreArray(self._pointer[0], array_pointer) 146*7def3d77Svaleriabarra 147*7def3d77Svaleriabarra # Restore an array obtained using getArrayRead 148*7def3d77Svaleriabarra def restore_array_read(self): 149*7def3d77Svaleriabarra """Restore an array obtained using get_array_read().""" 150*7def3d77Svaleriabarra 151*7def3d77Svaleriabarra # Setup the pointer's pointer 152*7def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 153*7def3d77Svaleriabarra 154*7def3d77Svaleriabarra # libCEED call 155*7def3d77Svaleriabarra lib.CeedVectorRestoreArrayRead(self._pointer[0], array_pointer) 156*7def3d77Svaleriabarra 157*7def3d77Svaleriabarra # Get the length of a Vector 158*7def3d77Svaleriabarra def get_length(self): 159*7def3d77Svaleriabarra """Get the length of a Vector. 160*7def3d77Svaleriabarra 161*7def3d77Svaleriabarra Returns: 162*7def3d77Svaleriabarra length: length of the Vector""" 163*7def3d77Svaleriabarra 164*7def3d77Svaleriabarra length_pointer = ffi.new("CeedInt *") 165*7def3d77Svaleriabarra 166*7def3d77Svaleriabarra # libCEED call 167*7def3d77Svaleriabarra lib.CeedVectorGetLength(self._pointer[0], length_pointer) 168*7def3d77Svaleriabarra 169*7def3d77Svaleriabarra return length_pointer[0] 170*7def3d77Svaleriabarra 171*7def3d77Svaleriabarra # Get the length of a Vector 172*7def3d77Svaleriabarra def __len__(self): 173*7def3d77Svaleriabarra """Get the length of a Vector. 174*7def3d77Svaleriabarra 175*7def3d77Svaleriabarra Returns: 176*7def3d77Svaleriabarra length: length of the Vector""" 177*7def3d77Svaleriabarra 178*7def3d77Svaleriabarra length_pointer = ffi.new("CeedInt *") 179*7def3d77Svaleriabarra 180*7def3d77Svaleriabarra # libCEED call 181*7def3d77Svaleriabarra lib.CeedVectorGetLength(self._pointer[0], length_pointer) 182*7def3d77Svaleriabarra 183*7def3d77Svaleriabarra return length_pointer[0] 184*7def3d77Svaleriabarra 185*7def3d77Svaleriabarra # Set the Vector to a given constant value 186*7def3d77Svaleriabarra def set_value(self, value): 187*7def3d77Svaleriabarra """Set the Vector to a constant value. 188*7def3d77Svaleriabarra 189*7def3d77Svaleriabarra Args: 190*7def3d77Svaleriabarra value: value to be used""" 191*7def3d77Svaleriabarra 192*7def3d77Svaleriabarra # libCEED call 193*7def3d77Svaleriabarra lib.CeedVectorSetValue(self._pointer[0], value) 194*7def3d77Svaleriabarra 195*7def3d77Svaleriabarra # Sync the Vector to a specified memtype 196*7def3d77Svaleriabarra def sync_array(self, memtype): 197*7def3d77Svaleriabarra """Sync the Vector to a specified memtype. 198*7def3d77Svaleriabarra 199*7def3d77Svaleriabarra Args: 200*7def3d77Svaleriabarra **memtype: memtype to be synced""" 201*7def3d77Svaleriabarra 202*7def3d77Svaleriabarra # libCEED call 203*7def3d77Svaleriabarra lib.CeedVectorSyncArray(self._pointer[0], memtype) 204*7def3d77Svaleriabarra 205*7def3d77Svaleriabarra# ------------------------------------------------------------------------------ 206*7def3d77Svaleriabarraclass _VectorWrap(Vector): 207*7def3d77Svaleriabarra """Wrap a CeedVector pointer in a Vector object.""" 208*7def3d77Svaleriabarra 209*7def3d77Svaleriabarra # Constructor 210*7def3d77Svaleriabarra def __init__(self, ceed, pointer): 211*7def3d77Svaleriabarra # CeedVector object 212*7def3d77Svaleriabarra self._pointer = pointer 213*7def3d77Svaleriabarra 214*7def3d77Svaleriabarra # Reference to Ceed 215*7def3d77Svaleriabarra self._ceed = ceed 216*7def3d77Svaleriabarra 217*7def3d77Svaleriabarra# ------------------------------------------------------------------------------ 218