RegisterData
RegisterData contains the actual results of an execution for a partiuclar register (e.g., "ro"). You get a pointer to one by calling get_data.
Definition
typedef struct RegisterData {
unsigned short number_of_shots;
unsigned short shot_length;
struct DataType data;
} RegisterData;
typedef struct DataType {
DataType_Tag tag;
union {
struct {
char **byte;
};
struct {
double **real;
};
};
} DataType;
typedef enum DataType_Tag {
DataType_Byte,
DataType_Real,
} DataType_Tag;
Safety
The memory for any RegisterData will be freed when calling free_execution_result for the corresponding ExecutionResult. Make sure not to free the ExecutionResult until after you're done with the data.
Attributes
number_of_shotsis the outer dimension of the 2D array of data. This should always be equal to the parameter provided towrap_in_shots(or 1 if not called).shot_lengthis the inner dimension of the data array, corresponding to the dimension of the declared memory. For example, declaringBITin Quil will result in ashot_lengthof 1, but declaringBIT[2]in Quil will result in ashot_lengthof 2.datais aDataTypewhich contains the actual results as measured from the requested register. This is a 2D array with outer dimension ofnumber_of_shotsand inner dimension ofshot_length. The type of this data depends on the type of the declared memory. Thetagfield tells you which type of data is contained within, thenbyteorrealis the 2D array.
Variants
The type of data will depend on how the memory was declared in Quil.
Byte
The result of reading from a BIT or OCTET register is the Byte variant. data.tag will be DataType_Byte, and data.byte will be populated.
Real
The result of reading from a REAL register is the Real variant. data.tag will be DataType_Real, and data.real will be populated.
Example
Here we declare both REAL and OCTET registers which will correspond to Real and Byte variants.
char *REAL_MEMORY_PROGRAM =
"DECLARE first REAL[1]\n"
"DECLARE second OCTET[1]\n"
"MOVE first[0] 3.141\n"
"MOVE second[0] 2\n";
bool test_real_data_type() {
const char *TEST_NAME = "test_real_data_type";
Executable *exe = executable_from_quil(REAL_MEMORY_PROGRAM);
read_from(exe, "first");
read_from(exe, "second");
ExecutionResult *result = execute_on_qvm(exe);
if (result->tag == ExecutionResult_Error) {
return fail(
TEST_NAME,
result->error,
exe,
result
);
}
const RegisterData *first = get_data(result->success.handle, "first");
const RegisterData *second = get_data(result->success.handle, "second");
if (first == NULL || first->data.tag != DataType_Real) {
return fail(
TEST_NAME,
"first register did not contain real data",
exe,
result
);
}
if (second == NULL || second->data.tag != DataType_Byte) {
return fail(
TEST_NAME,
"second register did not contain byte data",
exe,
result
);
}
if (first->data.real[0][0] != 3.141) {
char message[50];
sprintf(
message,
"Found %f in first, expected 3.141",
first->data.real[0][0]
);
return fail(
TEST_NAME,
message,
exe,
result
);
}
if (second->data.byte[0][0] != 2) {
char message[50];
sprintf(
message,
"Found %d in first, expected 2",
second->data.byte[0][0]
);
return fail(
TEST_NAME,
message,
exe,
result
);
}
return succeed(TEST_NAME, exe, result);
}