def R_z(self, i, phi): phase_one = np.exp(1j * phi) g.bilinear_combination( [self.lattice], [self.bit_map.zero_mask[i], self.bit_map.one_mask[i]], [self.lattice], [[1.0, phase_one]], [[0, 1]], [[0, 0]], )
def CNOT(self, control, target): assert control != target bfl = self.bit_flipped_lattice(target) g.bilinear_combination( [self.lattice], [self.bit_map.zero_mask[control], self.bit_map.one_mask[control]], [self.lattice, bfl], [[1.0, 1.0]], [[0, 1]], [[0, 1]], )
def H(self, i): bfl = self.bit_flipped_lattice(i) nrm = 1.0 / 2.0**0.5 g.bilinear_combination( [self.lattice], [self.bit_map.zero_mask[i], self.bit_map.one_mask[i]], [self.lattice, bfl], [[nrm, nrm, -nrm, nrm]], [[0, 0, 1, 1]], [[0, 1, 0, 1]], )
def measure(self, i): p_one = self.probability(i) p_zero = 1.0 - p_one l = self.rng.uniform_real() if l <= p_one: proj = self.bit_map.one_mask[self.bit_permutation[i]] nrm = 1.0 / (p_one**0.5) r = 1 else: proj = self.bit_map.zero_mask[self.bit_permutation[i]] nrm = 1.0 / (p_zero**0.5) r = 0 g.bilinear_combination([self.lattice], [proj], [self.lattice], [[nrm]], [[0]], [[0]]) self.classical_bit[i] = r return r
# Test bilinear_combination against expression engine ################################################################################ for grid in [grid_sp, grid_dp]: left = [g.complex(grid) for i in range(3)] right = [g.complex(grid) for i in range(3)] result_bilinear = [g.complex(grid) for i in range(3)] rng.cnormal([left, right]) result = [ g.eval(left[1] * right[2] - left[2] * right[1]), g.eval(left[2] * right[0] - left[0] * right[2]), g.eval(left[0] * right[1] + left[2] * right[0]), ] g.bilinear_combination( result_bilinear, left, right, [[1.0, -1.0], [1.0, -1.0], [1.0, 1.0]], [[1, 2], [2, 0], [0, 2]], [[2, 1], [0, 2], [1, 0]], ) for j in range(len(result)): eps2 = g.norm2(result[j] - result_bilinear[j]) / g.norm2(result[j]) g.message(f"Test bilinear combination of vector {j}: {eps2}") assert eps2 < 1e-13 ################################################################################ # Test where ################################################################################ grid = grid_dp sel = g.complex(grid) rng.uniform_int(sel, min=0, max=1)
def quark_contract_xx(mspincolor1, mspincolor2, components): """ This routine is written for Nc = 3 y^{k2, k1} = \\sum_{i1, i2, j1, j2} \\epsilon^{i1, j1, k1} \\epsilon^{i2, j2, k2} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(0, 1, 2), +(1, 2, 0), +(2, 0, 1), -(1, 0, 2), -(0, 2, 1), -(2, 1, 0) i.e. - y^{0, 0} = \\epsilon^{i1, j1, 0} \\epsilon^{i2, j2, 0} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(1, 2, 0), -(2, 1, 0); +(1, 2, 0), -(2, 1, 0) - y^{0, 1} = \\epsilon^{i1, j1, 1} \\epsilon^{i2, j2, 0} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(2, 0, 1), -(0, 2, 1); +(1, 2, 0), -(2, 1, 0) - y^{0, 2} = \\epsilon^{i1, j1, 2} \\epsilon^{i2, j2, 0} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(0, 1, 2), -(1, 0, 2) +(1, 2, 0), -(2, 1, 0) - y^{1, 0} = \\epsilon^{i1, j1, 0} \\epsilon^{i2, j2, 1} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(1, 2, 0), -(2, 1, 0) +(2, 0, 1), -(0, 2, 1) - y^{1, 1} = \\epsilon^{i1, j1, 1} \\epsilon^{i2, j2, 1} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(2, 0, 1), -(0, 2, 1) +(2, 0, 1), -(0, 2, 1) - y^{1, 2} = \\epsilon^{i1, j1, 2} \\epsilon^{i2, j2, 1} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(0, 1, 2), -(1, 0, 2) +(2, 0, 1), -(0, 2, 1) - y^{2, 0} = \\epsilon^{i1, j1, 0} \\epsilon^{i2, j2, 2} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(1, 2, 0), -(2, 1, 0) +(0, 1, 2), -(1, 0, 2) - y^{2, 1} = \\epsilon^{i1, j1, 1} \\epsilon^{i2, j2, 2} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(2, 0, 1), -(0, 2, 1) +(0, 1, 2), -(1, 0, 2) - y^{2, 2} = \\epsilon^{i1, j1, 2} \\epsilon^{i2, j2, 2} xc1^{i1, i2} xc2^{j1, j2} Permutations: +(0, 1, 2), -(1, 0, 2) +(0, 1, 2), -(1, 0, 2) """ t_separatespin, t_separatecolor, t_create, t_bilinear, t_merge = 0.0, 0.0, 0.0, 0.0, 0.0 t_start = gpt.time() comps1, comps2 = dict(), dict() for mspincolor, comps in [[mspincolor1, comps1], [mspincolor2, comps2]]: if isinstance(mspincolor, gpt.lattice): t_separatespin -= gpt.time() spin_separated = gpt.separate_spin(mspincolor) t_separatespin += gpt.time() for spinkey in spin_separated: t_separatecolor -= gpt.time() comps[spinkey] = gpt.separate_color(spin_separated[spinkey]) t_separatecolor += gpt.time() elif isinstance(mspincolor, dict): for spinkey in mspincolor: n_keys = len(mspincolor[spinkey]) n_colors = np.sqrt(n_keys) assert n_colors == int(n_colors) assert (int(n_colors) - 1, int(n_colors) - 1) in mspincolor[spinkey] comps[spinkey] = mspincolor[spinkey] grid = comps1[0, 0][0, 0].grid t_create -= gpt.time() dst = gpt.mspincolor(grid) spinsep_dst = {(ii // 4, ii % 4): gpt.mcolor(grid) for ii in range(16)} bilinear_result = [gpt.complex(grid) for _ in range(9)] t_create += gpt.time() leftbase = np.array( [[4, 5, 7, 8], [7, 8, 1, 2], [1, 2, 4, 5], [5, 3, 8, 6], [8, 6, 2, 0], [2, 0, 5, 3], [3, 4, 6, 7], [6, 7, 0, 1], [0, 1, 3, 4]], dtype=np.int32) rightbase = np.array( [[8, 7, 5, 4], [2, 1, 8, 7], [5, 4, 2, 1], [6, 8, 3, 5], [0, 2, 6, 8], [3, 5, 0, 2], [7, 6, 4, 3], [1, 0, 7, 6], [4, 3, 1, 0]], dtype=np.int32) for spin_key in components.keys(): lefts, rights = [], [] bilin_coeffs, bilin_leftbasis, bilin_rightbasis = [], [], [] for nn, comps in enumerate(components[spin_key]): c0_0, c0_1, c1_0, c1_1 = comps for ii in range(9): lefts.append(comps1[c0_0, c0_1][ii // 3, ii % 3]) rights.append(comps2[c1_0, c1_1][ii // 3, ii % 3]) bilin_coeffs = np.append(bilin_coeffs, [1.0, -1.0, -1.0, +1.0]) bilin_leftbasis.append(leftbase + nn * 9) bilin_rightbasis.append(rightbase + nn * 9) bilin_coeffs = np.array([bilin_coeffs for _ in range(9)], dtype=np.int32) bilin_leftbasis = np.concatenate(bilin_leftbasis, axis=1) bilin_rightbasis = np.concatenate(bilin_rightbasis, axis=1) t_bilinear -= gpt.time() gpt.bilinear_combination(bilinear_result, lefts, rights, bilin_coeffs, bilin_leftbasis, bilin_rightbasis) t_bilinear += gpt.time() cmat_dict = dict() for ii in range(9): cmat_dict[ii // 3, ii % 3] = bilinear_result[ii] t_merge -= gpt.time() gpt.merge_color(spinsep_dst[spin_key], cmat_dict) t_merge += gpt.time() t_merge -= gpt.time() gpt.merge_spin(dst, spinsep_dst) t_merge += gpt.time() t_total = gpt.time() - t_start t_profiled = t_separatespin + t_separatecolor + t_create + t_bilinear + t_merge if gpt.default.is_verbose("quark_contract_xx"): gpt.message("quark_contract_xx: total", t_total, "s") gpt.message("quark_contract_xx: t_separatespin", t_separatespin, "s", round(100 * t_separatespin / t_total, 1), "%") gpt.message("quark_contract_xx: t_separatecolor", t_separatecolor, "s", round(100 * t_separatecolor / t_total, 1), "%") gpt.message("quark_contract_xx: t_create", t_create, "s", round(100 * t_create / t_total, 1), "%") gpt.message("quark_contract_xx: t_bilinear", t_bilinear, "s", round(100 * t_bilinear / t_total, 1), "%") gpt.message("quark_contract_xx: t_merge", t_merge, "s", round(100 * t_merge / t_total, 1), "%") gpt.message("quark_contract_xx: unprofiled", t_total - t_profiled, "s", round(100 * (t_total - t_profiled) / t_total, 1), "%") return dst
rng.cnormal(basis) # Typical usecase : nbasis x nbasis -> nbasis Qt = np.ones((nbasis, nbasis), np.complex128) lidx = np.mod(np.arange(nbasis * nbasis, dtype=np.int32), nbasis).reshape( nbasis, nbasis ) # Bytes nbytes = nbasis * (2 * nbasis + 1) * result[0].global_bytes() * N # Time dt = 0.0 for it in range(N + Nwarmup): if it >= Nwarmup: dt -= g.time() g.bilinear_combination(result, basis, basis, Qt, lidx, lidx) if it >= Nwarmup: dt += g.time() # Report GBPerSec = nbytes / dt / 1e9 g.message( f"""{N} bilinear_combination Object type : {tp.__name__} Number of basis vectors : {nbasis} Time to complete : {dt:.2f} s Effective memory bandwidth : {GBPerSec:.2f} GB/s """ )