Skip to content

Commit

Permalink
Increase OS and future C++ version compatibility (#487)
Browse files Browse the repository at this point in the history
- Port over some changes needed for eventual C++20 compatibility
- Enable compiler optimizations on Windows
  • Loading branch information
Strilanc authored Feb 1, 2023
1 parent 94dce47 commit 0cb6adc
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 45 deletions.
2 changes: 1 addition & 1 deletion BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ cc_binary(
"-fvisibility=hidden",
"-march=native",
"-DSTIM_PYBIND11_MODULE_NAME=stim",
"-DVERSION_INFO=0.0.dev"
"-DVERSION_INFO=0.0.dev",
],
includes = ["src/"],
linkopts = ["-lpthread"],
Expand Down
41 changes: 26 additions & 15 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys

from setuptools import setup, Extension
import glob
Expand All @@ -26,22 +27,35 @@

version = '1.11.dev0'

common_compile_args = [
'-std=c++11',
'-fno-strict-aliasing',
'-O3',
'-g0',
f'-DVERSION_INFO={version}',
]
if sys.platform.startswith('win'):
common_compile_args = [
'/std:c++11',
'/O2',
f'/DVERSION_INFO={version}',
]
arch_avx = ['/arch:AVX2']
arch_sse = ['/arch:SSE2']
arch_basic = []
else:
common_compile_args = [
'-std=c++11',
'-fno-strict-aliasing',
'-O3',
'-g0',
f'-DVERSION_INFO={version}',
]
arch_avx = ['-mavx2']
arch_sse = ['-msse2', '-mno-avx2']
arch_basic = []

stim_detect_machine_architecture = Extension(
'stim._detect_machine_architecture',
sources=MUX_SOURCE_FILES,
include_dirs=[pybind11.get_include(), "src"],
language='c++',
extra_compile_args=[
*common_compile_args,
'-mno-sse2',
'-mno-avx2',
*arch_basic,
],
)
stim_polyfill = Extension(
Expand All @@ -51,8 +65,7 @@
language='c++',
extra_compile_args=[
*common_compile_args,
# I would specify -mno-sse2 but that causes build failures in non-stim code...?
'-mno-avx2',
*arch_basic,
'-DSTIM_PYBIND11_MODULE_NAME=_stim_polyfill',
],
)
Expand All @@ -63,8 +76,7 @@
language='c++',
extra_compile_args=[
*common_compile_args,
'-msse2',
'-mno-avx2',
*arch_sse,
'-DSTIM_PYBIND11_MODULE_NAME=_stim_sse2',
],
)
Expand All @@ -77,8 +89,7 @@
# language='c++',
# extra_compile_args=[
# *common_compile_args,
# '-msse2',
# '-mavx2',
# *arch_avx,
# '-DSTIM_PYBIND11_MODULE_NAME=_stim_avx2',
# ],
# )
Expand Down
18 changes: 9 additions & 9 deletions src/stim/benchmark_main.perf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,40 +25,40 @@ std::vector<RegisteredBenchmark> all_registered_benchmarks{};

/// Describe quantity as an SI-prefixed value with two significant figures.
std::string si2(double val) {
std::string unit = "";
char unit = ' ';
if (val < 1) {
if (val < 1) {
val *= 1000;
unit = "m";
unit = 'm';
}
if (val < 1) {
val *= 1000;
unit = "u";
unit = 'u';
}
if (val < 1) {
val *= 1000;
unit = "n";
unit = 'n';
}
if (val < 1) {
val *= 1000;
unit = "p";
unit = 'p';
}
} else {
if (val > 1000) {
val /= 1000;
unit = "k";
unit = 'k';
}
if (val > 1000) {
val /= 1000;
unit = "M";
unit = 'M';
}
if (val > 1000) {
val /= 1000;
unit = "G";
unit = 'G';
}
if (val > 1000) {
val /= 1000;
unit = "T";
unit = 'T';
}
}
std::stringstream ss;
Expand Down
4 changes: 3 additions & 1 deletion src/stim/diagram/timeline/timeline_ascii_drawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,11 @@ AsciiDiagram DiagramTimelineAsciiDrawer::make_diagram(const Circuit &circuit) {
{0, obj.q2y(q), 1.0, 0.5},
{obj.m2x(obj.cur_moment), obj.q2y(q), 0.0, 0.5},
};
std::stringstream qubit;
qubit << 'q' << q << ": ";
obj.diagram.add_entry(AsciiDiagramEntry{
{0, obj.q2y(q), 1.0, 0.5},
"q" + std::to_string(q) + ": ",
qubit.str(),
});
}

Expand Down
12 changes: 9 additions & 3 deletions src/stim/gen/circuit_gen_params.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,25 @@ void CircuitGenParameters::append_unitary_2(
}

void CircuitGenParameters::append_reset(Circuit &circuit, const std::vector<uint32_t> targets, char basis) const {
circuit.safe_append_u(std::string("R") + basis, targets);
std::string gate("R");
gate.push_back(basis);
circuit.safe_append_u(gate, targets);
append_anti_basis_error(circuit, targets, after_reset_flip_probability, basis);
}

void CircuitGenParameters::append_measure(Circuit &circuit, const std::vector<uint32_t> targets, char basis) const {
std::string gate("M");
gate.push_back(basis);
append_anti_basis_error(circuit, targets, before_measure_flip_probability, basis);
circuit.safe_append_u(std::string("M") + basis, targets);
circuit.safe_append_u(gate, targets);
}

void CircuitGenParameters::append_measure_reset(
Circuit &circuit, const std::vector<uint32_t> targets, char basis) const {
std::string gate("MR");
gate.push_back(basis);
append_anti_basis_error(circuit, targets, before_measure_flip_probability, basis);
circuit.safe_append_u(std::string("MR") + basis, targets);
circuit.safe_append_u(gate, targets);
append_anti_basis_error(circuit, targets, after_reset_flip_probability, basis);
}

Expand Down
2 changes: 1 addition & 1 deletion src/stim/gen/circuit_gen_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct CircuitGenParameters {

struct GeneratedCircuit {
Circuit circuit;
std::map<std::pair<uint32_t, uint32_t>, std::pair<std::string, uint32_t>> layout;
std::map<std::pair<uint32_t, uint32_t>, std::pair<char, uint32_t>> layout;
std::string hint_str;
std::string layout_str() const;
};
Expand Down
6 changes: 3 additions & 3 deletions src/stim/gen/gen_color_code.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ GeneratedCircuit stim::generate_color_code_circuit(const CircuitGenParameters &p
auto full_circuit = head + body * (params.rounds - 2) + tail;

// Make 2d layout.
std::map<std::pair<uint32_t, uint32_t>, std::pair<std::string, uint32_t>> layout;
std::map<std::pair<uint32_t, uint32_t>, std::pair<char, uint32_t>> layout;
for (auto q : data_coords) {
layout[{(uint32_t)(q.x * 2), (uint32_t)q.y}] = {q.y == 0 ? "L" : "d", p2q[q]};
layout[{(uint32_t)(q.x * 2), (uint32_t)q.y}] = {q.y == 0 ? 'L' : 'd', p2q[q]};
}
std::array<const char *, 3> rgb{"R", "G", "B"};
std::array<char, 3> rgb{'R', 'G', 'B'};
for (auto q : measure_coords) {
auto x = (uint32_t)(q.x * 2);
auto y = (uint32_t)q.y;
Expand Down
6 changes: 3 additions & 3 deletions src/stim/gen/gen_rep_code.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ GeneratedCircuit stim::generate_rep_code_circuit(const CircuitGenParameters &par
Circuit full_circuit = head + body * (params.rounds - 1) + tail;

// Produce a 2d layout.
std::map<std::pair<uint32_t, uint32_t>, std::pair<std::string, uint32_t>> layout;
std::map<std::pair<uint32_t, uint32_t>, std::pair<char, uint32_t>> layout;
for (uint32_t k = 0; k < n; k++) {
layout[{k, 0}] = {std::string() + "dZ"[k & 1], k};
layout[{k, 0}] = {"dZ"[k & 1], k};
}
layout[{0, 0}].first = "L";
layout[{0, 0}].first = 'L';

return {
full_circuit,
Expand Down
10 changes: 5 additions & 5 deletions src/stim/gen/gen_surface_code.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,19 @@ GeneratedCircuit _finish_surface_code_circuit(
Circuit full_circuit = head + body * (params.rounds - 1) + tail;

// Produce a 2d layout.
std::map<std::pair<uint32_t, uint32_t>, std::pair<std::string, uint32_t>> layout;
std::map<std::pair<uint32_t, uint32_t>, std::pair<char, uint32_t>> layout;
float scale = x_order[0].x == 0.5 ? 2 : 1;
for (auto q : data_coords) {
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}] = {"d", p2q[q]};
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}] = {'d', p2q[q]};
}
for (auto q : x_measure_coords) {
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}] = {"X", p2q[q]};
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}] = {'X', p2q[q]};
}
for (auto q : z_measure_coords) {
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}] = {"Z", p2q[q]};
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}] = {'Z', p2q[q]};
}
for (auto q : chosen_basis_observable) {
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}].first = "L";
layout[{(uint32_t)(q.x * scale), (uint32_t)(q.y * scale)}].first = 'L';
}

return {
Expand Down
2 changes: 2 additions & 0 deletions src/stim/mem/simd_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ struct simd_bits {

// Equality.
bool operator==(const simd_bits_range_ref<W> &other) const;
bool operator==(const simd_bits<W> &other) const;
// Inequality.
bool operator!=(const simd_bits_range_ref<W> &other) const;
bool operator!=(const simd_bits<W> &other) const;
/// Determines whether or not any of the bits in the simd_bits are non-zero.
bool not_zero() const;

Expand Down
10 changes: 10 additions & 0 deletions src/stim/mem/simd_bits.inl
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,21 @@ bool simd_bits<W>::operator==(const simd_bits_range_ref<W> &other) const {
return simd_bits_range_ref<W>(*this) == other;
}

template <size_t W>
bool simd_bits<W>::operator==(const simd_bits<W> &other) const {
return simd_bits_range_ref<W>(*this) == simd_bits_range_ref<W>(other);
}

template <size_t W>
bool simd_bits<W>::operator!=(const simd_bits_range_ref<W> &other) const {
return !(*this == other);
}

template <size_t W>
bool simd_bits<W>::operator!=(const simd_bits<W> &other) const {
return !(*this == other);
}

template <size_t W>
simd_bits<W> simd_bits<W>::random(size_t min_bits, std::mt19937_64 &rng) {
simd_bits<W> result(min_bits);
Expand Down
4 changes: 2 additions & 2 deletions src/stim/mem/simd_bits_range_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ struct simd_bits_range_ref {
void swap_with(simd_bits_range_ref other);

/// Equality.
bool operator==(const simd_bits_range_ref other) const;
bool operator==(const simd_bits_range_ref<W> &other) const;
/// Inequality.
bool operator!=(const simd_bits_range_ref other) const;
bool operator!=(const simd_bits_range_ref<W> &other) const;
/// Determines whether or not any of the bits in the referenced range are non-zero.
bool not_zero() const;

Expand Down
4 changes: 2 additions & 2 deletions src/stim/mem/simd_bits_range_ref.inl
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void simd_bits_range_ref<W>::clear() {
}

template <size_t W>
bool simd_bits_range_ref<W>::operator==(const simd_bits_range_ref<W> other) const {
bool simd_bits_range_ref<W>::operator==(const simd_bits_range_ref<W> &other) const {
return num_simd_words == other.num_simd_words && memcmp(ptr_simd, other.ptr_simd, num_u8_padded()) == 0;
}

Expand All @@ -89,7 +89,7 @@ bool simd_bits_range_ref<W>::not_zero() const {
}

template <size_t W>
bool simd_bits_range_ref<W>::operator!=(const simd_bits_range_ref<W> other) const {
bool simd_bits_range_ref<W>::operator!=(const simd_bits_range_ref<W> &other) const {
return !(*this == other);
}

Expand Down
6 changes: 6 additions & 0 deletions src/stim/stabilizers/pauli_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,16 @@ PauliString PauliString::random(size_t num_qubits, std::mt19937_64 &rng) {
bool PauliString::operator==(const PauliStringRef &other) const {
return ref() == other;
}
bool PauliString::operator==(const PauliString &other) const {
return ref() == other.ref();
}

bool PauliString::operator!=(const PauliStringRef &other) const {
return ref() != other;
}
bool PauliString::operator!=(const PauliString &other) const {
return ref() != other.ref();
}

void PauliString::ensure_num_qubits(size_t min_num_qubits, double resize_pad_factor) {
assert(resize_pad_factor >= 1);
Expand Down
2 changes: 2 additions & 0 deletions src/stim/stabilizers/pauli_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ struct PauliString {

/// Equality.
bool operator==(const PauliStringRef &other) const;
bool operator==(const PauliString &other) const;
/// Inequality.
bool operator!=(const PauliStringRef &other) const;
bool operator!=(const PauliString &other) const;

/// Implicit conversion to a reference.
operator PauliStringRef();
Expand Down

0 comments on commit 0cb6adc

Please sign in to comment.