Skip to content

Commit 60c4775

Browse files
authored
Add Stim source files and README describing slight modifications (NVIDIA#34)
* Add original Stim source files; upcoming commits slightly modify them Original source of the files was https://github.com/quantumlib/Stim/tree/47190f4a3afb104c9f0068d0be9fea87d2894a70/src/stim/mem (Hash aligns with v1.14.0.) Not all files in this directory were copied over. * Modify Stim files and add README
1 parent 66215f7 commit 60c4775

File tree

17 files changed

+2734
-0
lines changed

17 files changed

+2734
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DisableFormat: true
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Description
2+
3+
This directory contains a slightly modified copy of specific files from <https://github.com/quantumlib/Stim>. The original files that were copied into here are the minimal set needed to utilize the `stim::simd_bit_table` for binary linear algebra.
4+
5+
The source commit was `47190f4a3afb104c9f0068d0be9fea87d2894a70` (aka `v1.14.0`).
6+
7+
The original source files are copyrighted by Google and licensed under the Apache 2.0 license.
8+
9+
Any modifications to the files are marked with "NVIDIA-MOD".
10+
11+
The main purpose of the modifications (so far) is to simply compile with C++17.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "stim/mem/bit_ref.h"
16+
17+
using namespace stim;
18+
19+
bit_ref::bit_ref(void *base, size_t init_offset)
20+
: byte((uint8_t *)base + (init_offset / 8)), bit_index(init_offset & 7) {
21+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef _STIM_MEM_BIT_REF_H
18+
#define _STIM_MEM_BIT_REF_H
19+
20+
#include <cstddef>
21+
#include <cstdint>
22+
23+
namespace stim {
24+
25+
/// A reference to a bit within a byte.
26+
///
27+
/// Conceptually behaves the same as a `bool &`, as opposed to a `bool *`. For example, the `=` operator overwrites the
28+
/// contents of the bit being referenced instead of changing which bit is pointed to.
29+
///
30+
/// This should behave essentially identically to the weird bit references that come out of a `std::vector<bool>`.
31+
struct bit_ref {
32+
uint8_t *byte;
33+
uint8_t bit_index;
34+
35+
/// Construct a bit_ref from a pointer and a bit offset.
36+
/// The offset can be larger than a word.
37+
/// Automatically canonicalized so that the offset is less than 8.
38+
bit_ref(void *base, size_t offset);
39+
40+
/// Copy assignment.
41+
inline bit_ref &operator=(bool value) {
42+
*byte &= ~((uint8_t)1 << bit_index);
43+
*byte |= (uint8_t)value << bit_index;
44+
return *this;
45+
}
46+
/// Copy assignment.
47+
inline bit_ref &operator=(const bit_ref &value) {
48+
*this = (bool)value;
49+
return *this;
50+
}
51+
/// Xor assignment.
52+
inline bit_ref &operator^=(bool value) {
53+
*byte ^= (uint8_t)value << bit_index;
54+
return *this;
55+
}
56+
/// Bitwise-and assignment.
57+
inline bit_ref &operator&=(bool value) {
58+
*byte &= ((uint8_t)value << bit_index) | ~(1 << bit_index);
59+
return *this;
60+
}
61+
/// Bitwise-or assignment.
62+
inline bit_ref &operator|=(bool value) {
63+
*byte |= (uint8_t)value << bit_index;
64+
return *this;
65+
}
66+
/// Swap assignment.
67+
inline void swap_with(bit_ref other) {
68+
bool b = (bool)other;
69+
other = (bool)*this;
70+
*this = b;
71+
}
72+
73+
/// Implicit conversion to bool.
74+
inline operator bool() const { // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
75+
return (*byte >> bit_index) & 1;
76+
}
77+
};
78+
79+
} // namespace stim
80+
81+
#endif
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <cstddef>
18+
19+
#ifndef _STIM_MEM_BIT_WORD_H
20+
#define _STIM_MEM_BIT_WORD_H
21+
22+
namespace stim {
23+
24+
/// A `bitword` is a bag of bits that can be operated on in a SIMD-esque fashion
25+
/// by individual CPU instructions.
26+
///
27+
/// This template would not have to exist, except that different architectures and
28+
/// operating systems expose different interfaces between native types like
29+
/// uint64_t and intrinsics like __m256i. For example, in some contexts, __m256i
30+
/// values can be operated on by operators (e.g. you can do `a ^= b`) while in
31+
/// other contexts this does not work. The bitword template implementations define
32+
/// a common set of methods required by stim to function, so that the same code
33+
/// can be compiled to use 256 bit registers or 64 bit registers as appropriate.
34+
template <size_t bit_size>
35+
struct bitword;
36+
37+
template <size_t W>
38+
inline bool operator==(const bitword<W> &self, const bitword<W> &other) {
39+
return self.to_u64_array() == other.to_u64_array();
40+
}
41+
42+
template <size_t W>
43+
inline bool operator<(const bitword<W> &self, const bitword<W> &other) {
44+
auto v1 = self.to_u64_array();
45+
auto v2 = other.to_u64_array();
46+
for (size_t k = 0; k < v1.size(); k++) {
47+
if (v1[k] != v2[k]) {
48+
return v1[k] < v2[k];
49+
}
50+
}
51+
return false;
52+
}
53+
54+
template <size_t W>
55+
inline bool operator!=(const bitword<W> &self, const bitword<W> &other) {
56+
return !(self == other);
57+
}
58+
59+
template <size_t W>
60+
inline bool operator==(const bitword<W> &self, int other) {
61+
return self == (bitword<W>)other;
62+
}
63+
template <size_t W>
64+
inline bool operator!=(const bitword<W> &self, int other) {
65+
return self != (bitword<W>)other;
66+
}
67+
template <size_t W>
68+
inline bool operator==(const bitword<W> &self, uint64_t other) {
69+
return self == (bitword<W>)other;
70+
}
71+
template <size_t W>
72+
inline bool operator!=(const bitword<W> &self, uint64_t other) {
73+
return self != (bitword<W>)other;
74+
}
75+
template <size_t W>
76+
inline bool operator==(const bitword<W> &self, int64_t other) {
77+
return self == (bitword<W>)other;
78+
}
79+
template <size_t W>
80+
inline bool operator!=(const bitword<W> &self, int64_t other) {
81+
return self != (bitword<W>)other;
82+
}
83+
84+
template <size_t W>
85+
std::ostream &operator<<(std::ostream &out, const bitword<W> &v) {
86+
out << "bitword<" << W << ">{";
87+
auto u = v.to_u64_array();
88+
for (size_t k = 0; k < u.size(); k++) {
89+
for (size_t b = 0; b < 64; b++) {
90+
if ((b | k) && (b & 7) == 0) {
91+
out << ' ';
92+
}
93+
out << ".1"[(u[k] >> b) & 1];
94+
}
95+
}
96+
out << '}';
97+
return out;
98+
}
99+
100+
template <size_t W>
101+
inline bitword<W> operator<<(const bitword<W> &self, uint64_t offset) {
102+
return self.shifted((int)offset);
103+
}
104+
105+
template <size_t W>
106+
inline bitword<W> operator>>(const bitword<W> &self, uint64_t offset) {
107+
return self.shifted(-(int)offset);
108+
}
109+
110+
template <size_t W>
111+
inline bitword<W> &operator<<=(bitword<W> &self, uint64_t offset) {
112+
self = (self << offset);
113+
return self;
114+
}
115+
116+
template <size_t W>
117+
inline bitword<W> &operator>>=(bitword<W> &self, uint64_t offset) {
118+
self = (self >> offset);
119+
return self;
120+
}
121+
122+
template <size_t W>
123+
inline bitword<W> operator<<(const bitword<W> &self, int offset) {
124+
return self.shifted((int)offset);
125+
}
126+
127+
template <size_t W>
128+
inline bitword<W> operator>>(const bitword<W> &self, int offset) {
129+
return self.shifted(-(int)offset);
130+
}
131+
132+
template <size_t W>
133+
inline bitword<W> &operator<<=(bitword<W> &self, int offset) {
134+
self = (self << offset);
135+
return self;
136+
}
137+
138+
template <size_t W>
139+
inline bitword<W> &operator>>=(bitword<W> &self, int offset) {
140+
self = (self >> offset);
141+
return self;
142+
}
143+
144+
template <size_t W>
145+
inline bitword<W> operator&(const bitword<W> &self, int mask) {
146+
return self & bitword<W>(mask);
147+
}
148+
template <size_t W>
149+
inline bitword<W> operator&(const bitword<W> &self, uint64_t mask) {
150+
return self & bitword<W>(mask);
151+
}
152+
template <size_t W>
153+
inline bitword<W> operator&(const bitword<W> &self, int64_t mask) {
154+
return self & bitword<W>(mask);
155+
}
156+
template <size_t W>
157+
inline bitword<W> operator|(const bitword<W> &self, int mask) {
158+
return self | bitword<W>(mask);
159+
}
160+
template <size_t W>
161+
inline bitword<W> operator|(const bitword<W> &self, uint64_t mask) {
162+
return self | bitword<W>(mask);
163+
}
164+
template <size_t W>
165+
inline bitword<W> operator|(const bitword<W> &self, int64_t mask) {
166+
return self | bitword<W>(mask);
167+
}
168+
template <size_t W>
169+
inline bitword<W> operator^(const bitword<W> &self, int mask) {
170+
return self ^ bitword<W>(mask);
171+
}
172+
template <size_t W>
173+
inline bitword<W> operator^(const bitword<W> &self, uint64_t mask) {
174+
return self ^ bitword<W>(mask);
175+
}
176+
template <size_t W>
177+
inline bitword<W> operator^(const bitword<W> &self, int64_t mask) {
178+
return self ^ bitword<W>(mask);
179+
}
180+
181+
} // namespace stim
182+
183+
#endif

0 commit comments

Comments
 (0)