cuPauliProp functions#

Library Initialization and Management API#

cupaulipropGetVersion#

size_t cupaulipropGetVersion()#

Returns the semantic version number of the cuPauliProp library.


cupaulipropGetErrorString#

const char *cupaulipropGetErrorString(cupaulipropStatus_t error)#

Returns the description string for an error code.

Remark

non-blocking, no reentrant, and thread-safe.

Parameters:

error[in] Error code to get the description string for.

Returns:

the error description string.


cupaulipropGetNumPackedIntegers#

cupaulipropStatus_t cupaulipropGetNumPackedIntegers(
int32_t numQubits,
int32_t *numPackedIntegers
)#

Returns the number of packed integers of cupaulipropPackedIntegerType_t needed to represent the X bits (or equivalently, the Z bits) of a single Pauli string.

Each Pauli string is represented by storing X bits and Z bits separately in packed integers. This function returns the number of packed integers needed for ONE set of bits (either X or Z). The total storage for a complete Pauli string is twice this value (one set for X bits, one set for Z bits). For example, for 64 qubits, this returns 1, and the total storage is 2 uint64 integers (1 for X bits + 1 for Z bits). For 65 qubits, this returns 2, and the total storage is 4 uint64 integers (2 for X bits + 2 for Z bits). Note that the integers are required to be zero padded for the most significant bits if the number of qubits is not a multiple of 64.

Parameters:
  • numQubits[in] Number of qubits.

  • numPackedIntegers[out] Number of uint64 integers needed to store X bits (or Z bits) for one Pauli string. To get the total storage requirement, multiply this value by 2.

Returns:

cupaulipropStatus_t


cupaulipropCreate#

cupaulipropStatus_t cupaulipropCreate(cupaulipropHandle_t *handle)#

Creates and initializes the library context.

Parameters:

handle[out] Library handle.

Returns:

cupaulipropStatus_t


cupaulipropDestroy#

cupaulipropStatus_t cupaulipropDestroy(cupaulipropHandle_t handle)#

Destroys the library context.

Parameters:

handle[in] Library handle.

Returns:

cupaulipropStatus_t


Workspace Management API#

cupaulipropCreateWorkspaceDescriptor#

cupaulipropStatus_t cupaulipropCreateWorkspaceDescriptor(
cupaulipropHandle_t handle,
cupaulipropWorkspaceDescriptor_t *workspaceDesc
)#

Creates a workspace descriptor.

Parameters:
  • handle[in] Library handle.

  • workspaceDesc[out] Workspace descriptor.

Returns:

cupaulipropStatus_t


cupaulipropDestroyWorkspaceDescriptor#

cupaulipropStatus_t cupaulipropDestroyWorkspaceDescriptor(
cupaulipropWorkspaceDescriptor_t workspaceDesc
)#

Destroys a workspace descriptor.

Parameters:

workspaceDesc[inout] Workspace descriptor.

Returns:

cupaulipropStatus_t


cupaulipropWorkspaceGetMemorySize#

cupaulipropStatus_t cupaulipropWorkspaceGetMemorySize(
const cupaulipropHandle_t handle,
const cupaulipropWorkspaceDescriptor_t workspaceDesc,
cupaulipropMemspace_t memSpace,
cupaulipropWorkspaceKind_t workspaceKind,
int64_t *memoryBufferSize
)#

Queries the required workspace buffer size.

Parameters:
  • handle[in] Library handle.

  • workspaceDesc[in] Workspace descriptor.

  • memSpace[in] Memory space.

  • workspaceKind[in] Workspace kind.

  • memoryBufferSize[out] Required workspace buffer size in bytes.

Returns:

cupaulipropStatus_t


cupaulipropWorkspaceSetMemory#

cupaulipropStatus_t cupaulipropWorkspaceSetMemory(
const cupaulipropHandle_t handle,
cupaulipropWorkspaceDescriptor_t workspaceDesc,
cupaulipropMemspace_t memSpace,
cupaulipropWorkspaceKind_t workspaceKind,
void *memoryBuffer,
int64_t memoryBufferSize
)#

Attaches memory to a workspace buffer.

Note

The pointer of memoryBuffer must be aligned to 16 bytes.

Parameters:
  • handle[in] Library handle.

  • workspaceDesc[inout] Workspace descriptor.

  • memSpace[in] Memory space.

  • workspaceKind[in] Workspace kind.

  • memoryBuffer[in] Pointer to a user-owned memory buffer to be used by the specified workspace.

  • memoryBufferSize[in] Size of the provided memory buffer in bytes.

Returns:

cupaulipropStatus_t


cupaulipropWorkspaceGetMemory#

cupaulipropStatus_t cupaulipropWorkspaceGetMemory(
const cupaulipropHandle_t handle,
const cupaulipropWorkspaceDescriptor_t workspaceDescr,
cupaulipropMemspace_t memSpace,
cupaulipropWorkspaceKind_t workspaceKind,
void **memoryBuffer,
int64_t *memoryBufferSize
)#

Retrieves a workspace buffer.

Parameters:
  • handle[in] Library handle.

  • workspaceDescr[in] Workspace descriptor.

  • memSpace[in] Memory space.

  • workspaceKind[in] Workspace kind.

  • memoryBuffer[out] Pointer to a user-owned memory buffer used by the specified workspace.

  • memoryBufferSize[out] Size of the memory buffer in bytes.

Returns:

cupaulipropStatus_t


Pauli Expansion API#

Pauli Expansion Creation and Management#

cupaulipropCreatePauliExpansion#

cupaulipropStatus_t cupaulipropCreatePauliExpansion(
const cupaulipropHandle_t handle,
int32_t numQubits,
void *xzBitsBuffer,
int64_t xzBitsBufferSize,
void *coefBuffer,
int64_t coefBufferSize,
cudaDataType_t dataType,
int64_t numTerms,
cupaulipropSortOrder_t sortOrder,
int32_t hasDuplicates,
cupaulipropPauliExpansion_t *pauliExpansion
)#

Creates a Pauli operator expansion.

Note

The xzBitsBuffer and coefBuffer must both be either GPU-accessible memory or CPU-accessible memory. Mixing memory types between these two buffers is not supported.

Note

The xzBitsBuffer must be aligned to 16 bytes, while the coefBuffer must be aligned to the size of a single coefficient, as determined by dataType, and upperbounded by 16 bytes.

Parameters:
  • handle[in] Library handle.

  • numQubits[in] Number of qubits.

  • xzBitsBuffer[in] Pointer to a user-owned memory buffer to be used by the created Pauli operator expansion for storing the X and Z bits for each Pauli operator term. The first numTerms Pauli operator terms will define the current Pauli operator expansion.

  • xzBitsBufferSize[in] Size (in bytes) of the provided memory buffer for storing the X and Z bits.

  • coefBuffer[in] Pointer to a user-owned memory buffer to be used by the created Pauli operator expansion for storing the coefficients for all Pauli operator terms. The first numTerms Pauli operator terms will define the current Pauli operator expansion.

  • coefBufferSize[in] Size (in bytes) of the provided memory buffer for storing the coefficients.

  • dataType[in] Data type of the coefficients in the Pauli operator expansion.

  • numTerms[in] Number of the Pauli operator terms stored in the provided memory buffer (the first numTerms components define the current Pauli operator expansion).

  • sortOrder[in] Sort order of the expansion. Use CUPAULIPROP_SORT_ORDER_NONE for unsorted expansions.

  • hasDuplicates[in] Whether or not there are duplicates in the expansion, i.e. several terms with identical X and Z bits.

  • pauliExpansion[out] Pauli operator expansion.

Returns:

cupaulipropStatus_t


cupaulipropDestroyPauliExpansion#

cupaulipropStatus_t cupaulipropDestroyPauliExpansion(
cupaulipropPauliExpansion_t pauliExpansion
)#

Destroys a Pauli operator expansion.

Parameters:

pauliExpansion[inout] Pauli operator expansion.

Returns:

cupaulipropStatus_t


Pauli Expansion Storage and Properties#

cupaulipropPauliExpansionGetStorageBuffer#

cupaulipropStatus_t cupaulipropPauliExpansionGetStorageBuffer(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
void **xzBitsBuffer,
int64_t *xzBitsBufferSize,
void **coefBuffer,
int64_t *coefBufferSize,
int64_t *numTerms,
cupaulipropMemspace_t *location
)#

Gets access to the storage of a Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • xzBitsBuffer[out] Pointer to a user-owned memory buffer used by the Pauli operator expansion for storing the X and Z bits for each Pauli operator term.

  • xzBitsBufferSize[out] Size (in bytes) of the memory buffer for X and Z bits.

  • coefBuffer[out] Pointer to a user-owned memory buffer used by the Pauli operator expansion for storing the coefficients for each Pauli operator term.

  • coefBufferSize[out] Size (in bytes) of the memory buffer for storing the coefficients.

  • numTerms[out] Current number of Pauli operator terms in the Pauli operator expansion (first numTerms terms define the current Pauli operator expansion).

  • location[out] Storage location of the Pauli operator expansion (whether it is on the host or device).

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionGetNumQubits#

cupaulipropStatus_t cupaulipropPauliExpansionGetNumQubits(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
int32_t *numQubits
)#

Gets the number of qubits of a Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • numQubits[out] Number of qubits.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionGetNumTerms#

cupaulipropStatus_t cupaulipropPauliExpansionGetNumTerms(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
int64_t *numTerms
)#

Gets the number of terms in the Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • numTerms[out] Number of terms.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionGetDataType#

cupaulipropStatus_t cupaulipropPauliExpansionGetDataType(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
cudaDataType_t *dataType
)#

Gets the data type of the coefficients in a Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • dataType[out] Data type.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionGetSortOrder#

cupaulipropStatus_t cupaulipropPauliExpansionGetSortOrder(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
cupaulipropSortOrder_t *sortOrder
)#

Queries the sort order of a Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • sortOrder[out] Sort order of the Pauli operator expansion. CUPAULIPROP_SORT_ORDER_NONE indicates the expansion is unsorted.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionIsDeduplicated#

cupaulipropStatus_t cupaulipropPauliExpansionIsDeduplicated(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
int32_t *isDeduplicated
)#

Queries whether a Pauli operator expansion is deduplicated. i.e. guaranteed to not contain duplicate Pauli strings or may otherwise potentially contain duplicates Pauli strings.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • isDeduplicated[out] Indicating whether the Pauli operator expansion is deduplicated. True (!= 0) if the Pauli operator expansion is guaranteed to not contain duplicate Pauli strings, false (0) if no such guarantee can be made (though it may be incidentally the case).

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionGetTerm#

cupaulipropStatus_t cupaulipropPauliExpansionGetTerm(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
int64_t termIndex,
cupaulipropPauliTerm_t *term
)#

Gets access to a specific term of a Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • termIndex[in] Index of the term.

  • term[out] Pauli operator term.

Returns:

cupaulipropStatus_t


Pauli Expansion Views#

cupaulipropPauliExpansionGetContiguousRange#

cupaulipropStatus_t cupaulipropPauliExpansionGetContiguousRange(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansion_t pauliExpansion,
int64_t startIndex,
int64_t endIndex,
cupaulipropPauliExpansionView_t *view
)#

Creates a non-owning view of a contiguous range of Pauli operator terms inside a Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • pauliExpansion[in] Pauli operator expansion.

  • startIndex[in] Start index of the range (inclusive, first element in the range).

  • endIndex[in] End index of the range (exclusive, one past the last element).

  • view[out] View to a range of Pauli terms inside the Pauli operator expansion.

Returns:

cupaulipropStatus_t


cupaulipropDestroyPauliExpansionView#

cupaulipropStatus_t cupaulipropDestroyPauliExpansionView(
cupaulipropPauliExpansionView_t view
)#

Destroys a Pauli expansion view.

Parameters:

view[inout] Pauli expansion view.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewGetNumTerms#

cupaulipropStatus_t cupaulipropPauliExpansionViewGetNumTerms(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view,
int64_t *numTerms
)#

Returns the number of Pauli terms in a Pauli expansion view.

Parameters:
  • handle[in] Library handle.

  • view[in] Pauli expansion view.

  • numTerms[out] Number of terms.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewGetLocation#

cupaulipropStatus_t cupaulipropPauliExpansionViewGetLocation(
const cupaulipropPauliExpansionView_t view,
cupaulipropMemspace_t *location
)#

Gets the storage location of a Pauli expansion view (whether its elements are stored on the host or device).

Parameters:
  • view[in] Pauli expansion view.

  • location[out] Location.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewGetTerm#

cupaulipropStatus_t cupaulipropPauliExpansionViewGetTerm(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view,
int64_t termIndex,
cupaulipropPauliTerm_t *term
)#

Gets a specific term of a Pauli expansion view.

Parameters:
  • handle[in] Library handle.

  • view[in] Pauli expansion view.

  • termIndex[in] Index of the term in the Pauli expansion view.

  • term[out] Pauli operator term.

Returns:

cupaulipropStatus_t


Deduplication Operations#

cupaulipropPauliExpansionViewPrepareDeduplication#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareDeduplication(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropSortOrder_t sortOrder,
int64_t maxWorkspaceDeviceSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for deduplication of the given view.

This function queries the workspace requirements for deduplicating a Pauli expansion view (removing duplicate Pauli strings and summing their coefficients) via cupaulipropPauliExpansionViewExecuteDeduplication(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to be deduplicated.

  • sortOrder[in] Sort order to apply to the output expansion. Use CUPAULIPROP_SORT_ORDER_NONE if sorting is not required. Currently, only CUPAULIPROP_SORT_ORDER_INTERNAL and CUPAULIPROP_SORT_ORDER_NONE are supported.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewExecuteDeduplication#

cupaulipropStatus_t cupaulipropPauliExpansionViewExecuteDeduplication(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropPauliExpansion_t expansionOut,
cupaulipropSortOrder_t sortOrder,
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Deduplicates a Pauli expansion view.

This function removes duplicate Pauli strings from a sorted Pauli expansion view and sums their coefficients, populating the output expansion with the deduplicated view.

Note

This method is blocking, i.e. it will wait for the operation to complete before returning to the caller.

Note

The storage location of both the input view and the output expansion must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to be deduplicated.

  • expansionOut[out] Pauli expansion to be populated with the deduplicated view.

  • sortOrder[in] Sort order to apply to the output expansion. Use CUPAULIPROP_SORT_ORDER_NONE if sorting is not required. Currently, only CUPAULIPROP_SORT_ORDER_INTERNAL and CUPAULIPROP_SORT_ORDER_NONE are supported.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Sorting Operations#

cupaulipropPauliExpansionViewPrepareSort#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareSort(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropSortOrder_t sortOrder,
int64_t maxWorkspaceDeviceSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for sorting of the given view.

This function queries the workspace requirements for out-of-place sorting of a Pauli expansion view, according to the specified sort order, via cupaulipropPauliExpansionViewExecuteSort(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to be sorted.

  • sortOrder[in] Sort order to apply.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewExecuteSort#

cupaulipropStatus_t cupaulipropPauliExpansionViewExecuteSort(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropPauliExpansion_t expansionOut,
cupaulipropSortOrder_t sortOrder,
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Sorts a Pauli expansion view.

This function sorts a Pauli expansion view according to the specified sort order, writing the result to the output expansion.

Note

This function is non-blocking, i.e. it will return immediately and the sorting will be performed asynchronously on the stream.

Note

The storage location of both the input view and the output expansion must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to be sorted.

  • expansionOut[out] Pauli expansion to be populated with the sorted view.

  • sortOrder[in] Sort order to apply.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Population Operations#

cupaulipropPauliExpansionPopulateFromView#

cupaulipropStatus_t cupaulipropPauliExpansionPopulateFromView(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropPauliExpansion_t expansionOut,
cudaStream_t stream
)#

Populates a Pauli operator expansion from a Pauli expansion view.

Note

This function is non-blocking, i.e. it will return immediately and the population will be performed asynchronously on the stream.

Note

The Pauli expansion view must not belong to the same Pauli operator expansion.

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Input Pauli expansion view.

  • expansionOut[out] Populated Pauli operator expansion.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Trace Operations#

cupaulipropPauliExpansionViewPrepareTraceWithExpansionView#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareTraceWithExpansionView(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view1,
const cupaulipropPauliExpansionView_t view2,
int64_t maxWorkspaceDeviceSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for computing the trace of the product of two Pauli expansion views.

This function queries the workspace requirements for computing the trace of the product of two Pauli expansion views via cupaulipropPauliExpansionViewComputeTraceWithExpansionView(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Note

Both views must not contain duplicates.

Parameters:
  • handle[in] Library handle.

  • view1[in] First Pauli expansion view to be traced.

  • view2[in] Second Pauli expansion view to be traced.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeTraceWithExpansionView#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeTraceWithExpansionView(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view1,
const cupaulipropPauliExpansionView_t view2,
int32_t takeAdjoint1,
void *traceSignificand,
double *traceExponent,
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the trace of the product of two Pauli expansion views.

This function computes the trace of the composition (i.e. product) of two Pauli expansion views. The trace is returned as two scalars - the trace’s significand and exponent (base two) - and can be reconstructed in a single scalar as trace = traceSignificand * pow(2, traceExponent). This separation is helpful for avoiding numerical precision issues due to the exponentially large range of the trace. Optionally, the adjoint of the first view view1 can be taken when computing the trace.

Note

Both views must not contain duplicates.

Note

This function is non-blocking, i.e. it will return immediately and the tracing will be performed asynchronously on the stream.

Note

The storage location of both input views must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • view1[in] First Pauli expansion view.

  • view2[in] Second Pauli expansion view.

  • takeAdjoint1[in] Whether or not the adjoint of the first view is taken. True (!= 0) if the adjoint is taken, false (0) otherwise.

  • traceSignificand[out] Pointer to CPU-accessible memory where the trace’s significand will be written. The numerical type must match the data type of the views’ coefficients.

  • traceExponent[out] Pointer to CPU-accessible memory where the trace’s exponent will be stored. The numerical type is always double.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewPrepareTraceWithZeroState#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareTraceWithZeroState(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view,
int64_t maxWorkspaceDeviceSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for computing the trace of the given Pauli expansion view with the zero state, i.e. computing Tr(view * |0...0><0...0|).

This function queries the workspace requirements for subsequently calling cupaulipropPauliExpansionViewComputeTraceWithZeroState(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • view[in] Pauli expansion view to be traced.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeTraceWithZeroState#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeTraceWithZeroState(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view,
void *traceSignificand,
double *traceExponent,
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the trace of the Pauli expansion view with the zero state, i.e. Tr(view * |0...0><0...0|).

The trace is returned as two scalars - the trace’s significand and exponent (base two) - and can be reconstructed in a single scalar as trace = traceSignificand * pow(2, traceExponent). This separation is helpful for avoiding numerical precision issues due to the exponentially large range of the trace.

Note

This function is non-blocking, i.e. it will return immediately and the tracing will be performed asynchronously on the stream.

Note

The storage location of the input view must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • view[in] Pauli expansion view to be traced.

  • traceSignificand[out] Pointer to CPU-accessible memory where the trace’s significand will be written. The numerical type must match the data type of the views’ coefficients.

  • traceExponent[out] Pointer to CPU-accessible memory where the trace’s exponent will be stored. The numerical type is always double.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Backward Differentiation of Trace Operations#

cupaulipropPauliExpansionViewPrepareTraceWithExpansionViewBackwardDiff#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareTraceWithExpansionViewBackwardDiff(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view1,
const cupaulipropPauliExpansionView_t view2,
int64_t maxWorkspaceDeviceSize,
int64_t *requiredXZBitsBufferSize1,
int64_t *requiredCoefBufferSize1,
int64_t *requiredXZBitsBufferSize2,
int64_t *requiredCoefBufferSize2,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for backward differentiation of the trace of the product of two Pauli expansion views.

This function queries the workspace requirements for backward differentiation of the trace of two Pauli expansion views. The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • view1[in] First Pauli expansion view to be traced.

  • view2[in] Second Pauli expansion view to be traced.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • requiredXZBitsBufferSize1[out] Required size (in bytes) of the X and Z bits output buffer for cotangentExpansion1.

  • requiredCoefBufferSize1[out] Required size (in bytes) of the coefficients output buffer for cotangentExpansion1.

  • requiredXZBitsBufferSize2[out] Required size (in bytes) of the X and Z bits output buffer for cotangentExpansion2.

  • requiredCoefBufferSize2[out] Required size (in bytes) of the coefficients output buffer for cotangentExpansion2.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeTraceWithExpansionViewBackwardDiff#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeTraceWithExpansionViewBackwardDiff(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view1,
const cupaulipropPauliExpansionView_t view2,
int32_t takeAdjoint1,
const void *cotangentTraceSignificand,
const double *cotangentTraceExponent,
cupaulipropPauliExpansion_t cotangentExpansion1,
cupaulipropPauliExpansion_t cotangentExpansion2,
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the backward differentiation of the trace of two Pauli expansion views.

This function computes cotangents with respect to the coefficients of view1 and view2 for the trace of their product, separated into significand and exponent, satisfying trace = traceSignificand * pow(2, traceExponent).

Letting \(s\) and \(p\) denote the computed scalar outputs traceSignificand and traceExponent, and \(L=L(s,p)\) denote an external real-valued scalar loss defined by the caller, this function takes as input scalar cotangents \(\tilde{s} = \partial L / \partial s\) and \(\tilde{p} = \partial L / \partial p\) (passed via cotangentTraceSignificand and cotangentTraceExponent) and computes the coefficient cotangents \(\partial L / \partial c_i\) for the coefficients \(c_i\) of view1 and view2.

The output expansions cotangentExpansion1 and cotangentExpansion2 contain Pauli terms corresponding to coefficient cotangents for view1 and view2 respectively. Terms with exactly zero coefficient cotangent are discarded and may be omitted from the output expansions. The Pauli strings (X/Z bits) are treated as fixed identifiers and are not differentiated.

Note

This function is non-blocking, i.e. it will return immediately and the operation will be performed asynchronously on the stream.

Note

The storage location of both input views and both output expansions must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • view1[in] First Pauli expansion view.

  • view2[in] Second Pauli expansion view.

  • takeAdjoint1[in] Whether or not the adjoint of the first view is taken when forming the trace. True (!= 0) if the adjoint is taken, false (0) otherwise.

  • cotangentTraceSignificand[in] Pointer to host-accessible memory holding the scalar cotangent \(\tilde{s} = \partial L / \partial s\) of traceSignificand. The numerical type must match the data type of the views’ coefficients.

  • cotangentTraceExponent[in] Pointer to host-accessible memory holding the scalar cotangent \(\tilde{p} = \partial L / \partial p\) of traceExponent. This argument is currently a dead branch for coefficient cotangents, since traceExponent presently carries no parameter dependence, though beware that this may change in the future. The numerical type is always double.

  • cotangentExpansion1[out] Output Pauli expansion populated with coefficient cotangents corresponding to view1. The numerical type must match the data type of the views’ coefficients.

  • cotangentExpansion2[out] Output Pauli expansion populated with coefficient cotangents corresponding to view2. The numerical type must match the data type of the views’ coefficients.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewPrepareTraceWithZeroStateBackwardDiff#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareTraceWithZeroStateBackwardDiff(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view,
int64_t maxWorkspaceDeviceSize,
int64_t *requiredXZBitsBufferSize,
int64_t *requiredCoefBufferSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for backward differentiation of the trace with the zero state.

This function queries the workspace requirements for subsequently calling cupaulipropPauliExpansionViewComputeTraceWithZeroStateBackwardDiff(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • view[in] Pauli expansion view to be traced.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • requiredXZBitsBufferSize[out] Required size (in bytes) of the X and Z bits output buffer for the cotangent expansion.

  • requiredCoefBufferSize[out] Required size (in bytes) of the coefficients output buffer for the cotangent expansion.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeTraceWithZeroStateBackwardDiff#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeTraceWithZeroStateBackwardDiff(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t view,
const void *cotangentTraceSignificand,
const double *cotangentTraceExponent,
cupaulipropPauliExpansion_t cotangentExpansion,
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the backward differentiation of the trace of a Pauli expansion view with the zero state.

This function computes coefficient cotangents for the scalar outputs traceSignificand and traceExponent, where trace = traceSignificand * pow2(traceExponent) and trace = tr(view * |0...0><0...0|).

Letting \(s\) and \(p\) denote the computed scalar outputs traceSignificand and traceExponent, and \(L=L(s,p)\) denote an external real-valued scalar loss defined by the caller, this function takes as input scalar cotangents \(\tilde{s} = \partial L / \partial s\) and \(\tilde{p} = \partial L / \partial p\) (passed via cotangentTraceSignificand and cotangentTraceExponent) and computes the coefficient cotangents \(\partial L / \partial c_i\) for the coefficients \(c_i\) of view.

The output expansion cotangentExpansion contains Pauli terms corresponding to coefficient cotangents for view. Terms with exactly zero coefficient cotangent are discarded and may be omitted from the output expansion. The Pauli strings (X/Z bits) are treated as fixed identifiers and are not differentiated.

Note

This function is non-blocking, i.e. it will return immediately and the operation will be performed asynchronously on the stream.

Note

The storage location of the input view must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • view[in] Pauli expansion view to be traced.

  • cotangentTraceSignificand[in] Pointer to host-accessible memory holding the scalar cotangent \(\tilde{s} = \partial L / \partial s\) of traceSignificand. The numerical type must match the data type of the view’s coefficients.

  • cotangentTraceExponent[in] Pointer to host-accessible memory holding the scalar cotangent \(\tilde{p} = \partial L / \partial p\) of traceExponent. This argument is currently a dead branch for coefficient cotangents, since traceExponent presently carries no parameter dependence, though beware that this may change in the future. The numerical type is always double.

  • cotangentExpansion[out] Output Pauli expansion populated with coefficient cotangents corresponding to view. The numerical type must match the data type of the view’s coefficients.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Operator Application#

cupaulipropPauliExpansionViewPrepareOperatorApplication#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareOperatorApplication(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
const cupaulipropQuantumOperator_t quantumOperator,
cupaulipropSortOrder_t sortOrder,
int32_t keepDuplicates,
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
int64_t maxWorkspaceDeviceSize,
int64_t *requiredXZBitsBufferSize,
int64_t *requiredCoefBufferSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for quantum operator application.

This function queries the workspace requirements for subsequently calling cupaulipropPauliExpansionViewComputeOperatorApplication(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to apply a quantum operator to.

  • quantumOperator[in] Quantum operator to be applied.

  • sortOrder[in] Sort order to apply to the output expansion. Use CUPAULIPROP_SORT_ORDER_NONE if sorting is not required. Currently, only CUPAULIPROP_SORT_ORDER_INTERNAL and CUPAULIPROP_SORT_ORDER_NONE are supported.

  • keepDuplicates[in] Whether or not the output expansion is allowed to contain duplicates.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • requiredXZBitsBufferSize[out] Required size (in bytes) of the X and Z bits output buffer.

  • requiredCoefBufferSize[out] Required size (in bytes) of the coefficients output buffer.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeOperatorApplication#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeOperatorApplication(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropPauliExpansion_t expansionOut,
const cupaulipropQuantumOperator_t quantumOperator,
int32_t adjoint,
cupaulipropSortOrder_t sortOrder,
int32_t keepDuplicates,
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the application of a quantum operator to a Pauli expansion view.

This function computes the application of a quantum operator to a Pauli expansion view. Optionally, the adjoint of the quantum operator can be applied when computing the application. Optionally, truncations can be applied to the output expansion to reduce the number of terms.

Note

This function is blocking on exit, i.e. it will wait for the operation to complete before returning to the caller.

Note

The storage location of the input view and the output expansion must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to apply a quantum operator to.

  • expansionOut[inout] Pauli expansion to be overwritten with the result. The terms of the output expansion will be sorted with respect to the specified sortOrder and their Pauli strings will be unique if keepDuplicates is set to false. Their state is queryable on the output expansion after this function call via cupaulipropPauliExpansionGetSortOrder() and cupaulipropPauliExpansionIsDeduplicated().

  • quantumOperator[in] Quantum operator to be applied.

  • adjoint[in] Whether or not the adjoint of the quantum operator is applied. True (!= 0) if the adjoint is applied, false (0) otherwise.

  • sortOrder[in] Sort order to apply to the output expansion. Use CUPAULIPROP_SORT_ORDER_NONE if sorting is not required. Currently, only CUPAULIPROP_SORT_ORDER_INTERNAL and CUPAULIPROP_SORT_ORDER_NONE are supported.

  • keepDuplicates[in] Whether or not the output expansion is allowed to contain duplicates.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Fused Operator Application#

cupaulipropPauliExpansionViewPrepareOperatorFusedApplication#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareOperatorFusedApplication(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
int32_t numQuantumOperators,
const cupaulipropQuantumOperator_t quantumOperators[],
const int32_t adjoints[],
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
int64_t maxWorkspaceDeviceSize,
int64_t *minExpansionOutCapacity,
cupaulipropWorkspaceDescriptor_t minWorkspace,
int64_t *averageExpansionOutCapacity,
cupaulipropWorkspaceDescriptor_t averageWorkspace,
int64_t *maxExpansionOutCapacity,
cupaulipropWorkspaceDescriptor_t maxWorkspace
)#

Updates the given workspace descriptors and expansion buffer sizes in preparation for fused quantum operator application.

This function queries the workspace and output expansion term-capacity requirements for subsequently calling cupaulipropPauliExpansionViewComputeOperatorFusedApplication(). Unlike the single operator functions, fused operators can be applied without providing sufficient workspace or output expansion capacity for the worst case expansion growth, and the operation may incidentally succeed or fail on the fly. Therefore this prepare function modifies three workspace descriptors and output expansion term capacities, giving the minimum, maximum, and average memory needed by the subsequent apply-fused-operator function, in the respective scenarios of least, most expansion and expected expansion growth.

The workspace results are attached to the workspace descriptors and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be attached to a workspace subsequently passed to the corresponding operator-application function via cupaulipropWorkspaceSetMemory(). Attaching a buffer size which interpolates the minimum and maximum output workspace sizes forms a tradeoff between workspace size and apply-operation success probability.

Passing maxWorkspace (with the advised attached buffer) and an expansion with term capacity of at least maxExpansionOutCapacity to cupaulipropPauliExpansionViewComputeOperatorFusedApplication() will guarantee the fused operation succeeds. In contrast, passing minWorkspace with attached buffers smaller than maxWorkspace, and/or an output expansion with term capacity smaller than maxExpansionOutCapacity, may cause the operation to fail on the fly due to infeasible expansion growth. It remains necessary to supply a workspace larger than minWorkspace, and an output expansion with term capacity of at least minExpansionOutCapacity.

The averageWorkspace (and corresponding averageExpansionOutCapacity) indicates the memory necessary to handle the average expansion growth, as results from every operator inducing the expected expansion growth when treating the input Pauli strings as uniformly random. This is informed by the Pauli transfer matrix of the fused operators, and is typically significantly smaller than the average of the above minimum and maximum memory requirements. It is advisable to supply memory slightly larger than these indicated sizes (e.g. 20% more), so that variations from the expected value are supported.

Since memory costs can grow exponentially with numQuantumOperators, it is possible for the calculated average-case and worst-case memory requirements (averageExpansionOutCapacity, averageWorkspace, maxExpansionOutCapacity and maxWorkspace) to overflow. When this happens, those overflowed quantities are set to -1 and should not be consulted. The remaining outputs remain valid, and no error is returned.

Some fused-operator pathways have hardware-imposed limits on the number of operators that can be fused. If the given operator sequence exceeds such a limit, this function returns CUPAULIPROP_STATUS_INSUFFICIENT_DEVICE_PROPERTY. In that case, the output memory quantities should not be consulted, and the user should reduce the number of fused operators before retrying.

The user given maxWorkspaceDeviceSize specifies the user’s memory budget for the workspace. If exceeded by the established minWorkspace memory, an error is returned. Otherwise, it can inform which internal strategies will be used by the subsequent operator-application function, affecting the necessary workspace.

Note

This function is experimental and is subject to change in future releases.

Note

Presently, only Clifford gates and Pauli noise channels are supported. As these are both “non-branching” operators, the min, max and average workspace and capacity outputs of this function are presently all equal.

Note

This function performs the same input validation as cupaulipropPauliExpansionViewComputeOperatorFusedApplication(), and so has the same limitations upon operator kind and support.

Note

This function may be sensitive to the ordering of quantumOperators, and so precisely the same quantumOperators must be subsequently passed to cupaulipropPauliExpansionViewComputeOperatorFusedApplication().

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to apply quantumOperators upon.

  • numQuantumOperators[in] The length of quantumOperators.

  • quantumOperators[in] The sequence of operators to apply upon viewIn.

  • adjoints[in] A sequence specifying whether each corresponding operator is to be adjointed.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • minExpansionOutCapacity[out] Minimum term capacity of the output expansion needed to begin the subsequent compute call.

  • minWorkspace[out] Workspace descriptor to be updated with the minimum workspace necessary to begin the subsequent compute call.

  • averageExpansionOutCapacity[out] Expected term count of the output expansion, resulting from each fused operator inducing the expected growth of the input expansion. A typical-case sizing hint between minExpansionOutCapacity and maxExpansionOutCapacity.

  • averageWorkspace[out] Workspace descriptor to be updated with the workspace needed under the estimated average-case scenario.

  • maxExpansionOutCapacity[out] Maximum necessary term capacity of the output expansion, which would guarantee that operator application succeeds (assuming workspace is sufficient).

  • maxWorkspace[out] Workspace descriptor to be updated with the maximum workspace necessary to guarantee operator application succeeds.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeOperatorFusedApplication#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeOperatorFusedApplication(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropPauliExpansion_t expansionOut,
int32_t numQuantumOperators,
const cupaulipropQuantumOperator_t quantumOperators[],
const int32_t adjoints[],
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the application of a sequence of same-kind quantum operators upon a Pauli expansion view in a fused fashion.

This function attempts to apply the entire sequence of quantum operators in a fused fashion, which is often more efficient than applying each operator in-turn via single-operator application. This function applies operators quantumOperators[0] through quantumOperators[numQuantumOperators-1] in order, where each is adjointed according to the corresponding flag in adjoints.

Semantically, this is a multi-operator analogue of cupaulipropPauliExpansionViewComputeOperatorApplication(), but there are several important nuances:

  • This function accepts workspace and output expansion sizes smaller than the worst case requirements, which may be otherwise intractable for large numQuantumOperators. Fused application may therefore fail on the fly due to insufficient workspace memory or output expansion capacity. These failures are returned as CUPAULIPROP_STATUS_INSUFFICIENT_WORKSPACE and CUPAULIPROP_STATUS_INSUFFICIENT_OUT_EXPANSION respectively. Workspace and output buffer sizing should be chosen according to the sizes output by cupaulipropPauliExpansionViewPrepareOperatorFusedApplication().

  • The given operator sequence may exceed a hardware-imposed fused-launch limitation (e.g. the combined per-launch shared-memory footprint of all operators must fit within the device’s per-block shared-memory capacity). In this case, CUPAULIPROP_STATUS_INSUFFICIENT_DEVICE_PROPERTY is returned, no kernel is launched, and the output expansion expansionOut is left untouched. The same status code is returned by cupaulipropPauliExpansionViewPrepareOperatorFusedApplication() given the same operator sequence, so this condition can be detected ahead of time during the prepare phase.

  • The single-operator parameters sortOrder and keepDuplicates are not accepted here; the postconditions of the output expansion are left at the discretion of this function. Presently, these are:

    • Pauli noise channels maintain sortedness and deduplication of viewIn.

    • Clifford gates maintain deduplication but not sortedness of viewIn.

  • The specified truncation is performed once, after the final operator is applied. This can result in a distinct output expansion than that produced by applying each operator in-turn via single-operator application passing the same truncation parameters.

The maximum number of quantum operators that can be passed will be limited by properties specific to the family of operator, its combined support, and its branching behaviour (how many Pauli strings it can produce from a single input string). The number of quantum operators for which this function outperforms application of each operator in-turn via cupaulipropPauliExpansionViewComputeOperatorApplication() will also vary by these properties, and potentially by hardware characteristics.

Note

This function is experimental and is subject to change in future releases.

Note

Presently, only Clifford gates and Pauli noise channels are supported.

Note

Only quantum operators of the same kind (e.g. all Pauli noise channels) are presently supported.

Note

This function is blocking on exit, i.e. it will wait for the operation to complete before returning to the caller.

Note

The storage location of viewIn and expansionOut must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to apply the operator sequence upon.

  • expansionOut[inout] Pauli expansion to be overwritten with the result.

  • numQuantumOperators[in] Length of quantumOperators and adjoints.

  • quantumOperators[in] Sequence of quantum operators given in order of their intended application.

  • adjoints[in] A sequence of flags indicating whether to adjoint the corresponding operator.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • workspace[in] Workspace descriptor with memory attached per cupaulipropPauliExpansionViewPrepareOperatorFusedApplication().

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Backward Differentiation of Operator Application#

cupaulipropPauliExpansionViewPrepareOperatorApplicationBackwardDiff#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareOperatorApplicationBackwardDiff(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
const cupaulipropPauliExpansionView_t cotangentOut,
const cupaulipropQuantumOperator_t quantumOperator,
cupaulipropSortOrder_t sortOrder,
int32_t keepDuplicates,
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
int64_t maxWorkspaceDeviceSize,
int64_t *requiredXZBitsBufferSize,
int64_t *requiredCoefBufferSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for backward differentiation of quantum operator application.

Consider the forward computation \(y = F(x)\) where \(F\) denotes applying quantumOperator to viewIn. Let \(L=L(y)\) denote an external scalar loss defined by the caller, and let \(\tilde{y}=\partial L/\partial y\) denote the cotangent of the output \(y\) provided via cotangentOut. This function prepares the workspace requirements for computing the pullback \(\tilde{x}=\partial L/\partial x\) (written to cotangentIn in the corresponding compute function) and for updating the parameter adjoints stored in the quantum operator’s attached cotangent buffer.

The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Input Pauli expansion view (forward input) corresponding to \(x\).

  • cotangentOut[in] Output cotangent \(\tilde{y}=\partial L/\partial y\) represented as a Pauli expansion view.

  • quantumOperator[in] Quantum operator whose cotangent buffer will be updated during the compute function.

  • sortOrder[in] Sort order to apply to the output expansion. Use CUPAULIPROP_SORT_ORDER_NONE if sorting is not required. Currently, only CUPAULIPROP_SORT_ORDER_INTERNAL and CUPAULIPROP_SORT_ORDER_NONE are supported.

  • keepDuplicates[in] Whether or not the output expansion is allowed to contain duplicates.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • requiredXZBitsBufferSize[out] Required size (in bytes) of the X and Z bits output buffer.

  • requiredCoefBufferSize[out] Required size (in bytes) of the coefficients output buffer.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewComputeOperatorApplicationBackwardDiff#

cupaulipropStatus_t cupaulipropPauliExpansionViewComputeOperatorApplicationBackwardDiff(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
const cupaulipropPauliExpansionView_t cotangentOut,
cupaulipropPauliExpansion_t cotangentIn,
cupaulipropQuantumOperator_t quantumOperator,
int32_t adjoint,
cupaulipropSortOrder_t sortOrder,
int32_t keepDuplicates,
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Computes the backward differentiation of the application of a quantum operator to a Pauli expansion view.

Consider the forward computation \(y = F(x)\) where \(F\) denotes applying quantumOperator to viewIn. Let \(L=L(y)\) denote an external scalar loss defined by the caller, and let \(\tilde{y}=\partial L/\partial y\) denote the cotangent of the output \(y\) provided via cotangentOut. This function computes the input cotangent \(\tilde{x}=\partial L/\partial x\) (written to cotangentIn) and updates the parameter cotangents stored in the quantum operator’s attached cotangent buffer.

Note

This function is blocking on exit, i.e. it will wait for the operation to complete before returning to the caller.

Note

The storage location of the input view, the cotangentOut view, and the cotangentIn expansion must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Input Pauli expansion view (forward input) corresponding to \(x\).

  • cotangentOut[in] Output cotangent \(\tilde{y}=\partial L/\partial y\) represented as a Pauli expansion view.

  • cotangentIn[inout] Pauli expansion populated with the input cotangent \(\tilde{x}=\partial L/\partial x\).

  • quantumOperator[inout] Quantum operator whose cotangent buffer will be updated.

  • adjoint[in] Whether or not the adjoint of the quantum operator is applied. True (!= 0) if the adjoint is applied, false (0) otherwise.

  • sortOrder[in] Sort order to apply to the output expansion. Use CUPAULIPROP_SORT_ORDER_NONE if sorting is not required. Currently, only CUPAULIPROP_SORT_ORDER_INTERNAL and CUPAULIPROP_SORT_ORDER_NONE are supported.

  • keepDuplicates[in] Whether or not the output expansion is allowed to contain duplicates.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Truncation Operations#

cupaulipropPauliExpansionViewPrepareTruncation#

cupaulipropStatus_t cupaulipropPauliExpansionViewPrepareTruncation(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
int64_t maxWorkspaceDeviceSize,
cupaulipropWorkspaceDescriptor_t workspace
)#

Updates the given workspace descriptor in preparation for truncation of a Pauli expansion view.

This function queries the workspace requirements for subsequently calling cupaulipropPauliExpansionViewExecuteTruncation(). The results are attached to the workspace descriptor and can be subsequently queried via cupaulipropWorkspaceGetMemorySize(). Appropriately sized buffers must then be (re)attached via cupaulipropWorkspaceSetMemory().

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Pauli expansion view to be truncated.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • maxWorkspaceDeviceSize[in] Maximum workspace device-memory size limit in bytes.

  • workspace[out] Workspace descriptor to be updated with the required workspace buffer size.

Returns:

cupaulipropStatus_t


cupaulipropPauliExpansionViewExecuteTruncation#

cupaulipropStatus_t cupaulipropPauliExpansionViewExecuteTruncation(
const cupaulipropHandle_t handle,
const cupaulipropPauliExpansionView_t viewIn,
cupaulipropPauliExpansion_t expansionOut,
int32_t numTruncationStrategies,
const cupaulipropTruncationStrategy_t truncationStrategies[],
cupaulipropWorkspaceDescriptor_t workspace,
cudaStream_t stream
)#

Truncates a Pauli expansion view.

This function applies truncation strategies to a Pauli expansion view, removing terms that do not satisfy the truncation criteria, and writes the result to the output expansion.

Note

This function is blocking on exit, i.e. it will wait for the operation to complete before returning to the caller.

Note

The storage location of the input view and the output expansion must be GPU-accessible (i.e. CUPAULIPROP_MEMSPACE_DEVICE).

Parameters:
  • handle[in] Library handle.

  • viewIn[in] Input Pauli expansion view to be truncated.

  • expansionOut[inout] Output Pauli operator expansion.

  • numTruncationStrategies[in] Number of Pauli expansion truncation strategies.

  • truncationStrategies[in] Pauli expansion truncation strategies.

  • workspace[in] Allocated workspace descriptor.

  • stream[in] CUDA stream to be used for the operation.

Returns:

cupaulipropStatus_t


Quantum Operators#

Clifford Gates#

cupaulipropCreateCliffordGateOperator#

cupaulipropStatus_t cupaulipropCreateCliffordGateOperator(
const cupaulipropHandle_t handle,
cupaulipropCliffordGateKind_t cliffordGateKind,
const int32_t qubitIndices[],
cupaulipropQuantumOperator_t *oper
)#

Creates a Clifford gate.

For two-qubit Clifford gates, qubitIndices are specified with increasing significance, and so the control qubit (in gates such as CUPAULIPROP_CLIFFORD_GATE_CX) is specified after the target qubit.

Parameters:
  • handle[in] Library handle.

  • cliffordGateKind[in] Clifford gate kind.

  • qubitIndices[in] Qubit indices.

  • oper[out] Quantum operator associated with the Clifford gate.

Returns:

cupaulipropStatus_t


Pauli Rotation Gates#

cupaulipropCreatePauliRotationGateOperator#

cupaulipropStatus_t cupaulipropCreatePauliRotationGateOperator(
const cupaulipropHandle_t handle,
double angle,
int32_t numQubits,
const int32_t qubitIndices[],
const cupaulipropPauliKind_t paulis[],
cupaulipropQuantumOperator_t *oper
)#

Creates a Pauli rotation gate, exp(-i * angle/2 * P), for a rotation of angle around the Pauli string P.

Parameters:
  • handle[in] Library handle.

  • angle[in] Rotation angle in radians.

  • numQubits[in] Number of qubits.

  • qubitIndices[in] Qubit indices. If NULL, the qubit indices are assumed to be [0, 1, 2, …, numQubits-1].

  • paulis[in] Pauli operators for each qubit index.

  • oper[out] Quantum operator associated with the Pauli rotation gate.

Returns:

cupaulipropStatus_t


Pauli Noise Channels#

cupaulipropCreatePauliNoiseChannelOperator#

cupaulipropStatus_t cupaulipropCreatePauliNoiseChannelOperator(
const cupaulipropHandle_t handle,
int32_t numQubits,
const int32_t qubitIndices[],
const double probabilities[],
cupaulipropQuantumOperator_t *oper
)#

Creates a Pauli noise channel.

Parameters:
  • handle[in] Library handle.

  • numQubits[in] Number of qubits. Only 1 and 2 qubits are supported.

  • qubitIndices[in] Qubit indices.

  • probabilities[in] Probabilities for each Pauli channel. For a single qubit Pauli Channel, the probabilities are an array of length 4: PauliKind((i)%4) (i.e. [p_I, p_X, p_Y, p_Z]). For a two qubit Pauli Channel, probabilities is an array of length 16. The i-th element of the probabilities is associated with the i-th element of the 2-qubit Pauli strings in lexicographic order. E.g. prob[i] corresponds to the Pauli string PauliKind((i)%4), PauliKind_t((i)/4).

  • oper[out] Quantum operator associated with the Pauli channel.

Returns:

cupaulipropStatus_t

Amplitude Damping Channels#

cupaulipropCreateAmplitudeDampingChannelOperator#

cupaulipropStatus_t cupaulipropCreateAmplitudeDampingChannelOperator(
const cupaulipropHandle_t handle,
int32_t qubitIndex,
double dampingProb,
double exciteProb,
cupaulipropQuantumOperator_t *oper
)#

Creates a generalized amplitude damping channel.

Letting \(\gamma=\) dampingProb and \(p=\) exciteProb, this channel is described by Kraus operators:

\[\begin{split} K_0 = \sqrt{1-p} \begin{pmatrix} 1 & 0 \\ 0 & \sqrt{1-\gamma} \end{pmatrix} \\ K_1 = \sqrt{1-p} \begin{pmatrix} 0 & \sqrt{\gamma} \\ 0 & 0 \end{pmatrix} \\ K_2 = \sqrt{p} \begin{pmatrix} \sqrt{1-\gamma} & 0 \\ 0 & 1 \end{pmatrix} \\ K_3 = \sqrt{p} \begin{pmatrix} 0 & 0 \\ \sqrt{\gamma} & 0 \end{pmatrix} \end{split}\]

Parameters:
  • handle[in] Library handle.

  • qubitIndex[in] Index of qubit upon which to operate.

  • dampingProb[in] Probability that the qubit is damped, i.e. decohered into a classical state.

  • exciteProb[in] Probability that damping results in excitation (driving to the one state) rather than dissipation (driving to the zero state). Set to zero for conventional, dissipative amplitude damping.

  • oper[out] Quantum operator associated with the channel.

Returns:

cupaulipropStatus_t


Operator Queries and Management#

cupaulipropQuantumOperatorAttachCotangentBuffer#

cupaulipropStatus_t cupaulipropQuantumOperatorAttachCotangentBuffer(
const cupaulipropHandle_t handle,
cupaulipropQuantumOperator_t oper,
void *cotangentBuffer,
int64_t cotangentBufferSize,
cudaDataType_t dataType,
cupaulipropMemspace_t location
)#

Attaches a cotangent buffer to a quantum operator.

The cotangent buffer stores parameter gradients produced by backward operations. cotangentBufferSize is the buffer size in bytes and must satisfy cotangentBufferSize >= numElements * elementSize, where numElements is the operator’s number of differentiable parameters (queryable via cupaulipropQuantumOperatorGetCotangentBuffer) and elementSize is the byte size of dataType. The dataType must match the expansion’s coefficient data type at backward-differentiation time.

Parameters:
  • handle[in] Library handle.

  • oper[inout] Quantum operator.

  • cotangentBuffer[in] Pointer to user-owned cotangent buffer.

  • cotangentBufferSize[in] Size of the buffer in bytes.

  • dataType[in] Data type of elements in the cotangent buffer.

  • location[in] Memory location of the buffer (host or device).

Returns:

cupaulipropStatus_t


cupaulipropQuantumOperatorGetCotangentBuffer#

cupaulipropStatus_t cupaulipropQuantumOperatorGetCotangentBuffer(
const cupaulipropHandle_t handle,
const cupaulipropQuantumOperator_t oper,
void **cotangentBuffer,
int64_t *cotangentBufferNumElements,
cudaDataType_t *dataType,
cupaulipropMemspace_t *location
)#

Retrieves the cotangent buffer attached to a quantum operator.

Parameters:
  • handle[in] Library handle.

  • oper[in] Quantum operator.

  • cotangentBuffer[out] Pointer to the attached cotangent buffer. If no buffer is attached, this pointer is set to NULL.

  • cotangentBufferNumElements[out] Required element count (number of differentiable parameters).

  • dataType[out] Data type of elements in the attached buffer. If no buffer is attached, this pointer is set to cudaDataType_t CUPAULIPROP_DATA_TYPE_INVALID.

  • location[out] Memory location of the attached buffer. If no buffer is attached, this pointer is set to cupaulipropMemspace_t CUPAULIPROP_MEMSPACE_DEVICE.

Returns:

cupaulipropStatus_t


cupaulipropDestroyOperator#

cupaulipropStatus_t cupaulipropDestroyOperator(
cupaulipropQuantumOperator_t oper
)#

Destroys a quantum operator.

Parameters:

oper[in] Quantum operator.

Returns:

cupaulipropStatus_t