<commit_before>// Distributed under MIT licence. See https://github.com/aniabrown/QuEST/blob/master/LICENCE.txt for details 

/** @file
 * The QuEST API.
 * This file contains the comments used by doxygen for generating API doc
*/

# ifndef QUEST_H
# define QUEST_H

# include "QuEST_precision.h"

#ifdef __cplusplus
extern "C" {
#endif


/*
 * private structures
 */
    
// hide these from doxygen
/// \cond HIDDEN_SYMBOLS    

// Codes for Z-axis phase gate variations
enum phaseGateType {SIGMA_Z=0, S_GATE=1, T_GATE=2};    
    
/** A logger of QASM instructions */
typedef struct {
    
    char* buffer;       // generated QASM string
    int bufferSize;     // maximum number of chars before overflow
    int bufferFill;     // number of chars currently in buffer
    int isLogging;      // whether gates are being added to buffer
    
} QASMLogger;

/** Represents an array of complex numbers grouped into an array of 
 * real components and an array of coressponding complex components.
 */
typedef struct ComplexArray
{
    qreal *real; 
    qreal *imag;
} ComplexArray;

/// \endcond

    

/*
 * public structures
 */

/** Represents one complex number.
 */
typedef struct Complex
{
    qreal real;
    qreal imag;
} Complex;

/** Represents a 2x2 matrix of complex numbers
 */
typedef struct ComplexMatrix2
{
    Complex r0c0, r0c1;
    Complex r1c0, r1c1;
} ComplexMatrix2;

/** Represents a 3-vector of real numbers
 */
typedef struct Vector
{
    qreal x, y, z;
} Vector;

/** Represents a system of qubits.
 * Qubits are zero-based
 */
typedef struct Qureg
{
    //! Whether this instance is a density-state representation
    int isDensityMatrix;
    //! The number of qubits represented in either the state-vector or density matrix
    int numQubitsRepresented;
    //! Number of qubits in the state-vector - this is double the number represented for mixed states
    int numQubitsInStateVec;
    //! Number of probability amplitudes held in stateVec by this process
    //! In the non-MPI version, this is the total number of amplitudes
    long long int numAmpsPerChunk;
    //! Total number of amplitudes, which are possibly distributed among machines
    long long int numAmpsTotal;
    //! The position of the chunk of the state vector held by this process in the full state vector
    int chunkId;
    //! Number of chunks the state vector is broken up into -- the number of MPI processes used
    int numChunks;
    
    //! Computational state amplitudes - a subset thereof in the MPI version
    ComplexArray stateVec; 
    //! Temporary storage for a chunk of the state vector received from another process in the MPI version
    ComplexArray pairStateVec;
    
    //! Storage for wavefunction amplitudes in the GPU version
    ComplexArray deviceStateVec;
    //! Storage for reduction of probabilities on GPU
    qreal *firstLevelReduction, *secondLevelReduction;

    //! Storage for generated QASM output
    QASMLogger* qasmLog;
    
} Qureg;

/** Information about the environment the program is running in.
In practice, this holds info about MPI ranks and helps to hide MPI initialization code
*/
typedef struct QuESTEnv
{
    int rank;
    int numRanks;
} QuESTEnv;



/*
 * public functions
 */

/** Create a Qureg object representing a set of qubits which will remain in a pure state.
 * Allocate space for state vector of probability amplitudes, including space for temporary values to be copied from
 * one other chunk if running the distributed version. Define properties related to the size of the set of qubits.
 * The qubits are initialised in the zero state (i.e. initZeroState is automatically called)
 *
 * @returns an object representing the set of qubits
 * @param[in] numQubits number of qubits in the system
 * @param[in] env object representing the execution environment (local, multinode etc)
 * @throws exitWithError if \p numQubits <= 0
 */
Qureg createQureg(int numQubits, QuESTEnv env);

/** Create a Qureg for qubits which are represented by a density matrix, and can be in mixed states.
 * Allocate space for a density matrix of probability amplitudes, including space for temporary values to be copied from
 * one other chunk if running the distributed version. Define properties related to the size of the set of qubits.
 * initZeroState should be called after this to initialise the qubits to the zero pure state.
 *
 * @returns an object representing the set of qubits
 * @param[in] numQubits number of qubits in the system
 * @param[in] env object representing the execution environment (local, multinode etc)
 * @throws exitWithError if \p numQubits <= 0
 */
Qureg createDensityQureg(int numQubits, QuESTEnv env);

/** Deallocate a Qureg object representing a set of qubits.
 * Free memory allocated to state vector of probability amplitudes, including temporary vector for
 * values copied from another chunk if running the distributed version.
 *
 * @param[in,out] qureg object to be deallocated
 * @param[in] env object representing the execution environment (local, multinode etc)
 */
void destroyQureg(Qureg qureg, QuESTEnv env);

/** Print the current state vector of probability amplitudes for a set of qubits to file.
 * File format:
 * @verbatim
real, imag
realComponent1, imagComponent1
realComponent2, imagComponent2
...
realComponentN, imagComponentN
@endverbatim<commit_msg>fixed createDensityQureg doc<commit_after>// Distributed under MIT licence. See https://github.com/aniabrown/QuEST/blob/master/LICENCE.txt for details 

/** @file
 * The QuEST API.
 * This file contains the comments used by doxygen for generating API doc
*/

# ifndef QUEST_H
# define QUEST_H

# include "QuEST_precision.h"

#ifdef __cplusplus
extern "C" {
#endif


/*
 * private structures
 */
    
// hide these from doxygen
/// \cond HIDDEN_SYMBOLS    

// Codes for Z-axis phase gate variations
enum phaseGateType {SIGMA_Z=0, S_GATE=1, T_GATE=2};    
    
/** A logger of QASM instructions */
typedef struct {
    
    char* buffer;       // generated QASM string
    int bufferSize;     // maximum number of chars before overflow
    int bufferFill;     // number of chars currently in buffer
    int isLogging;      // whether gates are being added to buffer
    
} QASMLogger;

/** Represents an array of complex numbers grouped into an array of 
 * real components and an array of coressponding complex components.
 */
typedef struct ComplexArray
{
    qreal *real; 
    qreal *imag;
} ComplexArray;

/// \endcond

    

/*
 * public structures
 */

/** Represents one complex number.
 */
typedef struct Complex
{
    qreal real;
    qreal imag;
} Complex;

/** Represents a 2x2 matrix of complex numbers
 */
typedef struct ComplexMatrix2
{
    Complex r0c0, r0c1;
    Complex r1c0, r1c1;
} ComplexMatrix2;

/** Represents a 3-vector of real numbers
 */
typedef struct Vector
{
    qreal x, y, z;
} Vector;

/** Represents a system of qubits.
 * Qubits are zero-based
 */
typedef struct Qureg
{
    //! Whether this instance is a density-state representation
    int isDensityMatrix;
    //! The number of qubits represented in either the state-vector or density matrix
    int numQubitsRepresented;
    //! Number of qubits in the state-vector - this is double the number represented for mixed states
    int numQubitsInStateVec;
    //! Number of probability amplitudes held in stateVec by this process
    //! In the non-MPI version, this is the total number of amplitudes
    long long int numAmpsPerChunk;
    //! Total number of amplitudes, which are possibly distributed among machines
    long long int numAmpsTotal;
    //! The position of the chunk of the state vector held by this process in the full state vector
    int chunkId;
    //! Number of chunks the state vector is broken up into -- the number of MPI processes used
    int numChunks;
    
    //! Computational state amplitudes - a subset thereof in the MPI version
    ComplexArray stateVec; 
    //! Temporary storage for a chunk of the state vector received from another process in the MPI version
    ComplexArray pairStateVec;
    
    //! Storage for wavefunction amplitudes in the GPU version
    ComplexArray deviceStateVec;
    //! Storage for reduction of probabilities on GPU
    qreal *firstLevelReduction, *secondLevelReduction;

    //! Storage for generated QASM output
    QASMLogger* qasmLog;
    
} Qureg;

/** Information about the environment the program is running in.
In practice, this holds info about MPI ranks and helps to hide MPI initialization code
*/
typedef struct QuESTEnv
{
    int rank;
    int numRanks;
} QuESTEnv;



/*
 * public functions
 */

/** Create a Qureg object representing a set of qubits which will remain in a pure state.
 * Allocate space for state vector of probability amplitudes, including space for temporary values to be copied from
 * one other chunk if running the distributed version. Define properties related to the size of the set of qubits.
 * The qubits are initialised in the zero state (i.e. initZeroState is automatically called)
 *
 * @returns an object representing the set of qubits
 * @param[in] numQubits number of qubits in the system
 * @param[in] env object representing the execution environment (local, multinode etc)
 * @throws exitWithError if \p numQubits <= 0
 */
Qureg createQureg(int numQubits, QuESTEnv env);

/** Create a Qureg for qubits which are represented by a density matrix, and can be in mixed states.
 * Allocates space for a density matrix of probability amplitudes, including space for temporary values to be copied from
 * one other chunk if running the distributed version. Define properties related to the size of the set of qubits.
 * initZeroState is automatically called allocation, so that the density qureg begins in the zero state |0><0|.
 *
 * @returns an object representing the set of qubits
 * @param[in] numQubits number of qubits in the system
 * @param[in] env object representing the execution environment (local, multinode etc)
 * @throws exitWithError if \p numQubits <= 0
 */
Qureg createDensityQureg(int numQubits, QuESTEnv env);

/** Deallocate a Qureg object representing a set of qubits.
 * Free memory allocated to state vector of probability amplitudes, including temporary vector for
 * values copied from another chunk if running the distributed version.
 *
 * @param[in,out] qureg object to be deallocated
 * @param[in] env object representing the execution environment (local, multinode etc)
 */
void destroyQureg(Qureg qureg, QuESTEnv env);

/** Print the current state vector of probability amplitudes for a set of qubits to file.
 * File format:
 * @verbatim
real, imag
realComponent1, imagComponent1
realComponent2, imagComponent2
...
realComponentN, imagComponentN
@endverbatim
{'fraction_non_alphanumeric': 0.06544405138707876, 'fraction_numerical': 0.004282256563023646, 'mean_word_length': 3.5100755667506296, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2445858', 'n_tokens_mistral': 2982, 'n_tokens_neox': 2844, 'n_words': 1356}