A fast stabilizer circuit simulator

Stim

Stim is a fast simulator for non-adaptive quantum stabilizer circuits. Stim is based on the stabilizer tableau representation introduced in Scott Aaronson et al's CHP simulator. Stim makes three key improvements over CHP.

First, the stabilizer tableau that is being tracked is inverted. The tableau tracked by Stim indexes how each qubit's X and Z observables at the current time map to compound observables at the start of time (instead of mapping from the start of time to the current time). This is done so that the sign of the tracked observables directly store the measurement result to return when a measurement is deterministic. As a result, deterministic measurements can be completed in linear time instead of quadratic time.

Second, when producing multiple samples, the initial stabilizer simulation is executed without noise in order to create a reference sample. Once a reference sample from the circuit is available, all that is needed is to track a Pauli frame through the circuit, using the original sample as a template whose results are flipped or not flipped by the passing Pauli frame. As long as all errors are probabilistic Pauli operations, and as long as 50/50 probability Z errors are placed after every reset and every measurement, the Pauli frame can track these errors and the resulting samples will come from the same distribution as a full stabilizer simulation. This ensures every gate has a worst case complexity of O(1), instead of O(n) or O(n^2).

Third, data is laid out in a cache friendly way and operated on using vectorized 256-bit-wide SIMD instructions. This makes key operations fast. For example, Stim can multiply a Pauli string with a hundred billion terms into another in under a second. Pauli string multiplication is a key bottleneck operation when updating a stabilizer tableau. Tracking Pauli frames can also benefit from vectorization, by combining them into batches and computing thousands of samples at a time.

Usage (python)

Stim can be installed into a python 3 environment using pip:

pip install stim

Once stim is installed, you can import stim and use it. There are two supported use cases: interactive usage and high speed sampling.

You can use the Tableau simulator in an interactive fashion:

import stim

s = stim.TableauSimulator()

# Create a GHZ state.
s.h(0)
s.cnot(0, 1)
s.cnot(0, 2)

# Measure the GHZ state.
print(s.measure_many(0, 1, 2))  # [False, False, False] or [True, True, True]

Alternatively, you can compile a circuit and then begin generating samples from it:

import stim

# Create a circuit that measures a large GHZ state.
c = stim.Circuit()
c.append_operation("H", [0])
for k in range(1, 30):
    c.append_operation("CNOT", [0, k])
c.append_operation("M", range(30))

# Compile the circuit into a high performance sampler.
sampler = c.compile_sampler()

# Collect a batch of samples.
# Note: the ideal batch size, in terms of speed per sample, is roughly 1024.
# Smaller batches are slower because they are not sufficiently vectorized.
# Bigger batches are slower because they use more memory.
batch = sampler.sample(1024)
print(type(batch))  # numpy.ndarray
print(batch.dtype)  # numpy.uint8
print(batch.shape)  # (1024, 30)
print(batch)
# Prints something like:
# [[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
#  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
#  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
#  ...
#  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
#  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
#  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
#  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]]

The circuit can also include noise:

import stim
import numpy as np

c = stim.Circuit()
c.append_from_stim_program_text("""
    X_ERROR(0.1) 0
    Y_ERROR(0.2) 1
    Z_ERROR(0.3) 2
    DEPOLARIZE1(0.4) 3
    DEPOLARIZE2(0.5) 4 5
    M 0 1 2 3 4 5
""")
batch = c.compile_sampler().sample(2**20)
print(np.mean(batch, axis=0).round(3))
# Prints something like:
# [0.1   0.2   0.    0.267 0.267 0.266]

You can also sample detection events using stim.Circuit.compile_detector_sampler.

Usage (command line)

Stim reads a quantum circuit from stdin and writes measurement results to stdout. The input format is a series of lines, each starting with an optional gate (e.g. CNOT 0 1) and ending with an optional comment prefixed by #. See below for a list of supported gates. The default output format is a string of "0" and "1" characters, indicating measurement results. The order of the results is the same as the order of the measurement commands in the input.

Examples

Bit flip and measure a qubit:

echo "
  X 0
  M 0
" | ./stim --sample
1

Create and measure a GHZ state, five times:

echo "
  H 0
  CNOT 0 1 0 2
  M 0 1 2
" | ./stim --sample=5
111
111
000
111
000

Sample several runs of a small noisy surface code with phenomenological type noise:

echo "
  REPEAT 20 {
    DEPOLARIZE1(0.001) 0 1 2 3 4 5 6 7 8
    H 3 5
    CNOT 4 1 3 6 5 8
    CNOT 2 1 8 7 3 4
    CNOT 0 1 6 7 5 4
    CNOT 4 7 3 0 5 2
    H 3 5
    M 1 7 3 5
    R 1 7 3 5
  }
  M 0 2 4 6 8
" | ./stim --sample=10
0010001000100010001000100010001000100010001000100010001000100010011011000101010111010
0000000000000000000000000000000000000000000000000000000000001001100110011001100110011
0010001000100010001000100010001000100010001000100110001000100010001000100010001010110
0001000100010001000100010001000100010001000100010001000100010001000100010001000101101
0010001000100010001000100010001000100010001000100011001100110011001100110011001110110
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0010001000100010001000100010001000100010001000101000100010001000100010001000001000000
0010001000100010101000100010001000110001000100010001000100000001000100010001000100000
0010001000100010001000100010001000100010001100100010101010101010101010101010101010011
0000000000000000000000000000000000000000000001000100010001001000100011001100110000100

Sample detection events in a repetition code with circuit level noise, include two qubit depolarizing noise when performing a CNOT. Instead of listing all 0s and 1s, print the locations of the 1s in each line:

echo "
  M 1 3 5 7
  REPEAT 100 {
    DEPOLARIZE2(0.001) 0 1 2 3 4 5 6 7
    DEPOLARIZE1(0.001) 8
    CNOT 0 1 2 3 4 5 6 7
    DEPOLARIZE2(0.001) 8 7 6 5 4 3 2 1
    DEPOLARIZE1(0.001) 0
    CNOT 8 7 6 5 4 3 2 1
    DEPOLARIZE1(0.001) 0 1 2 3 4 5 6 7 8
    MR 1 3 5 7
    # Parity measurements should stay consistent over time.
    DETECTOR rec[-1] rec[-5]
    DETECTOR rec[-2] rec[-6]
    DETECTOR rec[-3] rec[-7]
    DETECTOR rec[-4] rec[-8]
  }
  M 0 2 4 6 8
  # Data measurements should agree with parity measurements.
  DETECTOR rec[-1] rec[-2] rec[-6]
  DETECTOR rec[-2] rec[-3] rec[-7]
  DETECTOR rec[-3] rec[-4] rec[-8]
  DETECTOR rec[-4] rec[-5] rec[-9]
  # Any one of the data qubit measurements can be the logical measurement result.
  OBSERVABLE_INCLUDE(0) rec[-1]
" | ./stim --detect=10 --out_format=hits
85,89
83


98,103,242,243
125,129,241,245
144,152,153,176,180,238,242
162,166
147
204

Compute the circuit's detector hypergraph (the graph whose nodes are detectors/observables and whose edges are errors grouped into equivalence classes based on which detectors and observables they invert). Output the graph's hyper edges as a series of lines like error(probability) D0 D1 L2:

echo "
  M 0 1
  H 0
  CNOT 0 1
  DEPOLARIZE1(0.01) 0
  X_ERROR(0.1) 1
  CNOT 0 1
  H 0
  M 0 1
  DETECTOR rec[-1] rec[-3]
  DETECTOR rec[-2] rec[-4]
" | ./stim --detector_hypergraph
error(0.1026756153132975941) D0
error(0.003344519141621982161) D0 D1
error(0.003344519141621982161) D1

Command line flags

  • --help: Prints usage examples and exits.

Modes

Only one mode can be specified.

  • --repl: Interactive mode. Print measurement results interactively as a circuit is typed into stdin. Note that this mode, unlike the other modes, prints output before operations that mutate the measurement record (e.g. CNOT rec[-1] rec[-2]) are applied.
  • --sample or --sample=#: Measurement sampling mode. Output measurement results from the given circuit. If an integer argument is specified, run that many shots of the circuit.
  • --detect or --detect=#: Detection event sampling mode. Outputs whether or not measurement sets specified by DETECTOR instructions have been flipped by noise. Assumes (does not verify) that all DETECTOR instructions corresponding to measurement sets with deterministic parity. See also --prepend_observables, --append_observables. If an integer argument is specified, run that many shots of the circuit.
  • --detector_hypergraph: Detector graph creation mode. Computes equivalence classes of errors based on the detectors and observables that the error inverts. Each equivalence class is a hyper edge in the graph, and is weighted with a probability such that independently sampling each edge and inverting the associated detectors is equivalent to sampling from the original circuit. The output is given as series of lines like error(probability) D1 D2 L3 where D# is a detector and L# is a logical observable.

Modifiers

Modifiers tweak how a mode runs. Not all modifiers apply to all modes.

  • --frame0: Significantly improve the performance of measurement sampling mode by asserting that it is possible to take a sample from the given circuit where all measurement results are 0. Allows the frame simulator to start immediately, without waiting for a reference sample from the tableau simulator. If this assertion is wrong, the output samples can be corrected by xoring them against a valid sample from the circuit. Requires measurement sampling mode.
  • --append_observables: Requires detection event sampling mode. In addition to outputting the values of detectors, output the values of logical observables built up using OBSERVABLE_INCLUDE instructions. Put these observables' values into the detection event output as if they were additional detectors at the end of the circuit.
  • --prepend_observables: Requires detection event sampling mode. In addition to outputting the values of detectors, output the values of logical observables built up using OBSERVABLE_INCLUDE instructions. Put these observables' values into the detection event output as if they were additional detectors at the start of the circuit
  • --in=FILEPATH: Specifies a file to read a circuit from. If not specified, the stdin pipe is used. Incompatible with interactive mode.
  • --out=FILEPATH: Specifies a file to create or overwrite with results. If not specified, the stdout pipe is used. Incompatible with interactive mode.
  • --out_format=[name]: Output format to use. Incompatible with interactive mode. Definition: a "sample" is one measurement result in measurement sampling mode or one detector/observable result in detection event sampling mode. Definition: a "shot" is composed of all of the samples from a circuit. Definition: a "sample location" is a measurement gate in measurement sampling mode, or a detector/observable in detection event sampling mode.
    • 01 (default): Human readable ASCII format. Prints all the samples from one shot before moving on to the next. Prints '0' or '1' for each sample. Prints '\n' at the end of each shot. Example all-true ASCII data (for 10 measurements, 4 shots):
      1111111111
      1111111111
      1111111111
      1111111111
      
    • hits: Human readable ASCII format. Writes the decimal indices of samples equal to 1, separated by a comma. Shots are separated by a newline. This format is more useful in --detect mode, where 1s are rarer. Example all-true output data (for 10 measurements, 4 shots):
      0,1,2,3,4,5,6,7,8,9
      0,1,2,3,4,5,6,7,8,9
      0,1,2,3,4,5,6,7,8,9
      0,1,2,3,4,5,6,7,8,9
      
    • dets: Human readable ASCII format. Similar to hits, except each line is prefixed by shot , hits are separated by spaces, and each hit is prefixed by a character indicating its type (M for measurement, D for detector, L for logical observable). Example output data (for 3 detectors, 2 observables):
      shot
      shot L0 L1 D0 D1 D2
      shot L0 D0
      
    • b8: Binary format. Writes all the samples from one shot before moving on to the next. The number of samples is padded up to a multiple of 8 using fake samples set to 0. Samples are combined into groups of 8. The sample results for a group are bit packed into a byte, ordered from least significant bit to most significant bit. The byte for the first sample group is printed, then the second, and so forth for all groups in order. There is no separator between shots (other than the fake zero sample padding). Example all-true output hex data (for 10 measurements, 4 shots):
      FF 30 FF 30 FF 30 FF 30
      
    • ptb64: Partially transposed binary format. The number of shots is padded up to a multiple of 64 using fake shots where all samples are 0. Shots are combined into groups of 64. All the samples from one shot group are written before moving on to the next group. Within a shot group, each of the circuit sample locations has 64 results (one from each shot). These 64 bits of information are packed into 8 bytes, ordered from first file byte to last file byte and then least significant bit to most significant bit. The 8 bytes for the first sample location are output, then the 8 bytes for the next, and so forth for all sample locations. There is no separator between shot groups (the reader must know how many measurements are expected). Example all-true output hex data (for 3 measurements, 81 shots):
      FF FF FF FF FF FF FF FF
      FF FF FF FF FF FF FF FF
      FF FF FF FF FF FF FF FF
      FF FF F1 00 00 00 00 00
      FF FF F1 00 00 00 00 00
      FF FF F1 00 00 00 00 00
      
    • r8: Binary run-length format. Each byte is the length of a run of samples that were all False. If the run length is non-maximal (less than 255), the next measurement result is a 1. For example, 0x00 means [1], 0x03 means [0, 0, 0, 1], 0xFE means [0] * 254 + [1], and 0xFF means [0] * 255. A fake "True" sample is appended to the end of each shot, and the data for a shot ends on the byte that decodes to produce this fake appended True. Note that this means the reader must know how many measurement results are expected, and that the data will never end with a 0xFF. There is no separator between shots, other than padding implicit in appending the fake "True" samples. Example data for an all-false shot then an all-true shot then an all-false shot (with 5 measurements per shot):
      0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x05
      
      Note the extra 0x00 due to the fake appended True.
  • --distance=#: Distance to use in circuit generation mode. Defaults to 3.
  • --rounds=#: Number of rounds to use in circuit generation mode. Defaults to the same as distance.
  • --noise_level=%f: Strength of depolarizing noise, from 0 to 1, to insert into generated circuits. Defaults to 0 (none).

Supported Gates

General facts about all gates.

  • Qubit Targets: Qubits are referred to by non-negative integers. There is a qubit 0, a qubit 1, and so forth (up to an implemented-defined maximum of 16777215). For example, the line X 2 says to apply an X gate to qubit 2. Beware that touching qubit 999999 implicitly tells simulators to resize their internal state to accommodate a million qubits.

  • Measurement Record Targets: Measurement results are referred to by rec[-#] arguments, where the index within the square brackets uses python-style negative indices to refer to the end of the growing measurement record. For example, CNOT rec[-1] 3 says "toggle qubit 3 if the most recent measurement returned True and CZ 1 rec[-2] means "phase flip qubit 1 if the second most recent measurement returned True. There is implementation-defined maximum lookback of -16777215 when accessing the measurement record. Non-negative indices are not permitted.

  • Broadcasting: Most gates support broadcasting over multiple targets. For example, H 0 1 2 will broadcast a Hadamard gate over qubits 0, 1, and 2. Two qubit gates can also broadcast, and do so over aligned pair of targets. For example, CNOT 0 1 2 3 will apply CNOT 0 1 and then CNOT 2 3. Broadcasting is always evaluated in left-to-right order.

Single qubit gates

  • Z: Pauli Z gate. Phase flip.
  • Y: Pauli Y gate.
  • X: Pauli X gate. Bit flip.
  • H (alternate name H_XZ): Hadamard gate. Swaps the X and Z axes. Unitary equals (X + Z) / sqrt(2).
  • H_XY: Variant of the Hadamard gate that swaps the X and Y axes (instead of X and Z). Unitary equals (X + Y) / sqrt(2).
  • H_YZ: Variant of the Hadamard gate that swaps the Y and Z axes (instead of X and Z). Unitary equals (Y + Z) / sqrt(2).
  • S (alternate name SQRT_Z): Principle square root of Z gate. Equal to diag(1, i).
  • S_DAG (alternate name SQRT_Z_DAG): Adjoint square root of Z gate. Equal to diag(1, -i).
  • SQRT_Y: Principle square root of Y gate. Equal to H_YZ*S*H_YZ.
  • SQRT_Y_DAG: Adjoint square root of Y gate. Equal to H_YZ*S_DAG*H_YZ.
  • SQRT_X: Principle square root of X gate. Equal to H*S*H.
  • SQRT_X_DAG: Adjoint square root of X gate. Equal to H*S_DAG*H.
  • I: Identity gate. Does nothing. Why is this even here? Probably out of a misguided desire for closure.

Two qubit gates

  • SWAP: Swaps two qubits.
  • ISWAP: Swaps two qubits while phasing the ZZ observable by i. Equal to SWAP * CZ * (S tensor S).
  • ISWAP_DAG: Swaps two qubits while phasing the ZZ observable by -i. Equal to SWAP * CZ * (S_DAG tensor S_DAG).
  • CNOT (alternate names CX, ZCX): Controlled NOT operation. Qubit pairs are in name order (first qubit is the control, second is the target). This gate can be controlled by on the measurement record. Examples: unitary CNOT 1 2, feedback CNOT rec[-1] 4.
  • CY (alternate name ZCY): Controlled Y operation. Qubit pairs are in name order (first qubit is the control, second is the target). This gate can be controlled by on the measurement record. Examples: unitary CY 1 2, feedback CY rec[-1] 4.
  • CZ (alternate name ZCZ): Controlled Z operation. This gate can be controlled by on the measurement record. Examples: unitary CZ 1 2, feedback CZ rec[-1] 4 or CZ 4 rec[-1].
  • YCZ: Y-basis-controlled Z operation (i.e. the reversed-argument-order controlled-Y). Qubit pairs are in name order. This gate can be controlled by on the measurement record. Examples: unitary YCZ 1 2, feedback YCZ 4 rec[-1].
  • YCY: Y-basis-controlled Y operation.
  • YCX: Y-basis-controlled X operation. Qubit pairs are in name order.
  • XCZ: X-basis-controlled Z operation (i.e. the reversed-argument-order controlled-not). Qubit pairs are in name order. This gate can be controlled by on the measurement record. Examples: unitary XCZ 1 2, feedback XCZ 4 rec[-1].
  • XCY: X-basis-controlled Y operation. Qubit pairs are in name order.
  • XCX: X-basis-controlled X operation.

Collapsing gates

  • M: Z-basis measurement. Examples: M 0, M 2 1, M 0 !3 1 2. Collapses the target qubits and reports their values (optionally flipped). Prefixing a target with a ! indicates that the measurement result should be inverted when reported. In the tableau simulator, this operation may require a transpose and so is more efficient when grouped (e.g. prefer M 0 1 \n H 0 over M 0 \n H 0 \n M 1).
  • R: Reset to |0>. Examples: R 0, R 2 1, R 0 3 1 2. Silently measures the target qubits and bit flips them if they're in the |1> state. Equivalently, discards the target qubits for zero'd qubits. In the tableau simulator, this operation may require a transpose and so is more efficient when grouped (e.g. prefer R 0 1 \n X 0 over R 0 \n X 0 \ nR 1).
  • MR: Z-basis measurement and reset. Examples: MR 0, MR 2 1, MR 0 !3 1 2. Collapses the target qubits, reports their values (optionally flipped), then resets them to the |0> state. Prefixing a target with a ! indicates that the measurement result should be inverted when reported. (The ! does not change that the qubit is reset to |0>.) In the tableau simulator, this operation may require a transpose and so is more efficient when grouped (e.g. prefer MR 0 1 \n H 0 over MR 0 \n H 0 \n MR 1).

Noise Gates

  • DEPOLARIZE1(p): Single qubit depolarizing error. Examples: DEPOLARIZE1(0.001) 1, DEPOLARIZE1(0.0003) 0 2 4 6. With probability p, applies independent single-qubit depolarizing kicks to the given qubits. A single-qubit depolarizing kick is X, Y, or Z chosen uniformly at random.

  • DEPOLARIZE2(p): Two qubit depolarizing error. Examples: DEPOLARIZE2(0.001) 0 1, DEPOLARIZE2(0.0003) 0 2 4 6. With probability p, applies independent two-qubit depolarizing kicks to the given qubit pairs. A two-qubit depolarizing kick is IX, IY, IZ, XI, XX, XY, XZ, YI, YX, YY, YZ, ZI, ZX, ZY, ZZ chosen uniformly at random.

  • X_ERROR(p): Single-qubit probabilistic X error. Examples: X_ERROR(0.001) 0 1. For each target qubit, independently applies an X gate With probability p.

  • Y_ERROR(p): Single-qubit probabilistic Y error. Examples: Y_ERROR(0.001) 0 1. For each target qubit, independently applies a Y gate With probability p.

  • Z_ERROR(p): Single-qubit probabilistic Z error. Examples: Z_ERROR(0.001) 0 1. For each target qubit, independently applies a Z gate With probability p.

  • CORRELATED_ERROR(p) (alternate name E) and ELSE_CORRELATED_ERROR(p): Pauli product error cases. Probabilistically applies a Pauli product error with probability p, unless the "correlated error occurred" flag is already set. CORRELATED_ERROR is equivalent to ELSE_CORRELATED_ERROR except that CORRELATED_ERROR starts by clearing the "correlated error occurred" flag. Both operations set the "correlated error occurred" flag if they apply their error. Example:

      # With 40% probability, uniformly pick X1*Y2 or Z2*Z3 or X1*Y2*Z3.
      CORRELATED_ERROR(0.2) X1 Y2
      ELSE_CORRELATED_ERROR(0.25) Z2 Z3
      ELSE_CORRELATED_ERROR(0.33333333333) X1 Y2 Z3
    

Annotations

  • DETECTOR: Asserts that a set of measurements have a deterministic result, and that this result changing can be used to detect errors. Ignored in measurement sampling mode. In detection sampling mode, a detector produces a sample indicating if it was inverted by noise or not. Example: DETECTOR rec[-1] rec[-2].
  • OBSERVABLE_INCLUDE(k): Adds physical measurement locations to a specified logical observable. The logical measurement result is the parity of all physical measurements added to it. Behaves similarly to a Detector, except observables can be built up globally over the entire circuit instead of being defined locally. Ignored in measurement sampling mode. In detection sampling mode, a logical observable can produce a sample indicating if it was inverted by noise or not. These samples are dropped or put before or after detector samples, depending on command line flags. Examples: OBSERVABLE_INCLUDE(0) rec[-1] rec[-2], OBSERVABLE_INCLUDE(3) rec[-7].

Other

  • TICK: Optional command indicating the end of a layer of gates. May be ignored, may force processing of internally queued operations and flushing of queued measurement results.
  • REPEAT N { ... }: Repeats the instructions in its body N times.

Building

CMake Build

cmake .
make stim
# ./out/stim

To control the vectorization (e.g. this is done for testing), use cmake . -DSIMD_WIDTH=256 (implying -mavx2) or cmake . -DSIMD_WIDTH=128 (implying -msse2) or cmake . -DSIMD_WIDTH=64 (implying no machine architecture flag). If SIMD_WIDTH is not specified, -march=native is used.

Bazel Build

bazel build stim
# bazel run stim

Manual Build

find src | grep "\\.cc" | grep -v "\\.\(test\|perf\|pybind\)\\.cc" | xargs g++ -pthread -std=c++11 -O3 -march=native
# ./a.out

Python Package Build

Environment requirements:

pip install -y pybind11 cibuildwheel

Build source distribution (fallback for missing binary wheels):

python setup.py sdist

Output in dist directory.

Build manylinux binary distributions (takes 30+ minutes):

python -m cibuildwheel --output-dir wheelhouse --platform=linux

Output in wheelhouse directory.

Build stimcirq package:

cd glue/cirq
python setup.py sdist

Output in glue/cirq/dist directory.

Testing

Run tests using CMAKE

Unit testing with CMAKE requires GTest to be installed on your system and discoverable by CMake. Follow the "Standalone CMake Project" from the GTest README.

Run tests with address and memory sanitization, but without optimizations:

cmake .
make stim_test
./out/stim_test

To force AVX vectorization, SSE vectorization, or no vectorization pass -DSIMD_WIDTH=256 or -DSIMD_WIDTH=128 or -DSIMD_WIDTH=64to thecmake` command.

Run tests with optimizations without sanitization:

cmake .
make stim_test_o3
./out/stim_test_o3

Run tests using Bazel

Run tests with whatever settings Bazel feels like using:

bazel :stim_test

Run python binding tests

In a fresh virtual environment:

pip install -e .
pip install -y numpy pytest
python -m pytest src

Benchmarking

cmake .
make stim_benchmark
./out/stim_benchmark

This will output results like:

[....................*....................] 460 ns (vs 450 ns) ( 21 GBits/s) simd_bits_randomize_10K
[...................*|....................]  24 ns (vs  20 ns) (400 GBits/s) simd_bits_xor_10K
[....................|>>>>*...............] 3.6 ns (vs 4.0 ns) (270 GBits/s) simd_bits_not_zero_100K
[....................*....................] 5.8 ms (vs 6.0 ms) ( 17 GBits/s) simd_bit_table_inplace_square_transpose_diam10K
[...............*<<<<|....................] 8.1 ms (vs 5.0 ms) ( 12 GOpQubits/s) FrameSimulator_depolarize1_100Kqubits_1Ksamples_per1000
[....................*....................] 5.3 ms (vs 5.0 ms) ( 18 GOpQubits/s) FrameSimulator_depolarize2_100Kqubits_1Ksamples_per1000

The bars on the left show how fast each task is running compared to baseline expectations (on my dev machine). Each tick away from the center | is 1 decibel slower or faster (i.e. each < or > represents a factor of 1.26).

Basically, if you see [......*<<<<<<<<<<<<<|....................] then something is seriously wrong, because the code is running 25x slower than expected.

The benchmark binary supports a --only=BENCHMARK_NAME filter flag. Multiple filters can be specified by separating them with commas --only=A,B. Ending a filter with a * turns it into a prefix filter --only=sim_*.

Owner
quantumlib
Code for the Quantum World
quantumlib
Comments
  • 'pip install stim' failing with error 'src/stim.cc:17:10: fatal error: 'stim.h' file not found'

    'pip install stim' failing with error 'src/stim.cc:17:10: fatal error: 'stim.h' file not found'

    I'm a novice with these sorts of things, so any help appreciated. I'm on a Mac running Monterey 12.1. I have a conda environment activated, and from inside that I write 'pip install stim' in the terminal. Here's the output:

    (FaultTolerantQPU) [email protected] FaultTolerantQPU % pip install stim              
    Collecting stim
      Using cached stim-1.8.0.tar.gz (164 kB)
      Installing build dependencies ... done
      Getting requirements to build wheel ... done
      Preparing metadata (pyproject.toml) ... done
    Requirement already satisfied: numpy in /opt/homebrew/Caskroom/miniconda/base/envs/FaultTolerantQPU/lib/python3.10/site-packages (from stim) (1.22.3)
    Building wheels for collected packages: stim
      Building wheel for stim (pyproject.toml) ... error
      error: subprocess-exited-with-error
      
      × Building wheel for stim (pyproject.toml) did not run successfully.
      │ exit code: 1
      ╰─> [29 lines of output]
          /private/var/folders/6x/zhywbg6x4h5grk1nhzkr3l8c0000gn/T/pip-build-env-k7_z1q49/overlay/lib/python3.10/site-packages/setuptools/_distutils/extension.py:131: UserWarning: Unknown Extension options: 'headers'
            warnings.warn(msg)
          running bdist_wheel
          running build
          running build_py
          creating python_build_stim
          creating python_build_stim/lib.macosx-11.1-arm64-cpython-310
          creating python_build_stim/lib.macosx-11.1-arm64-cpython-310/stim
          copying glue/python/src/stim/__init__.py -> python_build_stim/lib.macosx-11.1-arm64-cpython-310/stim
          running build_ext
          building 'stim._stim_march_polyfill' extension
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/circuit
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/dem
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/gen
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/io
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/mem
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/py
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/simulators
          creating python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim/stabilizers
          clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -O2 -isystem /opt/homebrew/Caskroom/miniconda/base/envs/FaultTolerantQPU/include -arch arm64 -fPIC -O2 -isystem /opt/homebrew/Caskroom/miniconda/base/envs/FaultTolerantQPU/include -arch arm64 -I/private/var/folders/6x/zhywbg6x4h5grk1nhzkr3l8c0000gn/T/pip-build-env-k7_z1q49/overlay/lib/python3.10/site-packages/pybind11/include -Isrc -I/opt/homebrew/Caskroom/miniconda/base/envs/FaultTolerantQPU/include/python3.10 -c src/stim.cc -o python_build_stim/temp.macosx-11.1-arm64-cpython-310/src/stim.o -std=c++11 -fno-strict-aliasing -O3 -g0 -DVERSION_INFO=1.8.0 -mno-avx2 -DSTIM_PYBIND11_MODULE_NAME=_stim_march_polyfill
          clang: warning: argument unused during compilation: '-mno-avx2' [-Wunused-command-line-argument]
          src/stim.cc:17:10: fatal error: 'stim.h' file not found
          #include "stim.h"
                   ^~~~~~~~
          1 error generated.
          error: command '/usr/bin/clang' failed with exit code 1
          [end of output]
      
      note: This error originates from a subprocess, and is likely not a problem with pip.
      ERROR: Failed building wheel for stim
    Failed to build stim
    ERROR: Could not build wheels for stim, which is required to install pyproject.toml-based projects
    

    I've tried upgrading my pip - no joy. When I type 'clang --version' I get:

    (FaultTolerantQPU) [email protected] FaultTolerantQPU % clang --version
    Apple clang version 13.1.6 (clang-1316.0.21.2)
    Target: arm64-apple-darwin21.2.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    

    What else can I try / what other info can I give that might be useful? Thanks in advance!

  • Stim v1.7.0 installation fails for Apple Silicon

    Stim v1.7.0 installation fails for Apple Silicon

    Unfortunately the Python interpreter crashes (using an M1-based mac) when importing stim after installing v1.7.0 with the prebuilt binaries:

    Python 3.9.6 (default, Jun 29 2021, 06:20:32) 
    [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import stim
    zsh: illegal hardware instruction  python
    

    I tried instead installing from source with the pip --no-binary flag which raises this exception instead:

      src/stim.cc:17:10: fatal error: 'stim.h' file not found
      #include "stim.h"
               ^~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      ----------------------------------------
      ERROR: Failed building wheel for stim
    

    since the stim.h file is no longer in the source distribution. From a comparison with the v1.6.0 source distribution it looks like all the header files are missing in the v1.7.0 PyPI source distribution.

  • Stim package cannot run properly on PyCharm

    Stim package cannot run properly on PyCharm

    Install the stim package as required and import it. But it cannot run properly on PyCharm. The result is "ImportError: PauliString: PyType_Ready failed (UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 46-47: invalid continuation byte)!" issue

  • Random exception in python when using multiprocessing due to rdseed failure

    Random exception in python when using multiprocessing due to rdseed failure

    When I am running a large number of samples simulations simultaneously using stim in a massively multi-process environment (python not supporting multi-threading, I use multi-process computation using python multithreading starmap), this happens semi-randomly when I run a multi-threaded simulation, see the stack trace below:

    image001

    This seems to be related to a multi-threading bug in libstdc++, so perhaps using the approach used by the google cloud c++ api would be a good approach. See:

    https://github.com/googleapis/google-cloud-cpp-common/pull/208

    https://github.com/googleapis/google-cloud-cpp-common/pull/272

    seeing as the call to random_device is only done once per process in PYBIND_SHARED_RNG(), it is probably safe performance-wise to use the second fix, as the performance regression should be very minor.

    This seems to be related to the shared rdseed buffer in certain Intel cpus.

  • Add support for randomly sampling Clifford circuits

    Add support for randomly sampling Clifford circuits

    A useful feature for this package (e.g. for something like simulating shadow tomography) would be to add functionality for randomly sampling Clifford circuits.

    If there is no obvious way of doing this a-priori with the code as it is now, I can have a go at implementing this myself - the procedure itself is not difficult though doing it in such a way that keeps up with Stims impressive scaling performance may require some time.

    Best, QCmonk

  • Basic readers

    Basic readers

    The API is simple, but supports rather varied file formats (one vs many measure records per file, known vs unknown record length) in a consistent way.

    Tests fall into three groups: counterparts to tests for writers, write-read-compare tests and additional tests for multi-record file formats.

    Follow-ups:

    • benchmarking tests for the readers,
    • integration with MeasureRecord,
    • support for PTB64 file format,
    • read counterpart to write_table_data,
    • possible refactoring of write_table_data to fit it into MeasureRecordWriters and similar for the read side (contingent on a fix for the performance regression this is causing).
  • Compressing circuit representation

    Compressing circuit representation

    Many simulators typically group noisy channels as pairs (unitary, error channel). When translating this into Stim, it can cause a significant blowup in the representation of the circuit (e.g. requiring a new line for each noisy gate). It would be a nice feature if Stim had a function that could automate the compression of such a circuit into an equivalent representation that minimized the number of lines.

  • Observations about SIMD, benchmarking, possible improvements

    Observations about SIMD, benchmarking, possible improvements

    First of all, thank you for creating this, it is incredibly useful!!! Not the least as a reference for other code writers!

    I am the developer of QuantumClifford.jl, which implements some useful Clifford circuit tools. It does not have the elegant Pauli frame tracking that enables your ridiculously high speeds, and generally, it has not been hand-tuned, but it is fairly fast and it has its uses elsewhere ;)

    I made some recent improvements in the inner-loop methods (the Pauli multiplication method) that were inspired by your work and wanted to see how it compares against stim. I was surprised that in one (very restricted) micro-benchmark the pure julia code was faster than your C++ SIMD code.

    Here is the example:

    julia> using QuantumClifford, BenchmarkTools
    julia> a = random_pauli(1_000_000);
    julia> b = random_pauli(1_000_000);
    julia> @btime a*b;
      41.598 μs (4 allocations: 244.39 KiB)
    
    julia> b = random_pauli(1_000_000_000);
    julia> a = random_pauli(1_000_000_000);
    julia> @btime a*b;
      101.032 ms (4 allocations: 238.42 MiB)
    
    In [2]: from stim import *
    In [3]: a = PauliString.random(1_000_000);
    In [4]: b = PauliString.random(1_000_000);
    In [5]: %timeit a*b
    42.7 µs ± 17.8 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    
    In [6]: b = PauliString.random(1_000_000_000);
    In [7]: a = PauliString.random(1_000_000_000);
    In [8]: %timeit a*b
    214 ms ± 4.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    The results are basically the same, except for larger (really large) Pauli's, julia is faster by a factor of 2ish. I do not know whether this is just some slowdown caused by the python interface. Or it might be due to the version of gcc/llvm that was used to compile stim.

    Just to be clear, I am not claiming that my julia library is generally faster: its aim is somewhat different from the aim of Stim and I am certain that, holistically, Stim blows everyone out of the water for the task for which it was designed. But given how crazy fast Stim is, I assumed that you would want to know that there might be still some more optimizations to be done. I can try to dig up the machine code that julia compiles if that would be of use. Here is the julia code performing this operation, which is fairly similar to your C++ code.

  • Stop adding dummy edges to ensure one connected component for pymatching

    Stop adding dummy edges to ensure one connected component for pymatching

    • pymatching no longer requires the input to have just one connected component
    • Use new 'fault_ids' instead of old 'qubit_id' on edges
    • Add a test that invincible observables work correctly
    • Loosen sinter's declared requirements
  • Add support for reading detection and measurement events files using the Python API

    Add support for reading detection and measurement events files using the Python API

    I noticed that while there's a sample_write method to write samples of detection events to file, I can't find a method to read these file formats using the Python API (unless it's there and I can't find it). The same is true of the measurement sampler sample_write method. It would be convenient to have a sample_read method or equivalent to read these file formats.

  • add preprocessor clauses for bare support for aarch64

    add preprocessor clauses for bare support for aarch64

    Stim includes some C preprocessor logic which assists in looking up processor intrinsics for specialized / accelerated operator evaluation. Currently, the logic forks on x86 Windows / x86 not-Windows, which breaks on modern Apple devices with ARM64 processors. This PR adds basic support for these processors by adding an extra (dummy) clause to the preprocessor logic, but it does not supply any specialized support for ARM64 features.

    This borrows from the ARM64 clause here: https://opensource.apple.com/source/WTF/WTF-7601.1.46.42/wtf/Platform.h.auto.html .

  • Open 100x fewer file handles when doing large-circuit sample streaming

    Open 100x fewer file handles when doing large-circuit sample streaming

    It's kinda dumb that there's one file per shot in a batch. It makes us go close to system file handle limits (forcing number of samples in a batch to be lower than optimal).

  • Doube check that depolarize2 error rate statistical test failure on macos was likely a false positive

    Doube check that depolarize2 error rate statistical test failure on macos was likely a false positive

    E AssertionError: Sample rate 0.0108 is over 5 standard deviations away from 0.006666665896773338.

    This is presumably a one in a million failure. But the test has been run a lot of times and there are a lot of similar tests. Just compute the probability of seeing this sort of thing by chance and eyeball if it's reasonable.

    Note that this occurred very recently after a change to how seeding is done.

    work/Stim/Stim/src/stim/circuit/circuit_gate_target_pybind_test.py ..... [  1%]
      ....                                                                     [  1%]
      work/Stim/Stim/src/stim/circuit/circuit_instruction_pybind_test.py ..... [  2%]
                                                                               [  2%]
      work/Stim/Stim/src/stim/circuit/circuit_pybind_test.py ................. [  6%]
      ...............                                                          [  9%]
      work/Stim/Stim/src/stim/circuit/circuit_repeat_block_test.py ...         [ 10%]
      work/Stim/Stim/src/stim/dem/detector_error_model_instruction_pybind_test.py . [ 10%]
      .......                                                                  [ 11%]
      work/Stim/Stim/src/stim/dem/detector_error_model_pybind_test.py ........ [ 13%]
      .....                                                                    [ 14%]
      work/Stim/Stim/src/stim/dem/detector_error_model_repeat_block_pybind_test.py . [ 14%]
      ..                                                                       [ 14%]
      work/Stim/Stim/src/stim/dem/detector_error_model_target_pybind_test.py . [ 15%]
      .....                                                                    [ 16%]
      work/Stim/Stim/src/stim/py/compiled_detector_sampler_pybind_test.py .    [ 16%]
      work/Stim/Stim/src/stim/py/compiled_measurement_sampler_pybind_test.py . [ 16%]
      ....                                                                     [ 17%]
      work/Stim/Stim/src/stim/py/stim_pybind_test.py ....                      [ 18%]
      work/Stim/Stim/src/stim/simulators/matched_error_pybind_test.py .......  [ 19%]
      work/Stim/Stim/src/stim/simulators/measurements_to_detection_events_test.py . [ 19%]
      .                                                                        [ 20%]
      work/Stim/Stim/src/stim/simulators/tableau_simulator_pybind_test.py .... [ 20%]
      ....................................                                     [ 28%]
      work/Stim/Stim/src/stim/stabilizers/pauli_string_pybind_test.py ........ [ 29%]
      ...............                                                          [ 33%]
      work/Stim/Stim/src/stim/stabilizers/tableau_pybind_test.py ............. [ 35%]
      .........                                                                [ 37%]
      work/Stim/Stim/glue/cirq/stimcirq/_cirq_to_stim_test.py ................ [ 40%]
      ........................................................................ [ 55%]
      .........................................................F.............. [ 70%]
      ............                                                             [ 72%]
      work/Stim/Stim/glue/cirq/stimcirq/_det_annotation_test.py ......         [ 74%]
      work/Stim/Stim/glue/cirq/stimcirq/_measure_and_or_reset_gate_test.py ..  [ 74%]
      work/Stim/Stim/glue/cirq/stimcirq/_obs_annotation_test.py ......         [ 75%]
      work/Stim/Stim/glue/cirq/stimcirq/_shift_coords_annotation_test.py ..... [ 76%]
      .                                                                        [ 77%]
      work/Stim/Stim/glue/cirq/stimcirq/_stim_sampler_test.py .....            [ 78%]
      work/Stim/Stim/glue/cirq/stimcirq/_stim_to_cirq_test.py ................ [ 81%]
      ........................................................................ [ 96%]
      ...........                                                              [ 98%]
      work/Stim/Stim/glue/cirq/stimcirq/_sweep_pauli_test.py ....              [ 99%]
      work/Stim/Stim/glue/cirq/stimcirq/_two_qubit_asymmetric_depolarize_test.py . [ 99%]
      ...                                                                      [100%]
      
      =================================== FAILURES ===================================
      __ test_tableau_simulator_sampling_noisy_gates_agrees_with_cirq_data[gate14] ___
      
      gate = cirq.depolarize(p=0.1,n_qubits=2)
      
          @pytest.mark.parametrize("gate", ROUND_TRIP_NOISY_GATES)
          def test_tableau_simulator_sampling_noisy_gates_agrees_with_cirq_data(gate: cirq.Gate):
              # Technically this be a test of the `stim` package itself, but it's so convenient to compare to cirq.
          
              # Create test circuit that uses superdense coding to quantify arbitrary Pauli error mixtures.
              n = cirq.num_qubits(gate)
              qs = cirq.LineQubit.range(n)
              circuit = cirq.Circuit(
                  cirq.H.on_each(qs),
                  [cirq.CNOT(q, q + n) for q in qs],
                  gate(*qs),
                  [cirq.CNOT(q, q + n) for q in qs],
                  cirq.H.on_each(qs),
              )
              expected_rates = cirq.final_density_matrix(circuit).diagonal().real
          
              # Convert test circuit to Stim and sample from it.
              stim_circuit, _ = cirq_circuit_to_stim_data(
                  circuit + cirq.measure(*sorted(circuit.all_qubits())[::-1])
              )
              sample_count = 10000
              samples = []
              for _ in range(sample_count):
                  sim = stim.TableauSimulator()
                  sim.do(stim_circuit)
                  s = 0
                  for k, v in enumerate(sim.current_measurement_record()):
                      s |= v << k
                  samples.append(s)
          
              unique, counts = np.unique(samples, return_counts=True)
          
              # Compare sample rates to expected rates.
              for value, count in zip(unique, counts):
                  expected_rate = expected_rates[value]
                  actual_rate = count / sample_count
                  allowed_variation = 5 * (expected_rate * (1 - expected_rate) / sample_count) ** 0.5
                  if not 0 <= expected_rate - allowed_variation <= 1:
                      raise ValueError("Not enough samples to bound results away from extremes.")
      >           assert abs(expected_rate - actual_rate) < allowed_variation, (
                      f"Sample rate {actual_rate} is over 5 standard deviations away from {expected_rate}.\n"
                      f"Gate: {gate}\n"
                      f"Test circuit:\n{circuit}\n"
                      f"Converted circuit:\n{stim_circuit}\n"
                  )
      E           AssertionError: Sample rate 0.0108 is over 5 standard deviations away from 0.006666665896773338.
      E             Gate: depolarize(p=0.1,n_qubits=2)
      E             Test circuit:
      E                       ┌──┐            ┌──┐
      E             0: ───H────@─────D(0.1)────@─────H───
      E                        │     │         │
      E             1: ───H────┼@────#2────────┼@────H───
      E                        ││              ││
      E             2: ────────X┼──────────────X┼────────
      E                         │               │
      E             3: ─────────X───────────────X────────
      E                       └──┘            └──┘
      E             Converted circuit:
      E             H 0 1
      E             TICK
      E             CX 0 2 1 3
      E             TICK
      E             DEPOLARIZE2(0.1) 0 1
      E             TICK
      E             CX 0 2 1 3
      E             TICK
      E             H 0 1
      E             TICK
      E             M 3 2 1 0
      E             TICK
      E             
      E           assert 0.004133334103226662 < 0.004068851638544387
      E            +  where 0.004133334103226662 = abs((0.006666666 - 0.0108))
      
      work/Stim/Stim/glue/cirq/stimcirq/_cirq_to_stim_test.py:235: AssertionError
      =========================== short test summary info ============================
      FAILED work/Stim/Stim/glue/cirq/stimcirq/_cirq_to_stim_test.py::test_tableau_simulator_sampling_noisy_gates_agrees_with_cirq_data[gate14]
      =================== 1 failed, 486 passed in 72.11s (0:01:12) ===================
    Error: Command  pytest /Users/runner/work/Stim/Stim/src /Users/runner/work/Stim/Stim/glue/cirq failed with code 1. None
    
                                                                ✕ 122.06s
    Error: Process completed with exit code 1.
    
  • Support for ELSE_CORRELATED_ERROR in stim analyze_errors

    Support for ELSE_CORRELATED_ERROR in stim analyze_errors

    Hello, I've been trying to use the glue code provided in the getting started tutorial to turn a noisy measurement circuit that I've built with Stim into a matching decoder in PyMatching. Unfortunately, I am making extensive use of the ELSE_CORRELATED_ERROR instruction in my circuit model, and when I use the glue code I get an error explaining that analyze_errors mode does not currently support the ELSE_CORRELATED_ERROR instruction when it's trying to convert my circuit into a detector error model.

    I see that you are aware of this, as it is mentioned in the Stim Command Line Reference doc. That said, I think this is the only place in the documentation where this issue with ELSE_CORRELATED_ERROR is mentioned, and I think it would be very helpful to beginners if this lack of support was mentioned in the Gate Reference doc section that describes ELSE_CORRELATED_ERROR. I read the gate reference doc before coding up my circuit, but not the Command Line Reference doc.

    I'm also wondering if there are any near term plans to implement support for ELSE_CORRELATED_ERROR in this setting? I read in another issue below that PAULI_CHANNEL_2 is currently 10x slower than DEPOLARIZE2. Is the reason for this performance difference the same reason why it might not currently be feasible to efficiently process correlated Pauli channels on larger numbers of qubits?

    Thanks, I've really been enjoying working with Stim so far!

  • Reduce space overhead of small stim.Tableaus

    Reduce space overhead of small stim.Tableaus

    A 30x30 tableau will use 65000 bits instead of 900 bits because the major axis is padded up to a multiple of 256. This padding is not actually necessary. Redesign simd_bit_table to allow an unpadded major axis, and rewrite any code that relies on that assumption. Maybe template the class to allow using smaller words?

Related tags
A fast, byte-code interpreted language

Minima Minima is a small, portable, and fast programming language written in C. The Syntax Minima's syntax is optimized for a fast byte-code translati

May 10, 2022
Naive Circuit Simulator
Naive Circuit Simulator

Naive Circuit Simulator It's an electric circuit solver written in C++, and it's called naive because it can only solve series and parallel circuits.

Jun 8, 2022
MPEG-TS stream selector and stabilizer

tsreadex - MPEG-TSのストリーム選択と安定化のためのツール 使用法: tsreadex [-z ignored][-s seek][-l limit][-t timeout][-m mode][-x pids][-n prog_num_or_index][-a aud1][-b

Mar 13, 2022
An ATTiny85 implementation of the well known sleep aid. Includes circuit, software and 3d printed case design
An ATTiny85 implementation of the well known sleep aid. Includes circuit, software and 3d printed case design

dodowDIY An ATTiny85 implementation of the well known sleep aid. Includes circuit, software and 3d printed case design The STL shells are desiged arou

Nov 7, 2021
A Motorola 68K simulator based on Musashi-master 68K simulator.

cpmsim Originally referenced as http://home.earthlink.net/~schultdw/cpm68/simulator.html (now 404) This simple CP/M-68K simulator, is built around the

Oct 26, 2021
Mobile robot simulator

The Stage Simulator This is the Stage README file, containing an introduction, license and citation information. Stage is a 2(.5)D robotics standalone

Jun 5, 2022
Real-time 2D fluid simulator with lots of visualization options.
Real-time 2D fluid simulator with lots of visualization options.

Fluid Simulator Building Start by cloning the program and all submodules using the following command: git clone --recursive https://github.com/linusmo

May 19, 2022
Advanced, modular, coupled geomorpohology simulator for real-time procedural terrain generation.
Advanced, modular, coupled geomorpohology simulator for real-time procedural terrain generation.

SoilMachine Advanced, modular, coupled geomorpohology simulator for real-time procedural terrain generation in C++. Visualization with TinyEngine. Art

Jun 17, 2022
Orbiter is a spaceflight simulator based on Newtonian mechanics.
Orbiter is a spaceflight simulator based on Newtonian mechanics.

Orbiter Space Flight Simulator Orbiter is a spaceflight simulator based on Newtonian mechanics. Its playground is our solar system with many of its ma

Jun 12, 2022
Open-source repository of Orbiter Space Flight Simulator
Open-source repository of Orbiter Space Flight Simulator

Orbiter Space Flight Simulator Orbiter is a spaceflight simulator based on Newtonian mechanics. Its playground is our solar system with many of its ma

Jun 12, 2022
Restoration of The Linux Scheduler Simulator (LinSched)

Restoration of The Linux Scheduler Simulator (LinSched)

Sep 3, 2021
HiFi error modeler and simulator with ploidy

A HiFi Shotgun Simulator Author: Gene Myers First: Aug 1, 2021 Current: Aug 1, 2021 Commands Himodel HIsim The Error Model Commands This module contai

Feb 15, 2022
GrandOrgue is a sample based pipe organ simulator.

GrandOrgue is a sample based pipe organ simulator. It currently supports Linux, Windows and OS X. Porting to other OS supported by RtMidi,

Jun 22, 2022
a Living ENsemble Simulator -- a lens to help you watch biophysics

aLENS (a Living ENsemble Simulator) The motivation, algorithm and examples are discussed in this paper: aLENS: towards the cellular-scale simulation o

Jun 6, 2022
A simple mirror simulator made with OpenGL 3.3 and C++

Mirror-Example A simple mirror example using OpenGL 3.3 with C++. Theory It basically constructs a camera at the mirror location, by determining its v

Feb 10, 2022
Biological evolution simulator

biosim4 What is this? This pile of code was used to simulate biological creatures that evolve through natural selection. The results of the experiment

Jun 15, 2022
Multi-Joint dynamics with Contact. A general purpose physics simulator.

Multi-Joint dynamics with Contact. A general purpose physics simulator.

Jun 17, 2022
JaBS - Jaakko's Backscattering Simulator

JaBS - Jaakko's Backscattering Simulator

Mar 31, 2022
A command line poker simulator made in C++.

C Plus Poker (C++ Poker) Introduction This is a C++ console application that simulates the scoring of a Poker game. Unlike typical Poker, this applica

Oct 21, 2021
a Little Computer 3 simulator

smol3 ??️ a Little Computer 3 simulator smol3 is a tiny LC3 simulator written in C. It aims to be fast and correct. TODO read input binary files write

Oct 22, 2021