cuStateVec Functions #################### .. role:: raw-html(raw) :format: html Library Management ****************** Handle Management API ===================== .. _custatevecCreate-label: :code:`custatevecCreate` ------------------------ .. doxygenfunction:: custatevecCreate ---- .. _custatevecDestroy-label: :code:`custatevecDestroy` ------------------------- .. doxygenfunction:: custatevecDestroy ---- .. _custatevecGetDefaultWorkspaceSize-label: :code:`custatevecGetDefaultWorkspaceSize` ----------------------------------------- .. doxygenfunction:: custatevecGetDefaultWorkspaceSize ---- .. _custatevecSetWorkspace-label: :code:`custatevecSetWorkspace` ------------------------------------- .. doxygenfunction:: custatevecSetWorkspace CUDA Stream Management API ========================== .. _custatevecSetStream-label: :code:`custatevecSetStream` --------------------------- .. doxygenfunction:: custatevecSetStream ---- .. _custatevecGetStream-label: :code:`custatevecGetStream` --------------------------- .. doxygenfunction:: custatevecGetStream Error Management API ==================== .. _custatevecGetErrorName-label: :code:`custatevecGetErrorName` ------------------------------ .. doxygenfunction:: custatevecGetErrorName ---- .. _custatevecGetErrorString-label: :code:`custatevecGetErrorString` -------------------------------- .. doxygenfunction:: custatevecGetErrorString Logger API ========== .. _custatevecLoggerSetCallback-label: :code:`custatevecLoggerSetCallback` ----------------------------------- .. doxygenfunction:: custatevecLoggerSetCallback ---- .. _custatevecLoggerSetFile-label: :code:`custatevecLoggerSetFile` ------------------------------- .. doxygenfunction:: custatevecLoggerSetFile ---- .. _custatevecLoggerOpenFile-label: :code:`custatevecLoggerOpenFile` -------------------------------- .. doxygenfunction:: custatevecLoggerOpenFile ---- .. _custatevecLoggerSetLevel-label: :code:`custatevecLoggerSetLevel` -------------------------------- .. doxygenfunction:: custatevecLoggerSetLevel ---- .. _custatevecLoggerSetMask-label: :code:`custatevecLoggerSetMask` ------------------------------- .. doxygenfunction:: custatevecLoggerSetMask ---- .. _custatevecLoggerForceDisable-label: :code:`custatevecLoggerForceDisable` ------------------------------------ .. doxygenfunction:: custatevecLoggerForceDisable Versioning API ============== .. _custatevecGetProperty-label: :code:`custatevecGetProperty` ----------------------------- .. doxygenfunction:: custatevecGetProperty ---- .. _custatevecGetVersion-label: :code:`custatevecGetVersion` ----------------------------- .. doxygenfunction:: custatevecGetVersion Gate Application **************** General Matrices ================ cuStateVec API `custatevecApplyMatrix` can apply a matrix representing a gate to a state vector. The API may require external workspace for large matrices, and `custatevecApplyMatrix_bufferSize` provides the size of workspace. Use case -------- .. code-block:: cpp // check the size of external workspace custatevecApplyMatrix_bufferSize( handle, svDataType, nIndexBits, matrix, matrixDataType, layout, adjoint, nTargets, nControls, computeType, &extraWorkspaceSizeInBytes); // allocate external workspace if necessary void* extraWorkspace = nullptr; if (extraWorkspaceSizeInBytes > 0) cudaMalloc(&extraWorkspace, extraWorkspaceSizeInBytes); // apply gate custatevecApplyMatrix( handle, sv, svDataType, nIndexBits, matrix, matrixDataType, layout, adjoint, targets, nTargets, controls, nControls, controlBitValues, computeType, extraWorkspace, extraWorkspaceSizeInBytes); API reference ------------- .. _custatevecApplyMatrix_bufferSize-label: :code:`custatevecApplyMatrix_bufferSize` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecApplyMatrix_bufferSize ---- .. _custatevecApplyMatrix-label: :code:`custatevecApplyMatrix` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecApplyMatrix Pauli Matrices ============== Exponential of a tensor product of Pauli matrices can be expressed as follows: .. math:: e^{i \theta \left( P_{target[0]} \otimes P_{target[1]} \otimes \cdots \otimes P_{target[nTargets-1]} \right)}. Matrix :math:`P_{target[i]}` can be either of Pauli matrices :math:`I`, :math:`X`, :math:`Y`, and :math:`Z`, which are corresponding to the `custatevecPauli_t` enums `CUSTATEVEC_PAULI_I`, `CUSTATEVEC_PAULI_X`, `CUSTATEVEC_PAULI_Y`, and `CUSTATEVEC_PAULI_Z`, respectively. Also refer to :ref:`custatevecPauli_t` for details. Use case -------- .. code-block:: cpp // apply exponential custatevecApplyExp( handle, sv, svDataType, nIndexBits, theta, paulis, targets, nTargets, controls, controlBitValues, nControls); API reference ------------- .. _custatevecApplyExp-label: :code:`custatevecApplyExp` ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecApplyExp Generalized Permutation Matrices ================================ A generalized permutation matrix can be expressed as the multiplication of a permutation matrix :math:`P` and a diagonal matrix :math:`D`. For instance, we can decompose a 4 :math:`\times` 4 generalized permutation matrix :math:`A` as follows: .. math:: A = \left[ \begin{array}{cccc} 0 & 0 & a_0 & 0 \\ a_1 & 0 & 0 & 0 \\ 0 & 0 & 0 & a_2 \\ 0 & a_3 & 0 & 0 \end{array}\right] = DP , where .. math:: D = \left[ \begin{array}{cccc} a_0 & 0 & 0 & 0 \\ 0 & a_1 & 0 & 0 \\ 0 & 0 & a_2 & 0 \\ 0 & 0 & 0 & a_3 \end{array}\right], P = \left[ \begin{array}{cccc} 0 & 0 & 1 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 1 & 0 & 0 \end{array}\right]. When :math:`P` is diagonal, the generalized permutation matrix is also diagonal. Similarly, when :math:`D` is the identity matrix, the generalized permutation matrix becomes a permutation matrix. The cuStateVec API `custatevecApplyGeneralizedPermutationMatrix` applies a generalized permutation matrix like :math:`A` to a state vector. The API may require extra workspace for large matrices, whose size can be queried using `custatevecApplyGeneralizedPermutationMatrix_bufferSize`. Use case -------- .. code-block:: cpp // check the size of external workspace custatevecApplyGeneralizedPermutationMatrix_bufferSize( handle, CUDA_C_64F, nIndexBits, permutation, diagonals, CUDA_C_64F, basisBits, nBasisBits, maskLen, &extraWorkspaceSizeInBytes); // allocate external workspace if necessary void* extraWorkspace = nullptr; if (extraWorkspaceSizeInBytes > 0) cudaMalloc(&extraWorkspace, extraWorkspaceSizeInBytes); // apply a generalized permutation matrix custatevecApplyGeneralizedPermutationMatrix( handle, d_sv, CUDA_C_64F, nIndexBits, permutation, diagonals, CUDA_C_64F, adjoint, basisBits, nBasisBits, maskBitString, maskOrdering, maskLen, extraWorkspace, extraWorkspaceSizeInBytes); The operation is equivalent to the following: .. code-block:: cpp // sv, sv_temp: the state vector and temporary buffer. int64_t sv_size = int64_t{1} << nIndexBits; for (int64_t sv_idx = 0; sv_idx < sv_size; sv_idx++) { // The basis of sv_idx is converted to permutation basis to obtain perm_idx auto perm_idx = convertToPermutationBasis(sv_idx); // apply generalized permutation matrix if (adjoint == 0) sv_temp[sv_idx] = sv[permutation[perm_idx]] * diagonals[perm_idx]; else sv_temp[permutation[perm_idx]] = sv[sv_idx] * conj(diagonals[perm_idx]); } for (int64_t sv_idx = 0; sv_idx < sv_size; sv_idx++) sv[sv_idx] = sv_temp[sv_idx]; API reference ------------- .. _custatevecApplyGeneralizedPermutationMatrix_bufferSize-label: :code:`custatevecApplyGeneralizedPermutationMatrix_bufferSize` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecApplyGeneralizedPermutationMatrix_bufferSize ---- .. _custatevecApplyGeneralizedPermutationMatrix-label: :code:`custatevecApplyGeneralizedPermutationMatrix` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecApplyGeneralizedPermutationMatrix Measurement *********** Measurement on Z-bases ====================== Let us consider the measurement of an :math:`nIndexBits`-qubit state vector :math:`sv` on an :math:`nBasisBits`-bit Z product basis :math:`basisBits`. The sums of squared absolute values of state vector elements on the Z product basis, :math:`abs2sum0` and :math:`abs2sum1`, are obtained by the followings: .. math:: abs2sum0 &= \Bra{sv} \left\{ \dfrac{1}{2} \left( 1 + Z_{basisBits[0]} \otimes Z_{basisBits[1]} \otimes \cdots \otimes Z_{basisBits[nBasisBits-1]} \right) \right\} \Ket{sv}, \\ abs2sum1 &= \Bra{sv} \left\{ \dfrac{1}{2} \left( 1 - Z_{basisBits[0]} \otimes Z_{basisBits[1]} \otimes \cdots \otimes Z_{basisBits[nBasisBits-1]} \right) \right\} \Ket{sv}. Therefore, probabilities to obtain parity 0 and 1 are expressed in the following expression: .. math:: Pr(parity = 0) &= \dfrac{abs2sum0}{abs2sum0 + abs2sum1}, \\ Pr(parity = 1) &= \dfrac{abs2sum1}{abs2sum0 + abs2sum1}. Depending on the measurement result, the state vector is collapsed. If parity is equal to 0, we obtain the following vector: .. math:: \ket{sv} = \dfrac{1}{\sqrt{norm}} \left\{ \dfrac{1}{2} \left( 1 + Z_{basisBits[0]} \otimes Z_{basisBits[1]} \otimes \cdots \otimes Z_{basisBits[nBasisBits-1]} \right) \right\} \Ket{sv}, and if parity is equal to 1, we obtain the following vector: .. math:: \ket{sv} = \dfrac{1}{\sqrt{norm}} \left\{ \dfrac{1}{2} \left( 1 - Z_{basisBits[0]} \otimes Z_{basisBits[1]} \otimes \cdots \otimes Z_{basisBits[nBasisBits-1]} \right) \right\} \Ket{sv}, where :math:`norm` is the normalization factor. Use case -------- We can measure by `custatevecMeasureOnZBasis` as follows: .. code-block:: cpp // measure on a Z basis custatevecMeasureOnZBasis( handle, sv, svDataType, nIndexBits, &parity, basisBits, nBasisBits, randnum, collapse); The operation is equivalent to the following: .. code-block:: cpp // compute the sums of squared absolute values of state vector elements // on a Z product basis double abs2sum0, abs2sum1; custatevecAbs2SumOnZBasis( handle, sv, svDataType, nIndexBits, &abs2sum0, &abs2sum1, basisBits, nBasisBits); // [User] compute parity and norm double abs2sum = abs2sum0 + abs2sum1; int parity = (randnum * abs2sum < abs2sum0) ? 0 : 1; double norm = (parity == 0) ? abs2sum0 : abs2sum1; // collapse if necessary switch (collapse) { case CUSTATEVEC_COLLAPSE_NORMALIZE_AND_ZERO: custatevecCollapseOnZBasis( handle, sv, svDataType, nIndexBits, parity, basisBits, nBasisBits, norm); break; /* collapse */ case CUSTATEVEC_COLLAPSE_NONE: break; /* Do nothing */ API reference ------------- .. _custatevecAbs2SumOnZBasis-label: :code:`custatevecAbs2SumOnZBasis` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecAbs2SumOnZBasis ---- .. _custatevecCollapseOnZBasis-label: :code:`custatevecCollapseOnZBasis` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecCollapseOnZBasis ---- .. _custatevecMeasureOnZBasis-label: :code:`custatevecMeasureOnZBasis` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecMeasureOnZBasis Batched Single Qubit Measurement ================================ Assume that we measure an :math:`nIndexBits`-qubits state vector :math:`sv` with a :math:`bitOrderingLen`-bits bit string :math:`bitOrdering`. The sums of squared absolute values of state vector elements are obtained by the following: .. math:: abs2sum[idx] = \braket{sv|i}\braket{i|sv}, where :math:`idx = b_{BitOrderingLen-1}\cdots b_1 b_0`, :math:`i = b_{bitOrdering[BitOrderingLen-1]} \cdots b_{bitOrdering[1]} b_{bitOrdering[0]}`, :math:`b_p \in \{0, 1\}`. Therefore, probability to obtain the :math:`idx`-th pattern of bits are expressed in the following expression: .. math:: Pr(idx) = \dfrac{abs2sum[idx]}{\sum_{k}abs2sum[k]}. Depending on the measurement result, the state vector is collapsed. If :math:`idx` satisfies :math:`(idx \ \& \ bitString) = idx`, we obtain :math:`sv[idx] = \dfrac{1}{\sqrt{norm}} sv[idx]`. Otherwise, :math:`sv[idx] = 0`, where :math:`norm` is the normalization factor. Use case -------- We can measure by `custatevecBatchMeasure` as follows: .. code-block:: cpp // measure with a bit string custatevecBatchMeasure( handle, sv, svDataType, nIndexBits, bitString, bitOrdering, bitStringLen, randnum, collapse); The operation is equivalent to the following: .. code-block:: cpp // compute the sums of squared absolute values of state vector elements int maskLen = 0; int* maskBitString = nullptr; int* maskOrdering = nullptr; custatevecAbs2SumArray( handle, sv, svDataType, nIndexBits, abs2Sum, bitOrdering, bitOrderingLen, maskBitString, maskOrdering, maskLen); // [User] compute a cumulative sum and choose bitString by a random number // collapse if necessary switch (collapse) { case CUSTATEVEC_COLLAPSE_NORMALIZE_AND_ZERO: custatevecCollapseByBitString( handle, sv, svDataType, nIndexBits, bitString, bitOrdering, bitStringLen, norm); break; /* collapse */ case CUSTATEVEC_COLLAPSE_NONE: break; /* Do nothing */ API reference ------------- .. _custatevecAbs2SumArray-label: :code:`custatevecAbs2SumArray` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecAbs2SumArray ---- .. _custatevecCollapseByBitString-label: :code:`custatevecCollapseByBitString` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecCollapseByBitString ---- .. _custatevecBatchMeasure-label: :code:`custatevecBatchMeasure` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecBatchMeasure Expectation *********** Expectation via a Matrix ======================== Expectation performs the following operation: .. math:: \langle A \rangle = \bra{\phi}A\ket{\phi}, where :math:`\ket{\phi}` is a state vector and :math:`A` is a matrix or an observer. The API for expectation `custatevecExpectation` may require external workspace for large matrices, and `custatevecExpectation_bufferSize` provides the size of workspace. Use case -------- .. code-block:: cpp // check the size of external workspace custatevecExpectation_bufferSize( handle, svDataType, nIndexBits, matrix, matrixDataType, layout, nBasisBits, computeType, &extraWorkspaceSizeInBytes); // allocate external workspace if necessary void* extraWorkspace = nullptr; if (extraWorkspaceSizeInBytes > 0) cudaMalloc(&extraWorkspace, extraWorkspaceSizeInBytes); // perform expectation custatevecExpectation( handle, sv, svDataType, nIndexBits, expect, expectDataType, residualNorm, matrix, matrixDataType, layout, basisBits, nBasisBits, computeType, extraWorkspace, extraWorkspaceSizeInBytes); API reference ------------- .. _custatevecExpectation_bufferSize-label: :code:`custatevecExpectation_bufferSize` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecExpectation_bufferSize ---- .. _custatevecExpectation-label: :code:`custatevecExpectation` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecExpectation Expectation on Pauli Basis ========================== cuStateVec API `custatevecExpectationsOnPauliBasis` computes expectation values for a batch of Pauli strings. Each observable can be expressed as follows: .. math:: P_{\text{basisBits}[0]} \otimes P_{\text{basisBits}[1]} \otimes \cdots \otimes P_{\text{basisBits}[\text{nBasisBits}-1]}. Each matrix :math:`P_{\text{basisBits}[i]}` can be one of the Pauli matrices :math:`I`, :math:`X`, :math:`Y`, and :math:`Z`, corresponding to the `custatevecPauli_t` enums `CUSTATEVEC_PAULI_I`, `CUSTATEVEC_PAULI_X`, `CUSTATEVEC_PAULI_Y`, and `CUSTATEVEC_PAULI_Z`, respectively. Also refer to :ref:`custatevecPauli_t` for details. Use case -------- .. code-block:: cpp // calculate the norm and the expectations for Z(q1) and X(q0)Y(q2) uint32_t nPauliOperatorArrays = 3; custatevecPauli_t pauliOperators0[] = {}; // III int32_t basisBits0[] = {}; custatevecPauli_t pauliOperators1[] = {CUSTATEVEC_PAULI_Z}; // IZI int32_t basisBits1[] = {1}; custatevecPauli_t pauliOperators2[] = {CUSTATEVEC_PAULI_X, CUSTATEVEC_PAULI_Y}; // XIY int32_t basisBits2[] = {0, 2}; const uint32_t nBasisBitsArray[] = {0, 1, 2}; const custatevecPauli_t* pauliOperatorsArray[] = {pauliOperators0, pauliOperators1, pauliOperators2}; const int32_t *basisBitsArray[] = { basisBits0, basisBits1, basisBits2}; uint32_t nIndexBits = 3; double expectationValues[nPauliOperatorArrays]; custatevecExpectationsOnPauliBasis( handle, sv, svDataType, nIndexBits, expectationValues, pauliOperatorsArray, basisBitsArray, nBasisBitsArray, nPauliOperatorArrays); API reference ------------- .. _custatevecExpectationsOnPauliBasis-label: :code:`custatevecExpectationsOnPauliBasis` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: custatevecExpectationsOnPauliBasis Sampling ******** Sampling enables to obtain measurement results many times by using probability calculated from quantum states. Use case ======== .. code-block:: cpp // create sampler and check the size of external workspace custatevecSampler_create( handle, sv, svDataType, nIndexBits, sampler, nMaxShots, &extraWorkspaceSizeInBytes); // allocate external workspace if necessary void extraWorkspace = nullptr; if (extraWorkspaceSizeInBytes > 0) cudaMalloc(extraWorkspace, extraWorkspaceSizeInBytes); // calculate cumulative abs2sum custatevecSampler_preprocess( handle, sampler, extraWorkspace, extraWorkspaceSizeInBytes); // [User] generate randnums, array of random numbers [0, 1) for sampling ... // sample bit strings custatevecSampler_sample( handle, sampler, bitStrings, bitOrdering, bitStringLen, randnums, nShots, output); .. _custatevecSampler_create-label: API reference ============= :code:`custatevecSampler_create` -------------------------------- .. doxygenfunction:: custatevecSampler_create ---- .. _custatevecSampler_preprocess-label: :code:`custatevecSampler_preprocess` ------------------------------------ .. doxygenfunction:: custatevecSampler_preprocess ---- .. _custatevecSampler_sample-label: :code:`custatevecSampler_sample` -------------------------------- .. doxygenfunction:: custatevecSampler_sample Accessor ******** An accessor extracts or updates state vector segments. The APIs `custatevecAccessor_create` and `custatevecAccessor_createReadOnly` initialize an accessor and also return the size of an extra workspace (if needed by the APIs `custatevecAccessor_get` and `custatevecAccessor_set` to perform the copy). The workspace must be allocated by the user and bound to an accessor by `custatevecAccessor_setExtraWorkspace`, and the lifetime of the workspace must be as long as the accessor's to cover the entire duration of the copy operation. The ``begin`` and ``end`` arguments in the get/set APIs correspond to the state vector elements' indices such that elements within the specified range are copied. Use case ======== Extraction ---------- .. code-block:: cpp // create accessor and check the size of external workspace custatevecAccessor_createReadOnly( handle, d_sv, CUDA_C_64F, nIndexBits, &accessor, bitOrdering, bitOrderingLen, maskBitString, maskOrdering, maskLen, &extraWorkspaceSizeInBytes); // allocate external workspace if necessary if (extraWorkspaceSizeInBytes > 0) cudaMalloc(&extraWorkspace, extraWorkspaceSizeInBytes); // set external workspace custatevecAccessor_setExtraWorkspace( handle, &accessor, extraWorkspace, extraWorkspaceSizeInBytes); // get state vector elements custatevecAccessor_get( handle, &accessor, buffer, accessBegin, accessEnd); Update ------ .. code-block:: cpp // create accessor and check the size of external workspace custatevecAccessor_create( handle, d_sv, CUDA_C_64F, nIndexBits, &accessor, bitOrdering, bitOrderingLen, maskBitString, maskOrdering, maskLen, &extraWorkspaceSizeInBytes); // allocate external workspace if necessary if (extraWorkspaceSizeInBytes > 0) cudaMalloc(&extraWorkspace, extraWorkspaceSizeInBytes); // set external workspace custatevecAccessor_setExtraWorkspace( handle, &accessor, extraWorkspace, extraWorkspaceSizeInBytes); // set state vector elements custatevecAccessor_set( handle, &accessor, buffer, 0, nSvSize); API reference ============= .. _custatevecAccessor_create-label: :code:`custatevecAccessor_create` --------------------------------- .. doxygenfunction:: custatevecAccessor_create ---- .. _custatevecAccessor_createReadOnly-label: :code:`custatevecAccessor_createReadOnly` ----------------------------------------- .. doxygenfunction:: custatevecAccessor_createReadOnly ---- .. _custatevecAccessor_setExtraWorkspace-label: :code:`custatevecAccessor_setExtraWorkspace` -------------------------------------------- .. doxygenfunction:: custatevecAccessor_setExtraWorkspace ---- .. _custatevecAccessor_get-label: :code:`custatevecAccessor_get` ------------------------------ .. doxygenfunction:: custatevecAccessor_get ---- .. _custatevecAccessor_set-label: :code:`custatevecAccessor_set` ------------------------------ .. doxygenfunction:: custatevecAccessor_set