microsoft/qdk
Publicmirrored from https://github.com/microsoft/qdkAvailable
source/pip/tests/test_qasm_io.py
307lines · modecode
| 1 | # Copyright (c) Microsoft Corporation. |
| 2 | # Licensed under the MIT License. |
| 3 | |
| 4 | from math import pi |
| 5 | import pytest |
| 6 | from qsharp import ( |
| 7 | QSharpError, |
| 8 | init, |
| 9 | TargetProfile, |
| 10 | Result, |
| 11 | ) |
| 12 | from qsharp.openqasm import ( |
| 13 | import_openqasm, |
| 14 | ProgramType, |
| 15 | ) |
| 16 | import qsharp.code as code |
| 17 | |
| 18 | |
| 19 | def test_import_unsupported_angle_input_type() -> None: |
| 20 | source = """ |
| 21 | input angle input_var; |
| 22 | """ |
| 23 | init(target_profile=TargetProfile.Base) |
| 24 | with pytest.raises(QSharpError): |
| 25 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 26 | |
| 27 | |
| 28 | def test_import_supported_angle_output_type() -> None: |
| 29 | source = """ |
| 30 | input float input_var; |
| 31 | output angle output_var; |
| 32 | output_var = input_var; |
| 33 | """ |
| 34 | init(target_profile=TargetProfile.Base) |
| 35 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 36 | |
| 37 | input = 1.0 |
| 38 | output = code.program(input) |
| 39 | assert abs(output - input) < 1e-10 |
| 40 | |
| 41 | input = 0.0 |
| 42 | output = code.program(input) |
| 43 | assert abs(output - input) < 1e-10 |
| 44 | |
| 45 | # 2pi wraps the angle type and should come back as ~0.0 |
| 46 | input = 2 * pi |
| 47 | output = code.program(input) |
| 48 | assert abs(output) < 1e-10 |
| 49 | |
| 50 | |
| 51 | def test_import_supported_bit_input_and_output_types() -> None: |
| 52 | source = """ |
| 53 | input bit input_var; |
| 54 | output bit output_var; |
| 55 | output_var = input_var; |
| 56 | """ |
| 57 | init(target_profile=TargetProfile.Base) |
| 58 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 59 | |
| 60 | input = Result.One |
| 61 | assert code.program(input) == input |
| 62 | input = Result.Zero |
| 63 | assert code.program(input) == input |
| 64 | |
| 65 | input = True |
| 66 | with pytest.raises(TypeError): |
| 67 | assert code.program(input) == input |
| 68 | input = False |
| 69 | with pytest.raises(TypeError): |
| 70 | assert code.program(input) == input |
| 71 | input = 1 |
| 72 | with pytest.raises(TypeError): |
| 73 | assert code.program(input) == input |
| 74 | input = 0 |
| 75 | with pytest.raises(TypeError): |
| 76 | assert code.program(input) == input |
| 77 | |
| 78 | |
| 79 | def test_import_supported_bool_input_and_output_types() -> None: |
| 80 | source = """ |
| 81 | input bool input_var; |
| 82 | output bool output_var; |
| 83 | output_var = input_var; |
| 84 | """ |
| 85 | init(target_profile=TargetProfile.Base) |
| 86 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 87 | |
| 88 | input = True |
| 89 | assert code.program(input) == input |
| 90 | input = False |
| 91 | assert code.program(input) == input |
| 92 | |
| 93 | input = Result.One |
| 94 | with pytest.raises(TypeError): |
| 95 | assert code.program(input) == input |
| 96 | input = Result.Zero |
| 97 | with pytest.raises(TypeError): |
| 98 | assert code.program(input) == input |
| 99 | input = 1 |
| 100 | with pytest.raises(TypeError): |
| 101 | assert code.program(input) == input |
| 102 | input = 0 |
| 103 | with pytest.raises(TypeError): |
| 104 | assert code.program(input) == input |
| 105 | |
| 106 | |
| 107 | def test_import_supported_complex_input_and_output_types() -> None: |
| 108 | source = """ |
| 109 | input complex input_var; |
| 110 | output complex output_var; |
| 111 | output_var = input_var; |
| 112 | """ |
| 113 | init(target_profile=TargetProfile.Base) |
| 114 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 115 | |
| 116 | input = 1.0 |
| 117 | output = code.program(input) |
| 118 | assert output == input |
| 119 | input = 1.0j |
| 120 | assert code.program(input) == input |
| 121 | input = 1.0 + 2.0j |
| 122 | assert code.program(input) == input |
| 123 | |
| 124 | |
| 125 | def test_import_supported_float_input_and_output_types() -> None: |
| 126 | source = """ |
| 127 | input float input_var; |
| 128 | output float output_var; |
| 129 | output_var = input_var; |
| 130 | """ |
| 131 | init(target_profile=TargetProfile.Base) |
| 132 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 133 | |
| 134 | input = 1.0 |
| 135 | assert code.program(input) == input |
| 136 | input = 0.0 |
| 137 | assert code.program(input) == input |
| 138 | |
| 139 | input = 1 |
| 140 | code.program(input) == float(input) |
| 141 | input = 0 |
| 142 | code.program(input) == float(input) |
| 143 | |
| 144 | |
| 145 | def test_import_supported_int_input_and_output_types() -> None: |
| 146 | source = """ |
| 147 | input int input_var; |
| 148 | output int output_var; |
| 149 | output_var = input_var; |
| 150 | """ |
| 151 | init(target_profile=TargetProfile.Base) |
| 152 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 153 | |
| 154 | input = 1 |
| 155 | assert code.program(input) == input |
| 156 | input = 0 |
| 157 | assert code.program(input) == input |
| 158 | input = -1 |
| 159 | assert code.program(input) == input |
| 160 | |
| 161 | |
| 162 | def test_import_supported_bigint_input_and_output_types() -> None: |
| 163 | source = """ |
| 164 | input int[128] input_var; |
| 165 | output int[128] output_var; |
| 166 | output_var = input_var; |
| 167 | """ |
| 168 | init(target_profile=TargetProfile.Base) |
| 169 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 170 | |
| 171 | input = 1 |
| 172 | assert code.program(input) == input |
| 173 | input = 0 |
| 174 | assert code.program(input) == input |
| 175 | input = -1 |
| 176 | assert code.program(input) == input |
| 177 | input = (1 << 64) - 1 |
| 178 | assert code.program(input) == input |
| 179 | input = -(1 << 63) |
| 180 | assert code.program(input) == input |
| 181 | input = (1 << 128) - 1 |
| 182 | assert code.program(input) == input |
| 183 | input = -(1 << 127) |
| 184 | assert code.program(input) == input |
| 185 | |
| 186 | |
| 187 | def test_import_supported_uint_input_and_output_types() -> None: |
| 188 | source = """ |
| 189 | input uint input_var; |
| 190 | output uint output_var; |
| 191 | output_var = input_var; |
| 192 | """ |
| 193 | init(target_profile=TargetProfile.Base) |
| 194 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 195 | |
| 196 | input = 1 |
| 197 | assert code.program(input) == input |
| 198 | input = 0 |
| 199 | assert code.program(input) == input |
| 200 | input = -1 |
| 201 | # we don't have uint, so it goes in as-is |
| 202 | assert code.program(input) == input |
| 203 | |
| 204 | |
| 205 | def test_import_supported_biguint_input_and_output_types() -> None: |
| 206 | source = """ |
| 207 | input uint[128] input_var; |
| 208 | output uint[128] output_var; |
| 209 | output_var = input_var; |
| 210 | """ |
| 211 | init(target_profile=TargetProfile.Base) |
| 212 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 213 | |
| 214 | input = 1 |
| 215 | assert code.program(input) == input |
| 216 | input = 0 |
| 217 | assert code.program(input) == input |
| 218 | input = -1 |
| 219 | assert code.program(input) == input |
| 220 | input = (1 << 64) - 1 |
| 221 | assert code.program(input) == input |
| 222 | # we don't have uint, so it goes in as-is |
| 223 | input = -(1 << 63) |
| 224 | assert code.program(input) == input |
| 225 | input = (1 << 128) - 1 |
| 226 | assert code.program(input) == input |
| 227 | # we don't have uint, so it goes in as-is |
| 228 | input = -(1 << 128) |
| 229 | assert code.program(input) == input |
| 230 | |
| 231 | |
| 232 | def test_import_supported_bitarray_input_and_output_types() -> None: |
| 233 | source = """ |
| 234 | input bit[5] i_0; |
| 235 | output bit[5] o_0; |
| 236 | o_0 = i_0; |
| 237 | """ |
| 238 | init(target_profile=TargetProfile.Base) |
| 239 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 240 | |
| 241 | with pytest.raises(TypeError): |
| 242 | code.program([1, 0, 1, 0, 0]) |
| 243 | with pytest.raises(TypeError): |
| 244 | code.program([True, False, True, False, False]) |
| 245 | with pytest.raises(QSharpError): |
| 246 | # invalid size |
| 247 | code.program([Result.One, Result.Zero, Result.Zero]) |
| 248 | |
| 249 | input = [Result.One, Result.Zero, Result.One, Result.Zero, Result.Zero] |
| 250 | assert code.program(input) == input |
| 251 | |
| 252 | |
| 253 | def test_import_supported_bool_array_input_and_output_types() -> None: |
| 254 | source = """ |
| 255 | input array[bool, 5] i_0; |
| 256 | output array[bool, 5] o_0; |
| 257 | o_0 = i_0; |
| 258 | """ |
| 259 | init(target_profile=TargetProfile.Base) |
| 260 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 261 | |
| 262 | with pytest.raises(TypeError): |
| 263 | code.program([1, 0, 1, 0, 0]) |
| 264 | with pytest.raises(TypeError): |
| 265 | code.program([Result.One, Result.Zero, Result.One, Result.Zero, Result.Zero]) |
| 266 | with pytest.raises(QSharpError): |
| 267 | # invalid size |
| 268 | code.program([True, False, False]) |
| 269 | |
| 270 | input = [True, False, True, False, False] |
| 271 | assert code.program(input) == input |
| 272 | |
| 273 | |
| 274 | def test_import_supported_bool_array_array_input_and_output_types() -> None: |
| 275 | source = """ |
| 276 | input array[bool, 5, 2] i_0; |
| 277 | output array[bool, 5, 2] o_0; |
| 278 | o_0 = i_0; |
| 279 | """ |
| 280 | init(target_profile=TargetProfile.Base) |
| 281 | import_openqasm(source, program_type=ProgramType.Operation, name="program") |
| 282 | |
| 283 | with pytest.raises(TypeError): |
| 284 | code.program([[1, 1], [0, 0], [1, 0], [0, 0]]) |
| 285 | with pytest.raises(TypeError): |
| 286 | # right shape, wrong type |
| 287 | code.program( |
| 288 | [ |
| 289 | [Result.One, Result.Zero], |
| 290 | [Result.One, Result.Zero], |
| 291 | [Result.Zero, Result.Zero], |
| 292 | [Result.Zero, Result.Zero], |
| 293 | [Result.Zero, Result.Zero], |
| 294 | ] |
| 295 | ) |
| 296 | with pytest.raises(QSharpError): |
| 297 | # invalid size |
| 298 | code.program([[True, True], [False, False], [False, False]]) |
| 299 | |
| 300 | input = [ |
| 301 | [True, False], |
| 302 | [False, False], |
| 303 | [True, False], |
| 304 | [False, False], |
| 305 | [False, False], |
| 306 | ] |
| 307 | assert code.program(input) == input |
| 308 | |